add transaction states
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
a334d21708
commit
38e7a7fe59
|
@ -1,5 +1,5 @@
|
||||||
"""AuthenticatorMobileStage API Views"""
|
"""AuthenticatorMobileStage API Views"""
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.http import Http404
|
||||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||||
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
|
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
|
||||||
from rest_framework import mixins
|
from rest_framework import mixins
|
||||||
|
@ -16,7 +16,12 @@ from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.stages.authenticator_mobile.api.auth import MobileDeviceTokenAuthentication
|
from authentik.stages.authenticator_mobile.api.auth import MobileDeviceTokenAuthentication
|
||||||
from authentik.stages.authenticator_mobile.models import MobileDevice, MobileDeviceToken
|
from authentik.stages.authenticator_mobile.models import (
|
||||||
|
MobileDevice,
|
||||||
|
MobileDeviceToken,
|
||||||
|
MobileTransaction,
|
||||||
|
TransactionStates,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MobileDeviceSerializer(ModelSerializer):
|
class MobileDeviceSerializer(ModelSerializer):
|
||||||
|
@ -66,16 +71,7 @@ class MobileDeviceResponseSerializer(PassiveSerializer):
|
||||||
|
|
||||||
tx_id = CharField(required=True)
|
tx_id = CharField(required=True)
|
||||||
status = ChoiceField(
|
status = ChoiceField(
|
||||||
(
|
TransactionStates.choices,
|
||||||
(
|
|
||||||
"accept",
|
|
||||||
_("Accept"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"deny",
|
|
||||||
_("Deny"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -193,6 +189,7 @@ class MobileDeviceViewSet(
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
responses={
|
responses={
|
||||||
204: OpenApiResponse(description="Key successfully set"),
|
204: OpenApiResponse(description="Key successfully set"),
|
||||||
|
404: OpenApiResponse(description="Transaction not found"),
|
||||||
},
|
},
|
||||||
request=MobileDeviceResponseSerializer,
|
request=MobileDeviceResponseSerializer,
|
||||||
)
|
)
|
||||||
|
@ -205,7 +202,12 @@ class MobileDeviceViewSet(
|
||||||
)
|
)
|
||||||
def receive_response(self, request: Request, pk: str) -> Response:
|
def receive_response(self, request: Request, pk: str) -> Response:
|
||||||
"""Get response from notification on phone"""
|
"""Get response from notification on phone"""
|
||||||
print(request.data)
|
data = MobileDeviceResponseSerializer(data=request.data)
|
||||||
|
data.is_valid()
|
||||||
|
transaction = MobileTransaction.objects.filter(tx_id=data.validated_data["tx_id"]).first()
|
||||||
|
if not transaction:
|
||||||
|
raise Http404
|
||||||
|
transaction.status = data.validated_data["status"]
|
||||||
return Response(status=204)
|
return Response(status=204)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
# Generated by Django 4.2.4 on 2023-09-04 18:18
|
# Generated by Django 4.2.4 on 2023-09-04 18:18
|
||||||
|
|
||||||
import authentik.core.models
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import authentik.core.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 4.2.4 on 2023-09-04 18:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("authentik_stages_authenticator_mobile", "0002_mobiletransaction"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="mobiletransaction",
|
||||||
|
name="status",
|
||||||
|
field=models.TextField(
|
||||||
|
choices=[("wait", "Wait"), ("accept", "Accept"), ("deny", "Deny")], default="wait"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -106,12 +106,20 @@ class MobileDevice(SerializerModel, Device):
|
||||||
verbose_name_plural = _("Mobile Devices")
|
verbose_name_plural = _("Mobile Devices")
|
||||||
|
|
||||||
|
|
||||||
|
class TransactionStates(models.TextChoices):
|
||||||
|
wait = "wait"
|
||||||
|
accept = "accept"
|
||||||
|
deny = "deny"
|
||||||
|
|
||||||
|
|
||||||
class MobileTransaction(ExpiringModel):
|
class MobileTransaction(ExpiringModel):
|
||||||
"""A single push transaction"""
|
"""A single push transaction"""
|
||||||
|
|
||||||
tx_id = models.UUIDField(default=uuid4, primary_key=True)
|
tx_id = models.UUIDField(default=uuid4, primary_key=True)
|
||||||
device = models.ForeignKey(MobileDevice, on_delete=models.CASCADE)
|
device = models.ForeignKey(MobileDevice, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
status = models.TextField(choices=TransactionStates.choices, default=TransactionStates.wait)
|
||||||
|
|
||||||
def send_message(self, request: Optional[HttpRequest], **context):
|
def send_message(self, request: Optional[HttpRequest], **context):
|
||||||
"""Send mobile message"""
|
"""Send mobile message"""
|
||||||
branding = DEFAULT_TENANT.branding_title
|
branding = DEFAULT_TENANT.branding_title
|
||||||
|
@ -120,6 +128,9 @@ class MobileTransaction(ExpiringModel):
|
||||||
branding = request.tenant.branding_title
|
branding = request.tenant.branding_title
|
||||||
domain = request.get_host()
|
domain = request.get_host()
|
||||||
message = Message(
|
message = Message(
|
||||||
|
data={
|
||||||
|
"tx_id": str(self.tx_id),
|
||||||
|
},
|
||||||
notification=Notification(
|
notification=Notification(
|
||||||
title=__("%(brand)s authentication request" % {"brand": branding}),
|
title=__("%(brand)s authentication request" % {"brand": branding}),
|
||||||
body=__(
|
body=__(
|
||||||
|
@ -144,7 +155,6 @@ class MobileTransaction(ExpiringModel):
|
||||||
category="cat_authentik_push_authorization",
|
category="cat_authentik_push_authorization",
|
||||||
),
|
),
|
||||||
interruption_level="time-sensitive",
|
interruption_level="time-sensitive",
|
||||||
tx_id=str(self.tx_id),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
token=self.device.firebase_token,
|
token=self.device.firebase_token,
|
||||||
|
|
|
@ -2266,6 +2266,8 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
'204':
|
'204':
|
||||||
description: Key successfully set
|
description: Key successfully set
|
||||||
|
'404':
|
||||||
|
description: Transaction not found
|
||||||
'400':
|
'400':
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
|
@ -35342,10 +35344,12 @@ components:
|
||||||
- tx_id
|
- tx_id
|
||||||
MobileDeviceResponseStatusEnum:
|
MobileDeviceResponseStatusEnum:
|
||||||
enum:
|
enum:
|
||||||
|
- wait
|
||||||
- accept
|
- accept
|
||||||
- deny
|
- deny
|
||||||
type: string
|
type: string
|
||||||
description: |-
|
description: |-
|
||||||
|
* `wait` - Wait
|
||||||
* `accept` - Accept
|
* `accept` - Accept
|
||||||
* `deny` - Deny
|
* `deny` - Deny
|
||||||
MobileDeviceSetPushKeyRequest:
|
MobileDeviceSetPushKeyRequest:
|
||||||
|
|
Reference in New Issue