strings
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
f4a18d1778
commit
14ab9a9f1b
|
@ -1,6 +1,6 @@
|
||||||
"""AuthenticatorMobileStage API Views"""
|
"""AuthenticatorMobileStage API Views"""
|
||||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||||
from drf_spectacular.utils import extend_schema, inline_serializer, OpenApiResponse
|
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
|
||||||
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
|
from rest_framework.fields import CharField, ChoiceField
|
||||||
|
@ -115,11 +115,13 @@ class MobileDeviceViewSet(
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@action(methods=["POST"],
|
@action(
|
||||||
|
methods=["POST"],
|
||||||
detail=True,
|
detail=True,
|
||||||
permission_classes=[],
|
permission_classes=[],
|
||||||
filter_backends=[],
|
filter_backends=[],
|
||||||
authentication_classes=[MobileDeviceTokenAuthentication],)
|
authentication_classes=[MobileDeviceTokenAuthentication],
|
||||||
|
)
|
||||||
def enrollment_status(self, request: Request, pk: str) -> Response:
|
def enrollment_status(self, request: Request, pk: str) -> Response:
|
||||||
"""Check device enrollment status"""
|
"""Check device enrollment status"""
|
||||||
device: MobileDevice = self.get_object()
|
device: MobileDevice = self.get_object()
|
||||||
|
|
|
@ -1,39 +1,42 @@
|
||||||
"""Mobile authenticator stage"""
|
"""Mobile authenticator stage"""
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.db import models
|
||||||
|
from django.http import HttpRequest
|
||||||
|
from django.utils.translation import gettext as __
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views import View
|
||||||
|
from django_otp.models import Device
|
||||||
|
from firebase_admin import credentials, initialize_app
|
||||||
|
from firebase_admin.exceptions import FirebaseError
|
||||||
from firebase_admin.messaging import (
|
from firebase_admin.messaging import (
|
||||||
Message,
|
|
||||||
send,
|
|
||||||
AndroidConfig,
|
AndroidConfig,
|
||||||
AndroidNotification,
|
AndroidNotification,
|
||||||
APNSConfig,
|
APNSConfig,
|
||||||
APNSPayload,
|
APNSPayload,
|
||||||
Notification,
|
|
||||||
Aps,
|
Aps,
|
||||||
|
Message,
|
||||||
|
Notification,
|
||||||
|
send,
|
||||||
)
|
)
|
||||||
from firebase_admin.exceptions import FirebaseError
|
|
||||||
from structlog.stdlib import get_logger
|
|
||||||
from django.contrib.auth import get_user_model
|
|
||||||
from django.db import models
|
|
||||||
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 rest_framework.serializers import BaseSerializer, Serializer
|
||||||
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
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
|
||||||
from authentik.lib.models import SerializerModel
|
from authentik.lib.models import SerializerModel
|
||||||
|
from authentik.tenants.utils import DEFAULT_TENANT
|
||||||
from firebase_admin import initialize_app
|
|
||||||
from firebase_admin import credentials
|
|
||||||
|
|
||||||
cred = credentials.Certificate("firebase.json")
|
cred = credentials.Certificate("firebase.json")
|
||||||
initialize_app(cred)
|
initialize_app(cred)
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
def default_token_key():
|
def default_token_key():
|
||||||
"""Default token key"""
|
"""Default token key"""
|
||||||
return generate_id(40)
|
return generate_id(40)
|
||||||
|
@ -95,11 +98,23 @@ class MobileDevice(SerializerModel, Device):
|
||||||
|
|
||||||
return MobileDeviceSerializer
|
return MobileDeviceSerializer
|
||||||
|
|
||||||
def send_message(self, **context):
|
def send_message(self, request: Optional[HttpRequest], **context):
|
||||||
|
"""Send mobile message"""
|
||||||
|
branding = DEFAULT_TENANT.branding_title
|
||||||
|
domain = ""
|
||||||
|
if request:
|
||||||
|
branding = request.tenant.branding_title
|
||||||
|
domain = request.get_host()
|
||||||
message = Message(
|
message = Message(
|
||||||
notification=Notification(
|
notification=Notification(
|
||||||
title="$GOOG up 1.43% on the day",
|
title=__("%(brand)s authentication request" % {"brand": branding}),
|
||||||
body="$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
|
body=__(
|
||||||
|
"%(user)s is attempting to log in to %(domain)s"
|
||||||
|
% {
|
||||||
|
"user": self.user.username,
|
||||||
|
"domain": domain,
|
||||||
|
}
|
||||||
|
),
|
||||||
),
|
),
|
||||||
android=AndroidConfig(
|
android=AndroidConfig(
|
||||||
priority="normal",
|
priority="normal",
|
||||||
|
|
|
@ -142,7 +142,12 @@ class AuthenticatorValidationChallengeResponse(ChallengeResponse):
|
||||||
def validate(self, attrs: dict):
|
def validate(self, attrs: dict):
|
||||||
# Checking if the given data is from a valid device class is done above
|
# Checking if the given data is from a valid device class is done above
|
||||||
# Here we only check if the any data was sent at all
|
# Here we only check if the any data was sent at all
|
||||||
if "code" not in attrs and "webauthn" not in attrs and "duo" not in attrs and "mobile" not in attrs:
|
if (
|
||||||
|
"code" not in attrs
|
||||||
|
and "webauthn" not in attrs
|
||||||
|
and "duo" not in attrs
|
||||||
|
and "mobile" not in attrs
|
||||||
|
):
|
||||||
raise ValidationError("Empty response")
|
raise ValidationError("Empty response")
|
||||||
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD, "auth_mfa")
|
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD, "auth_mfa")
|
||||||
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD_ARGS, {})
|
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD_ARGS, {})
|
||||||
|
|
Reference in New Issue