Skip to content
Snippets Groups Projects
authentication.py 1.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • import cryptography
    
    from django.contrib.auth.models import AnonymousUser
    
    from rest_framework import authentication
    from rest_framework import exceptions
    
    from . import actors
    from . import keys
    from . import serializers
    from . import signing
    
    
    class SignatureAuthentication(authentication.BaseAuthentication):
        def authenticate(self, request):
            try:
                signature = request.META['headers']['Signature']
                key_id = keys.get_key_id_from_signature_header(signature)
            except KeyError:
                raise exceptions.AuthenticationFailed('No signature')
            except ValueError as e:
                raise exceptions.AuthenticationFailed(str(e))
    
            try:
                actor_data = actors.get_actor_data(key_id)
            except Exception as e:
                raise exceptions.AuthenticationFailed(str(e))
    
            try:
                public_key = actor_data['publicKey']['publicKeyPem']
            except KeyError:
                raise exceptions.AuthenticationFailed('No public key found')
    
            serializer = serializers.ActorSerializer(data=actor_data)
            if not serializer.is_valid():
                raise exceptions.AuthenticationFailed('Invalid actor payload')
    
            try:
                signing.verify_django(request, public_key.encode('utf-8'))
            except cryptography.exceptions.InvalidSignature:
                raise exceptions.AuthenticationFailed('Invalid signature')
    
            user = AnonymousUser()
            ac = serializer.build()
            setattr(request, 'actor', ac)
            return (user, None)