2018-03-31 13:47:21 +00:00
|
|
|
import cryptography
|
|
|
|
from django.contrib.auth.models import AnonymousUser
|
2018-06-10 08:55:16 +00:00
|
|
|
from rest_framework import authentication, exceptions
|
2018-03-31 13:47:21 +00:00
|
|
|
|
2018-06-10 08:55:16 +00:00
|
|
|
from . import actors, keys, signing, utils
|
2018-03-31 13:47:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
class SignatureAuthentication(authentication.BaseAuthentication):
|
2018-03-31 16:40:41 +00:00
|
|
|
def authenticate_actor(self, request):
|
|
|
|
headers = utils.clean_wsgi_headers(request.META)
|
2018-03-31 13:47:21 +00:00
|
|
|
try:
|
2018-06-09 13:36:16 +00:00
|
|
|
signature = headers["Signature"]
|
2018-03-31 13:47:21 +00:00
|
|
|
key_id = keys.get_key_id_from_signature_header(signature)
|
|
|
|
except KeyError:
|
2018-03-31 16:40:41 +00:00
|
|
|
return
|
2018-03-31 13:47:21 +00:00
|
|
|
except ValueError as e:
|
|
|
|
raise exceptions.AuthenticationFailed(str(e))
|
|
|
|
|
|
|
|
try:
|
2018-06-09 13:36:16 +00:00
|
|
|
actor = actors.get_actor(key_id.split("#")[0])
|
2018-03-31 13:47:21 +00:00
|
|
|
except Exception as e:
|
|
|
|
raise exceptions.AuthenticationFailed(str(e))
|
|
|
|
|
2018-04-27 22:25:47 +00:00
|
|
|
if not actor.public_key:
|
2018-06-09 13:36:16 +00:00
|
|
|
raise exceptions.AuthenticationFailed("No public key found")
|
2018-03-31 13:47:21 +00:00
|
|
|
|
|
|
|
try:
|
2018-06-09 13:36:16 +00:00
|
|
|
signing.verify_django(request, actor.public_key.encode("utf-8"))
|
2018-03-31 13:47:21 +00:00
|
|
|
except cryptography.exceptions.InvalidSignature:
|
2018-06-09 13:36:16 +00:00
|
|
|
raise exceptions.AuthenticationFailed("Invalid signature")
|
2018-03-31 13:47:21 +00:00
|
|
|
|
2018-04-27 22:25:47 +00:00
|
|
|
return actor
|
2018-03-31 16:40:41 +00:00
|
|
|
|
|
|
|
def authenticate(self, request):
|
2018-06-09 13:36:16 +00:00
|
|
|
setattr(request, "actor", None)
|
2018-03-31 16:40:41 +00:00
|
|
|
actor = self.authenticate_actor(request)
|
2018-04-07 13:34:35 +00:00
|
|
|
if not actor:
|
|
|
|
return
|
2018-03-31 13:47:21 +00:00
|
|
|
user = AnonymousUser()
|
2018-06-09 13:36:16 +00:00
|
|
|
setattr(request, "actor", actor)
|
2018-03-31 13:47:21 +00:00
|
|
|
return (user, None)
|