authentik.enterprise.endpoints.connectors.agent.views.apple_register
1from django.urls import reverse 2from drf_spectacular.utils import extend_schema 3from rest_framework.exceptions import ValidationError 4from rest_framework.fields import CharField 5from rest_framework.permissions import IsAuthenticated 6from rest_framework.request import Request 7from rest_framework.response import Response 8from rest_framework.views import APIView 9 10from authentik.api.validation import validate 11from authentik.core.api.users import UserSelfSerializer 12from authentik.core.api.utils import PassiveSerializer 13from authentik.endpoints.connectors.agent.auth import AgentAuth 14from authentik.endpoints.connectors.agent.models import ( 15 AgentDeviceConnection, 16 AgentDeviceUserBinding, 17 DeviceAuthenticationToken, 18 DeviceToken, 19) 20from authentik.enterprise.api import EnterpriseRequiredMixin 21from authentik.lib.generators import generate_key 22 23 24class RegisterDeviceView(APIView): 25 26 class AgentPSSODeviceRegistration(EnterpriseRequiredMixin, PassiveSerializer): 27 """Register Apple device via Platform SSO""" 28 29 device_signing_key = CharField() 30 device_encryption_key = CharField() 31 sign_key_id = CharField() 32 enc_key_id = CharField() 33 34 class AgentPSSODeviceRegistrationResponse(PassiveSerializer): 35 """authentik settings for Platform SSO tokens""" 36 37 client_id = CharField() 38 issuer = CharField() 39 token_endpoint = CharField() 40 jwks_endpoint = CharField() 41 audience = CharField() 42 nonce_endpoint = CharField() 43 44 permission_classes = [IsAuthenticated] 45 pagination_class = None 46 filter_backends = [] 47 serializer_class = AgentPSSODeviceRegistration 48 authentication_classes = [AgentAuth] 49 50 @extend_schema( 51 responses={ 52 200: AgentPSSODeviceRegistrationResponse(), 53 } 54 ) 55 @validate(AgentPSSODeviceRegistration) 56 def post(self, request: Request, body: AgentPSSODeviceRegistration) -> Response: 57 device_token: DeviceToken = request.auth 58 conn: AgentDeviceConnection = device_token.device 59 conn.apple_signing_key = body.validated_data["device_signing_key"] 60 conn.apple_encryption_key = body.validated_data["device_encryption_key"] 61 conn.apple_sign_key_id = body.validated_data["sign_key_id"] 62 conn.apple_enc_key_id = body.validated_data["enc_key_id"] 63 conn.apple_key_exchange_key = generate_key() 64 conn.save() 65 return Response( 66 data={ 67 "client_id": str(conn.connector.pk), 68 "issuer": self.request.build_absolute_uri( 69 reverse("authentik_enterprise_endpoints_connectors_agent:psso-token") 70 ), 71 "audience": str(conn.device.pk), 72 "token_endpoint": request.build_absolute_uri( 73 reverse("authentik_enterprise_endpoints_connectors_agent:psso-token") 74 ), 75 "jwks_endpoint": request.build_absolute_uri( 76 reverse("authentik_enterprise_endpoints_connectors_agent:psso-jwks") 77 ), 78 "nonce_endpoint": request.build_absolute_uri( 79 reverse("authentik_enterprise_endpoints_connectors_agent:psso-nonce") 80 ), 81 } 82 ) 83 84 85class RegisterUserView(APIView): 86 87 class AgentPSSOUserRegistration(EnterpriseRequiredMixin, PassiveSerializer): 88 """Register Apple device user via Platform SSO""" 89 90 user_auth = CharField() 91 user_secure_enclave_key = CharField() 92 enclave_key_id = CharField() 93 94 permission_classes = [IsAuthenticated] 95 pagination_class = None 96 filter_backends = [] 97 serializer_class = AgentPSSOUserRegistration 98 authentication_classes = [AgentAuth] 99 100 @extend_schema( 101 responses={ 102 200: UserSelfSerializer(), 103 } 104 ) 105 @validate(AgentPSSOUserRegistration) 106 def post(self, request: Request, body: AgentPSSOUserRegistration) -> Response: 107 device_token: DeviceToken = request.auth 108 conn: AgentDeviceConnection = device_token.device 109 user_token = DeviceAuthenticationToken.objects.filter( 110 device=conn.device, 111 token=body.validated_data["user_auth"], 112 device_token=device_token, 113 ).first() 114 if not user_token: 115 raise ValidationError("Invalid user authentication") 116 AgentDeviceUserBinding.objects.update_or_create( 117 target=conn.device, 118 user=user_token.user, 119 connector=conn.connector, 120 create_defaults={ 121 "is_primary": True, 122 "order": 0, 123 }, 124 defaults={ 125 "apple_secure_enclave_key": body.validated_data["user_secure_enclave_key"], 126 "apple_enclave_key_id": body.validated_data["enclave_key_id"], 127 }, 128 ) 129 return Response( 130 UserSelfSerializer(instance=user_token.user, context={"request": request}).data 131 )
class
RegisterDeviceView(rest_framework.views.APIView):
25class RegisterDeviceView(APIView): 26 27 class AgentPSSODeviceRegistration(EnterpriseRequiredMixin, PassiveSerializer): 28 """Register Apple device via Platform SSO""" 29 30 device_signing_key = CharField() 31 device_encryption_key = CharField() 32 sign_key_id = CharField() 33 enc_key_id = CharField() 34 35 class AgentPSSODeviceRegistrationResponse(PassiveSerializer): 36 """authentik settings for Platform SSO tokens""" 37 38 client_id = CharField() 39 issuer = CharField() 40 token_endpoint = CharField() 41 jwks_endpoint = CharField() 42 audience = CharField() 43 nonce_endpoint = CharField() 44 45 permission_classes = [IsAuthenticated] 46 pagination_class = None 47 filter_backends = [] 48 serializer_class = AgentPSSODeviceRegistration 49 authentication_classes = [AgentAuth] 50 51 @extend_schema( 52 responses={ 53 200: AgentPSSODeviceRegistrationResponse(), 54 } 55 ) 56 @validate(AgentPSSODeviceRegistration) 57 def post(self, request: Request, body: AgentPSSODeviceRegistration) -> Response: 58 device_token: DeviceToken = request.auth 59 conn: AgentDeviceConnection = device_token.device 60 conn.apple_signing_key = body.validated_data["device_signing_key"] 61 conn.apple_encryption_key = body.validated_data["device_encryption_key"] 62 conn.apple_sign_key_id = body.validated_data["sign_key_id"] 63 conn.apple_enc_key_id = body.validated_data["enc_key_id"] 64 conn.apple_key_exchange_key = generate_key() 65 conn.save() 66 return Response( 67 data={ 68 "client_id": str(conn.connector.pk), 69 "issuer": self.request.build_absolute_uri( 70 reverse("authentik_enterprise_endpoints_connectors_agent:psso-token") 71 ), 72 "audience": str(conn.device.pk), 73 "token_endpoint": request.build_absolute_uri( 74 reverse("authentik_enterprise_endpoints_connectors_agent:psso-token") 75 ), 76 "jwks_endpoint": request.build_absolute_uri( 77 reverse("authentik_enterprise_endpoints_connectors_agent:psso-jwks") 78 ), 79 "nonce_endpoint": request.build_absolute_uri( 80 reverse("authentik_enterprise_endpoints_connectors_agent:psso-nonce") 81 ), 82 } 83 )
Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking.
serializer_class =
<class 'RegisterDeviceView.AgentPSSODeviceRegistration'>
authentication_classes =
[<class 'authentik.endpoints.connectors.agent.auth.AgentAuth'>]
@extend_schema(responses={200: AgentPSSODeviceRegistrationResponse()})
@validate(AgentPSSODeviceRegistration)
def
post( self, request: rest_framework.request.Request, body: RegisterDeviceView.AgentPSSODeviceRegistration) -> rest_framework.response.Response:
51 @extend_schema( 52 responses={ 53 200: AgentPSSODeviceRegistrationResponse(), 54 } 55 ) 56 @validate(AgentPSSODeviceRegistration) 57 def post(self, request: Request, body: AgentPSSODeviceRegistration) -> Response: 58 device_token: DeviceToken = request.auth 59 conn: AgentDeviceConnection = device_token.device 60 conn.apple_signing_key = body.validated_data["device_signing_key"] 61 conn.apple_encryption_key = body.validated_data["device_encryption_key"] 62 conn.apple_sign_key_id = body.validated_data["sign_key_id"] 63 conn.apple_enc_key_id = body.validated_data["enc_key_id"] 64 conn.apple_key_exchange_key = generate_key() 65 conn.save() 66 return Response( 67 data={ 68 "client_id": str(conn.connector.pk), 69 "issuer": self.request.build_absolute_uri( 70 reverse("authentik_enterprise_endpoints_connectors_agent:psso-token") 71 ), 72 "audience": str(conn.device.pk), 73 "token_endpoint": request.build_absolute_uri( 74 reverse("authentik_enterprise_endpoints_connectors_agent:psso-token") 75 ), 76 "jwks_endpoint": request.build_absolute_uri( 77 reverse("authentik_enterprise_endpoints_connectors_agent:psso-jwks") 78 ), 79 "nonce_endpoint": request.build_absolute_uri( 80 reverse("authentik_enterprise_endpoints_connectors_agent:psso-nonce") 81 ), 82 } 83 )
class
RegisterDeviceView.AgentPSSODeviceRegistration(authentik.enterprise.api.EnterpriseRequiredMixin, authentik.core.api.utils.PassiveSerializer):
27 class AgentPSSODeviceRegistration(EnterpriseRequiredMixin, PassiveSerializer): 28 """Register Apple device via Platform SSO""" 29 30 device_signing_key = CharField() 31 device_encryption_key = CharField() 32 sign_key_id = CharField() 33 enc_key_id = CharField()
Register Apple device via Platform SSO
class
RegisterDeviceView.AgentPSSODeviceRegistrationResponse(authentik.core.api.utils.PassiveSerializer):
35 class AgentPSSODeviceRegistrationResponse(PassiveSerializer): 36 """authentik settings for Platform SSO tokens""" 37 38 client_id = CharField() 39 issuer = CharField() 40 token_endpoint = CharField() 41 jwks_endpoint = CharField() 42 audience = CharField() 43 nonce_endpoint = CharField()
authentik settings for Platform SSO tokens
Inherited Members
class
RegisterUserView(rest_framework.views.APIView):
86class RegisterUserView(APIView): 87 88 class AgentPSSOUserRegistration(EnterpriseRequiredMixin, PassiveSerializer): 89 """Register Apple device user via Platform SSO""" 90 91 user_auth = CharField() 92 user_secure_enclave_key = CharField() 93 enclave_key_id = CharField() 94 95 permission_classes = [IsAuthenticated] 96 pagination_class = None 97 filter_backends = [] 98 serializer_class = AgentPSSOUserRegistration 99 authentication_classes = [AgentAuth] 100 101 @extend_schema( 102 responses={ 103 200: UserSelfSerializer(), 104 } 105 ) 106 @validate(AgentPSSOUserRegistration) 107 def post(self, request: Request, body: AgentPSSOUserRegistration) -> Response: 108 device_token: DeviceToken = request.auth 109 conn: AgentDeviceConnection = device_token.device 110 user_token = DeviceAuthenticationToken.objects.filter( 111 device=conn.device, 112 token=body.validated_data["user_auth"], 113 device_token=device_token, 114 ).first() 115 if not user_token: 116 raise ValidationError("Invalid user authentication") 117 AgentDeviceUserBinding.objects.update_or_create( 118 target=conn.device, 119 user=user_token.user, 120 connector=conn.connector, 121 create_defaults={ 122 "is_primary": True, 123 "order": 0, 124 }, 125 defaults={ 126 "apple_secure_enclave_key": body.validated_data["user_secure_enclave_key"], 127 "apple_enclave_key_id": body.validated_data["enclave_key_id"], 128 }, 129 ) 130 return Response( 131 UserSelfSerializer(instance=user_token.user, context={"request": request}).data 132 )
Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking.
serializer_class =
<class 'RegisterUserView.AgentPSSOUserRegistration'>
authentication_classes =
[<class 'authentik.endpoints.connectors.agent.auth.AgentAuth'>]
@extend_schema(responses={200: UserSelfSerializer()})
@validate(AgentPSSOUserRegistration)
def
post( self, request: rest_framework.request.Request, body: RegisterUserView.AgentPSSOUserRegistration) -> rest_framework.response.Response:
101 @extend_schema( 102 responses={ 103 200: UserSelfSerializer(), 104 } 105 ) 106 @validate(AgentPSSOUserRegistration) 107 def post(self, request: Request, body: AgentPSSOUserRegistration) -> Response: 108 device_token: DeviceToken = request.auth 109 conn: AgentDeviceConnection = device_token.device 110 user_token = DeviceAuthenticationToken.objects.filter( 111 device=conn.device, 112 token=body.validated_data["user_auth"], 113 device_token=device_token, 114 ).first() 115 if not user_token: 116 raise ValidationError("Invalid user authentication") 117 AgentDeviceUserBinding.objects.update_or_create( 118 target=conn.device, 119 user=user_token.user, 120 connector=conn.connector, 121 create_defaults={ 122 "is_primary": True, 123 "order": 0, 124 }, 125 defaults={ 126 "apple_secure_enclave_key": body.validated_data["user_secure_enclave_key"], 127 "apple_enclave_key_id": body.validated_data["enclave_key_id"], 128 }, 129 ) 130 return Response( 131 UserSelfSerializer(instance=user_token.user, context={"request": request}).data 132 )
class
RegisterUserView.AgentPSSOUserRegistration(authentik.enterprise.api.EnterpriseRequiredMixin, authentik.core.api.utils.PassiveSerializer):
88 class AgentPSSOUserRegistration(EnterpriseRequiredMixin, PassiveSerializer): 89 """Register Apple device user via Platform SSO""" 90 91 user_auth = CharField() 92 user_secure_enclave_key = CharField() 93 enclave_key_id = CharField()
Register Apple device user via Platform SSO