Accept follow requests

This commit is contained in:
Mouse Reeve 2020-01-26 18:49:57 -08:00
parent 6b85d8838f
commit 19f6ebb9a7
6 changed files with 70 additions and 17 deletions

View file

@ -1,4 +1,7 @@
''' generates activitypub formatted objects '''
from uuid import uuid4
from fedireads.settings import DOMAIN
def shelve_action(user, book, shelf):
''' a user puts a book on a shelf.
@ -27,3 +30,15 @@ def shelve_action(user, book, shelf):
}
}
def accept_follow(activity, user):
''' say YES! to a user '''
uuid = uuid4()
return {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': 'https://%s/%s' % (DOMAIN, uuid),
'type': 'Accept',
'actor': user.actor['id'],
'object': activity,
}

View file

@ -10,6 +10,8 @@ from django.views.decorators.csrf import csrf_exempt
from fedireads.settings import DOMAIN
from fedireads import models
from fedireads import openlibrary
import fedireads.activitypub_templates as templates
import json
import requests
def webfinger(request):
@ -52,13 +54,18 @@ def inbox(request, username):
# return a collection of something?
pass
activity = request.POST.dict()
activity = json.loads(request.body)
if activity['type'] == 'Add':
handle_add(activity)
if activity['type'] == 'Follow':
response = handle_follow(activity)
return JsonResponse(response)
return HttpResponse()
def handle_add(activity):
''' adding a book to a shelf '''
book_id = activity['object']['url']
book = openlibrary.get_or_create_book(book_id)
user_ap_id = activity['actor'].replace('https//:', '')
@ -70,6 +77,31 @@ def handle_add(activity):
added_by=user,
).save()
def handle_follow(activity):
'''
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://friend.camp/768222ce-a1c7-479c-a544-c93b8b67fb54",
"type": "Follow",
"actor": "https://friend.camp/users/tripofmice",
"object": "https://ff2cb3e9.ngrok.io/api/u/mouse"
}
'''
# figure out who they want to follow
following = activity['object'].replace('https://%s/api/u/' % DOMAIN, '')
following = models.User.objects.get(username=following)
# figure out who they are
ap_id = activity['actor']
try:
user = models.User.objects.get(activitypub_id=ap_id)
except models.User.DoesNotExist:
user = models.User(activitypub_id=ap_id, local=False).save()
following.followers.add(user)
# accept the request
return templates.accept_follow(activity, following)
@csrf_exempt
def outbox(request, username):
user = models.User.objects.get(username=username)
@ -106,19 +138,16 @@ date: %s''' % (inbox_fragment, DOMAIN, now)
signature += 'signature="%s"' % b64encode(signed_message)
response = requests.post(
recipient,
data=action,
body=action,
headers={
'Date': now,
'Signature': signature,
'Host': DOMAIN,
'Content-Type': 'application/json',
},
)
if not response.ok:
return response.raise_for_status()
def handle_follow(data):
pass
def get_or_create_remote_user(activity):
pass

View file

@ -1,4 +1,4 @@
# Generated by Django 2.0.13 on 2020-01-27 01:47
# Generated by Django 2.0.13 on 2020-01-27 02:41
from django.conf import settings
import django.contrib.auth.models
@ -34,9 +34,9 @@ class Migration(migrations.Migration):
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('activitypub_id', models.CharField(max_length=255)),
('private_key', models.TextField(blank=True, null=True)),
('public_key', models.TextField()),
('public_key', models.TextField(blank=True, null=True)),
('api_key', models.CharField(blank=True, max_length=255, null=True)),
('actor', django.contrib.postgres.fields.jsonb.JSONField()),
('actor', django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True)),
('local', models.BooleanField(default=True)),
('created_date', models.DateTimeField(auto_now_add=True)),
('updated_date', models.DateTimeField(auto_now=True)),

View file

@ -12,9 +12,9 @@ class User(AbstractUser):
''' a user who wants to read books '''
activitypub_id = models.CharField(max_length=255)
private_key = models.TextField(blank=True, null=True)
public_key = models.TextField()
public_key = models.TextField(blank=True, null=True)
api_key = models.CharField(max_length=255, blank=True, null=True)
actor = JSONField()
actor = JSONField(blank=True, null=True)
local = models.BooleanField(default=True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)

View file

@ -3,7 +3,7 @@
<div id="main">
<div class="user-profile">
<img class="user-pic" src="/static/images/profile.jpg">
<h2>{{ user.username }}</h2>
<h1>{{ user.username }}</h1>
<p>Since {{ user.created_date }}</p>
{% if not is_self %}
{% if not following %}
@ -19,11 +19,22 @@
{% endif %}
{% endif %}
</div>
{% for book in books.all %}
<div class="book">
{{ book.data.title }} by {{ book.authors.first.data.name }}
<div>
<h2>Books</h2>
{% for book in books.all %}
<div class="book">
{{ book.data.title }} by {{ book.authors.first.data.name }}
</div>
{% endfor %}
</div>
<div>
<h2>Followers</h2>
{% for follower in user.followers.all %}
{{ follower.activitypub_id }}
{% endfor %}
</div>
{% endfor %}
</div>
{% endblock %}

View file

@ -57,12 +57,10 @@ def user_profile(request, username):
''' profile page for a user '''
user = models.User.objects.get(username=username)
books = models.Book.objects.filter(shelves__user=user)
following = user.followers.filter(id=request.user.id).count() > 0
data = {
'user': user,
'books': books,
'is_self': request.user.id == user.id,
'following': following,
}
return TemplateResponse(request, 'user.html', data)