add logic for checkin
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
d7725ced6f
commit
268c5c7c6d
|
@ -1,10 +1,11 @@
|
|||
"""AuthenticatorMobileStage API Views"""
|
||||
from django.http import Http404
|
||||
from django.utils.timezone import now
|
||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
|
||||
from rest_framework import mixins
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import CharField, ChoiceField, UUIDField
|
||||
from rest_framework.fields import CharField, ChoiceField, JSONField, UUIDField
|
||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.request import Request
|
||||
|
@ -24,15 +25,6 @@ from authentik.stages.authenticator_mobile.models import (
|
|||
)
|
||||
|
||||
|
||||
class MobileDeviceSerializer(ModelSerializer):
|
||||
"""Serializer for Mobile authenticator devices"""
|
||||
|
||||
class Meta:
|
||||
model = MobileDevice
|
||||
fields = ["pk", "name"]
|
||||
depth = 2
|
||||
|
||||
|
||||
class MobileDeviceInfoSerializer(PassiveSerializer):
|
||||
"""Info about a mobile device"""
|
||||
|
||||
|
@ -47,6 +39,19 @@ class MobileDeviceInfoSerializer(PassiveSerializer):
|
|||
hostname = CharField()
|
||||
app_version = CharField()
|
||||
|
||||
others = JSONField()
|
||||
|
||||
|
||||
class MobileDeviceSerializer(ModelSerializer):
|
||||
"""Serializer for Mobile authenticator devices"""
|
||||
|
||||
last_checkin = MobileDeviceInfoSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = MobileDevice
|
||||
fields = ["pk", "name", "state", "last_checkin"]
|
||||
depth = 2
|
||||
|
||||
|
||||
class MobileDeviceCheckInSerializer(PassiveSerializer):
|
||||
"""Check info into authentik"""
|
||||
|
@ -213,6 +218,29 @@ class MobileDeviceViewSet(
|
|||
transaction.save()
|
||||
return Response(status=204)
|
||||
|
||||
@extend_schema(
|
||||
responses={
|
||||
204: OpenApiResponse(description="Checked in"),
|
||||
},
|
||||
request=MobileDeviceInfoSerializer,
|
||||
)
|
||||
@action(
|
||||
methods=["POST"],
|
||||
detail=True,
|
||||
permission_classes=[],
|
||||
filter_backends=[],
|
||||
authentication_classes=[MobileDeviceTokenAuthentication],
|
||||
)
|
||||
def check_in(self, request: Request, pk: str) -> Response:
|
||||
"""Check in data about a device"""
|
||||
data = MobileDeviceInfoSerializer(data=request.data)
|
||||
data.is_valid(raise_exception=True)
|
||||
device: MobileDevice = self.get_object()
|
||||
device.last_checkin = now()
|
||||
device.state = data.validated_data
|
||||
device.save()
|
||||
return Response(status=204)
|
||||
|
||||
|
||||
class AdminMobileDeviceViewSet(ModelViewSet):
|
||||
"""Viewset for Mobile authenticator devices (for admins)"""
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 4.2.4 on 2023-09-05 13:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("authentik_stages_authenticator_mobile", "0003_mobiletransaction_status"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="mobiledevice",
|
||||
name="last_checkin",
|
||||
field=models.DateTimeField(auto_now=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="mobiledevice",
|
||||
name="state",
|
||||
field=models.JSONField(default=dict),
|
||||
),
|
||||
]
|
|
@ -93,6 +93,9 @@ class MobileDevice(SerializerModel, Device):
|
|||
device_id = models.TextField(unique=True)
|
||||
firebase_token = models.TextField(blank=True)
|
||||
|
||||
state = models.JSONField(default=dict)
|
||||
last_checkin = models.DateTimeField(auto_now=True)
|
||||
|
||||
@property
|
||||
def serializer(self) -> Serializer:
|
||||
from authentik.stages.authenticator_mobile.api.device import MobileDeviceSerializer
|
||||
|
@ -108,6 +111,8 @@ class MobileDevice(SerializerModel, Device):
|
|||
|
||||
|
||||
class TransactionStates(models.TextChoices):
|
||||
"""States a transaction can be in"""
|
||||
|
||||
wait = "wait"
|
||||
accept = "accept"
|
||||
deny = "deny"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
"""API URLs"""
|
||||
from rest_framework import routers
|
||||
|
||||
from authentik.stages.authenticator_mobile.api.device import (
|
||||
AdminMobileDeviceViewSet,
|
||||
MobileDeviceViewSet,
|
||||
)
|
||||
from authentik.stages.authenticator_mobile.api.stage import AuthenticatorMobileStageViewSet
|
||||
from rest_framework import routers
|
||||
|
||||
# Separate router which is used for the subset-schema generation
|
||||
# for the cloud-gateway we (currently) only want the mobile device endpoints
|
||||
|
|
|
@ -6040,6 +6040,11 @@
|
|||
"minLength": 1,
|
||||
"title": "Name",
|
||||
"description": "The human-readable name of this device."
|
||||
},
|
||||
"state": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "State"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
|
79
schema.yml
79
schema.yml
|
@ -2165,6 +2165,43 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/authenticators/mobile/{uuid}/check_in/:
|
||||
post:
|
||||
operationId: authenticators_mobile_check_in_create
|
||||
description: Check in data about a device
|
||||
parameters:
|
||||
- in: path
|
||||
name: uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this Mobile Device.
|
||||
required: true
|
||||
tags:
|
||||
- authenticators
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MobileDeviceInfoRequest'
|
||||
required: true
|
||||
security:
|
||||
- mobile_device_token: []
|
||||
responses:
|
||||
'204':
|
||||
description: Checked in
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/authenticators/mobile/{uuid}/enrollment_callback/:
|
||||
post:
|
||||
operationId: authenticators_mobile_enrollment_callback_create
|
||||
|
@ -34271,7 +34308,15 @@ components:
|
|||
type: string
|
||||
description: The human-readable name of this device.
|
||||
maxLength: 64
|
||||
state:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
last_checkin:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/MobileDeviceInfo'
|
||||
readOnly: true
|
||||
required:
|
||||
- last_checkin
|
||||
- name
|
||||
MobileDeviceEnrollmentCallback:
|
||||
type: object
|
||||
|
@ -34307,6 +34352,30 @@ components:
|
|||
description: |-
|
||||
* `success` - Success
|
||||
* `waiting` - Waiting
|
||||
MobileDeviceInfo:
|
||||
type: object
|
||||
description: Info about a mobile device
|
||||
properties:
|
||||
platform:
|
||||
$ref: '#/components/schemas/PlatformEnum'
|
||||
os_version:
|
||||
type: string
|
||||
model:
|
||||
type: string
|
||||
hostname:
|
||||
type: string
|
||||
app_version:
|
||||
type: string
|
||||
others:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
required:
|
||||
- app_version
|
||||
- hostname
|
||||
- model
|
||||
- os_version
|
||||
- others
|
||||
- platform
|
||||
MobileDeviceInfoRequest:
|
||||
type: object
|
||||
description: Info about a mobile device
|
||||
|
@ -34325,11 +34394,15 @@ components:
|
|||
app_version:
|
||||
type: string
|
||||
minLength: 1
|
||||
others:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
required:
|
||||
- app_version
|
||||
- hostname
|
||||
- model
|
||||
- os_version
|
||||
- others
|
||||
- platform
|
||||
MobileDeviceRequest:
|
||||
type: object
|
||||
|
@ -34344,6 +34417,9 @@ components:
|
|||
minLength: 1
|
||||
description: The human-readable name of this device.
|
||||
maxLength: 64
|
||||
state:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
required:
|
||||
- name
|
||||
MobileDeviceResponseRequest:
|
||||
|
@ -38130,6 +38206,9 @@ components:
|
|||
minLength: 1
|
||||
description: The human-readable name of this device.
|
||||
maxLength: 64
|
||||
state:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
PatchedNotificationRequest:
|
||||
type: object
|
||||
description: Notification Serializer
|
||||
|
|
|
@ -209,6 +209,43 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/authenticators/mobile/{uuid}/check_in/:
|
||||
post:
|
||||
operationId: authenticators_mobile_check_in_create
|
||||
description: Check in data about a device
|
||||
parameters:
|
||||
- in: path
|
||||
name: uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this Mobile Device.
|
||||
required: true
|
||||
tags:
|
||||
- authenticators
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MobileDeviceInfoRequest'
|
||||
required: true
|
||||
security:
|
||||
- mobile_device_token: []
|
||||
responses:
|
||||
'204':
|
||||
description: Checked in
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/authenticators/mobile/{uuid}/enrollment_callback/:
|
||||
post:
|
||||
operationId: authenticators_mobile_enrollment_callback_create
|
||||
|
@ -435,7 +472,15 @@ components:
|
|||
type: string
|
||||
description: The human-readable name of this device.
|
||||
maxLength: 64
|
||||
state:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
last_checkin:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/MobileDeviceInfo'
|
||||
readOnly: true
|
||||
required:
|
||||
- last_checkin
|
||||
- name
|
||||
MobileDeviceEnrollmentCallback:
|
||||
type: object
|
||||
|
@ -471,6 +516,30 @@ components:
|
|||
description: |-
|
||||
* `success` - Success
|
||||
* `waiting` - Waiting
|
||||
MobileDeviceInfo:
|
||||
type: object
|
||||
description: Info about a mobile device
|
||||
properties:
|
||||
platform:
|
||||
$ref: '#/components/schemas/PlatformEnum'
|
||||
os_version:
|
||||
type: string
|
||||
model:
|
||||
type: string
|
||||
hostname:
|
||||
type: string
|
||||
app_version:
|
||||
type: string
|
||||
others:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
required:
|
||||
- app_version
|
||||
- hostname
|
||||
- model
|
||||
- os_version
|
||||
- others
|
||||
- platform
|
||||
MobileDeviceInfoRequest:
|
||||
type: object
|
||||
description: Info about a mobile device
|
||||
|
@ -489,11 +558,15 @@ components:
|
|||
app_version:
|
||||
type: string
|
||||
minLength: 1
|
||||
others:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
required:
|
||||
- app_version
|
||||
- hostname
|
||||
- model
|
||||
- os_version
|
||||
- others
|
||||
- platform
|
||||
MobileDeviceRequest:
|
||||
type: object
|
||||
|
@ -508,6 +581,9 @@ components:
|
|||
minLength: 1
|
||||
description: The human-readable name of this device.
|
||||
maxLength: 64
|
||||
state:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
required:
|
||||
- name
|
||||
MobileDeviceResponseRequest:
|
||||
|
@ -591,6 +667,9 @@ components:
|
|||
minLength: 1
|
||||
description: The human-readable name of this device.
|
||||
maxLength: 64
|
||||
state:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
PlatformEnum:
|
||||
enum:
|
||||
- ios
|
||||
|
|
Reference in New Issue