From 97a841d1bbbc105124e9c0f2b8d8629573743b36 Mon Sep 17 00:00:00 2001
From: Andrew Godwin
Date: Sun, 20 Nov 2022 18:32:55 -0700
Subject: Move signed request onto Identity as a shortcut

---
 users/models/follow.py   | 16 ++++++----------
 users/models/identity.py | 21 +++++++++++++++++++--
 2 files changed, 25 insertions(+), 12 deletions(-)

(limited to 'users/models')

diff --git a/users/models/follow.py b/users/models/follow.py
index e741c56..5f0d6ab 100644
--- a/users/models/follow.py
+++ b/users/models/follow.py
@@ -3,7 +3,6 @@ from typing import Optional
 from django.db import models, transaction
 
 from core.ld import canonicalise
-from core.signatures import HttpSignature
 from stator.models import State, StateField, StateGraph, StatorModel
 from users.models.identity import Identity
 
@@ -38,11 +37,10 @@ class FollowStates(StateGraph):
         if not follow.source.local:
             return cls.remote_requested
         # Sign it and send it
-        await HttpSignature.signed_request(
+        await follow.source.signed_request(
+            method="post",
             uri=follow.target.inbox_uri,
             body=canonicalise(follow.to_ap()),
-            private_key=follow.source.private_key,
-            key_id=follow.source.public_key_id,
         )
         return cls.local_requested
 
@@ -58,11 +56,10 @@ class FollowStates(StateGraph):
         source server.
         """
         follow = await instance.afetch_full()
-        await HttpSignature.signed_request(
+        await follow.target.signed_request(
+            method="post",
             uri=follow.source.inbox_uri,
             body=canonicalise(follow.to_accept_ap()),
-            private_key=follow.target.private_key,
-            key_id=follow.target.public_key_id,
         )
         return cls.accepted
 
@@ -72,11 +69,10 @@ class FollowStates(StateGraph):
         Delivers the Undo object to the target server
         """
         follow = await instance.afetch_full()
-        await HttpSignature.signed_request(
+        await follow.source.signed_request(
+            method="post",
             uri=follow.target.inbox_uri,
             body=canonicalise(follow.to_undo_ap()),
-            private_key=follow.source.private_key,
-            key_id=follow.source.public_key_id,
         )
         return cls.undone_remotely
 
diff --git a/users/models/identity.py b/users/models/identity.py
index 98e7df9..c2edf92 100644
--- a/users/models/identity.py
+++ b/users/models/identity.py
@@ -1,5 +1,5 @@
 from functools import partial
-from typing import Optional, Tuple
+from typing import Dict, Literal, Optional, Tuple
 from urllib.parse import urlparse
 
 import httpx
@@ -13,7 +13,7 @@ from django.utils import timezone
 from core.exceptions import ActorMismatchError
 from core.html import sanitize_post
 from core.ld import canonicalise, media_type_from_filename
-from core.signatures import RsaKeys
+from core.signatures import HttpSignature, RsaKeys
 from core.uploads import upload_namer
 from stator.models import State, StateField, StateGraph, StatorModel
 from users.models.domain import Domain
@@ -384,6 +384,23 @@ class Identity(StatorModel):
 
     ### Cryptography ###
 
+    async def signed_request(
+        self,
+        method: Literal["get", "post"],
+        uri: str,
+        body: Optional[Dict] = None,
+    ):
+        """
+        Performs a signed request on behalf of the System Actor.
+        """
+        return await HttpSignature.signed_request(
+            method=method,
+            uri=uri,
+            body=body,
+            private_key=self.private_key,
+            key_id=self.public_key_id,
+        )
+
     def generate_keypair(self):
         if not self.local:
             raise ValueError("Cannot generate keypair for remote user")
-- 
cgit v1.2.3