summaryrefslogtreecommitdiffstats
path: root/users/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'users/tasks')
-rw-r--r--users/tasks/__init__.py0
-rw-r--r--users/tasks/follow.py28
-rw-r--r--users/tasks/identity.py11
-rw-r--r--users/tasks/inbox.py36
4 files changed, 75 insertions, 0 deletions
diff --git a/users/tasks/__init__.py b/users/tasks/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/users/tasks/__init__.py
diff --git a/users/tasks/follow.py b/users/tasks/follow.py
new file mode 100644
index 0000000..3260124
--- /dev/null
+++ b/users/tasks/follow.py
@@ -0,0 +1,28 @@
+from core.ld import canonicalise
+from core.signatures import HttpSignature
+from users.models import Follow
+
+
+async def handle_follow_request(task_handler):
+ """
+ Request a follow from a remote server
+ """
+ follow = await Follow.objects.select_related(
+ "source", "source__domain", "target"
+ ).aget(pk=task_handler.subject)
+ # Construct the request
+ request = canonicalise(
+ {
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "id": follow.uri,
+ "type": "Follow",
+ "actor": follow.source.actor_uri,
+ "object": follow.target.actor_uri,
+ }
+ )
+ # Sign it and send it
+ response = await HttpSignature.signed_request(
+ follow.target.inbox_uri, request, follow.source
+ )
+ print(response)
+ print(response.content)
diff --git a/users/tasks/identity.py b/users/tasks/identity.py
new file mode 100644
index 0000000..f5cd214
--- /dev/null
+++ b/users/tasks/identity.py
@@ -0,0 +1,11 @@
+from asgiref.sync import sync_to_async
+
+from users.models import Identity
+
+
+async def handle_identity_fetch(task_handler):
+ # Get the actor URI via webfinger
+ actor_uri, handle = await Identity.fetch_webfinger(task_handler.subject)
+ # Get or create the identity, then fetch
+ identity = await sync_to_async(Identity.by_actor_uri_with_create)(actor_uri)
+ await identity.fetch_actor()
diff --git a/users/tasks/inbox.py b/users/tasks/inbox.py
new file mode 100644
index 0000000..ab80648
--- /dev/null
+++ b/users/tasks/inbox.py
@@ -0,0 +1,36 @@
+from users.models import Follow, Identity
+
+
+async def handle_inbox_item(task_handler):
+ type = task_handler.payload["type"].lower()
+ if type == "follow":
+ await inbox_follow(task_handler.payload)
+ elif type == "undo":
+ inner_type = task_handler.payload["object"]["type"].lower()
+ if inner_type == "follow":
+ await inbox_unfollow(task_handler.payload["object"])
+ else:
+ raise ValueError("Cannot undo activity of type {inner_type}")
+ else:
+ raise ValueError("Cannot handle activity of type {inner_type}")
+
+
+async def inbox_follow(payload):
+ """
+ Handles an incoming follow request
+ """
+ # TODO: Manually approved follows
+ source = Identity.by_actor_uri_with_create(payload["actor"])
+ target = Identity.by_actor_uri(payload["object"])
+ # See if this follow already exists
+ try:
+ follow = Follow.objects.get(source=source, target=target)
+ except Follow.DoesNotExist:
+ follow = Follow.objects.create(source=source, target=target, uri=payload["id"])
+ # See if we need to acknowledge it
+ if not follow.acknowledged:
+ pass
+
+
+async def inbox_unfollow(payload):
+ pass