47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
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)
|