forked from mirrors/bookwyrm
Merge remote-tracking branch 'origin/master' into settings-to-env
This commit is contained in:
commit
efc985d53c
4 changed files with 26 additions and 21 deletions
|
@ -38,7 +38,7 @@ def broadcast(sender, activity, recipients):
|
||||||
errors = []
|
errors = []
|
||||||
for recipient in recipients:
|
for recipient in recipients:
|
||||||
try:
|
try:
|
||||||
response = sign_and_send(sender, activity, recipient)
|
sign_and_send(sender, activity, recipient)
|
||||||
except requests.exceptions.HTTPError as e:
|
except requests.exceptions.HTTPError as e:
|
||||||
# TODO: maybe keep track of users who cause errors
|
# TODO: maybe keep track of users who cause errors
|
||||||
errors.append({
|
errors.append({
|
||||||
|
|
|
@ -36,17 +36,18 @@ def shared_inbox(request):
|
||||||
if activity['type'] == 'Add':
|
if activity['type'] == 'Add':
|
||||||
response = handle_incoming_shelve(activity)
|
response = handle_incoming_shelve(activity)
|
||||||
|
|
||||||
if activity['type'] == 'Follow':
|
elif activity['type'] == 'Follow':
|
||||||
response = handle_incoming_follow(activity)
|
response = handle_incoming_follow(activity)
|
||||||
|
|
||||||
if activity['type'] == 'Create':
|
elif activity['type'] == 'Create':
|
||||||
response = handle_incoming_create(activity)
|
response = handle_incoming_create(activity)
|
||||||
|
|
||||||
if activity['type'] == 'Accept':
|
elif activity['type'] == 'Accept':
|
||||||
response = handle_incoming_follow_accept(activity)
|
response = handle_incoming_follow_accept(activity)
|
||||||
|
|
||||||
return response
|
# TODO: Undo, Remove, etc
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def verify_signature(request):
|
def verify_signature(request):
|
||||||
|
@ -156,8 +157,6 @@ def get_status(request, username, status_id):
|
||||||
return JsonResponse(status.activity)
|
return JsonResponse(status.activity)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
def get_followers(request, username):
|
def get_followers(request, username):
|
||||||
''' return a list of followers for an actor '''
|
''' return a list of followers for an actor '''
|
||||||
|
@ -194,6 +193,7 @@ def format_follow_info(user, page, follow_queryset):
|
||||||
'first': '%s?page=1' % id_slug,
|
'first': '%s?page=1' % id_slug,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def get_follow_page(user_list, id_slug, page):
|
def get_follow_page(user_list, id_slug, page):
|
||||||
''' format a list of followers/following '''
|
''' format a list of followers/following '''
|
||||||
page = int(page)
|
page = int(page)
|
||||||
|
@ -243,15 +243,7 @@ def handle_incoming_shelve(activity):
|
||||||
|
|
||||||
|
|
||||||
def handle_incoming_follow(activity):
|
def handle_incoming_follow(activity):
|
||||||
'''
|
''' someone wants to follow a local user '''
|
||||||
{
|
|
||||||
"@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
|
# figure out who they want to follow
|
||||||
to_follow = models.User.objects.get(actor=activity['object'])
|
to_follow = models.User.objects.get(actor=activity['object'])
|
||||||
# figure out who they are
|
# figure out who they are
|
||||||
|
@ -267,7 +259,6 @@ def handle_incoming_follow(activity):
|
||||||
return HttpResponse()
|
return HttpResponse()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def handle_incoming_follow_accept(activity):
|
def handle_incoming_follow_accept(activity):
|
||||||
''' hurray, someone remote accepted a follow request '''
|
''' hurray, someone remote accepted a follow request '''
|
||||||
# figure out who they want to follow
|
# figure out who they want to follow
|
||||||
|
@ -320,7 +311,6 @@ def handle_incoming_create(activity):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def handle_incoming_accept(activity):
|
def handle_incoming_accept(activity):
|
||||||
''' someone is accepting a follow request '''
|
''' someone is accepting a follow request '''
|
||||||
# our local user
|
# our local user
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
''' handles all the activity coming out of the server '''
|
''' handles all the activity coming out of the server '''
|
||||||
|
from base64 import b64encode
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
from Crypto.Signature import pkcs1_15
|
||||||
|
from Crypto.Hash import SHA256
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from django.http import HttpResponseNotFound, JsonResponse
|
from django.http import HttpResponseNotFound, JsonResponse
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
@ -224,11 +228,12 @@ def handle_review(user, book, name, content, rating):
|
||||||
(DOMAIN, user.localname, review.id)
|
(DOMAIN, user.localname, review.id)
|
||||||
book_path = 'https://%s/book/%s' % (DOMAIN, review.book.openlibrary_key)
|
book_path = 'https://%s/book/%s' % (DOMAIN, review.book.openlibrary_key)
|
||||||
|
|
||||||
|
now = datetime.utcnow().isoformat() #TODO: should this be http_date?
|
||||||
review_activity = {
|
review_activity = {
|
||||||
'id': review_path,
|
'id': review_path,
|
||||||
'url': review_path,
|
'url': review_path,
|
||||||
'inReplyTo': book_path,
|
'inReplyTo': book_path,
|
||||||
'published': datetime.utcnow().isoformat(),
|
'published': now,
|
||||||
'attributedTo': user.actor,
|
'attributedTo': user.actor,
|
||||||
# TODO: again, assuming all posts are public
|
# TODO: again, assuming all posts are public
|
||||||
'to': ['https://www.w3.org/ns/activitystreams#Public'],
|
'to': ['https://www.w3.org/ns/activitystreams#Public'],
|
||||||
|
@ -255,19 +260,26 @@ def handle_review(user, book, name, content, rating):
|
||||||
review.activity = review_activity
|
review.activity = review_activity
|
||||||
review.save()
|
review.save()
|
||||||
|
|
||||||
|
signer = pkcs1_15.new(RSA.import_key(user.private_key))
|
||||||
|
signed_message = signer.sign(SHA256.new(content.encode('utf8')))
|
||||||
create_activity = {
|
create_activity = {
|
||||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
|
|
||||||
'id': '%s/activity' % review_path,
|
'id': '%s/activity' % review_path,
|
||||||
'type': 'Create',
|
'type': 'Create',
|
||||||
'actor': user.actor,
|
'actor': user.actor,
|
||||||
'published': datetime.utcnow().isoformat(),
|
'published': now,
|
||||||
|
|
||||||
'to': ['%s/followers' % user.actor],
|
'to': ['%s/followers' % user.actor],
|
||||||
'cc': ['https://www.w3.org/ns/activitystreams#Public'],
|
'cc': ['https://www.w3.org/ns/activitystreams#Public'],
|
||||||
|
|
||||||
'object': review_activity,
|
'object': review_activity,
|
||||||
# TODO: signature
|
'signature': {
|
||||||
|
'type': 'RsaSignature2017',
|
||||||
|
'creator': 'https://%s/user/%s#main-key' % (DOMAIN, user.localname),
|
||||||
|
'created': now,
|
||||||
|
'signatureValue': b64encode(signed_message).decode('utf8'),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recipients = get_recipients(user, 'public')
|
recipients = get_recipients(user, 'public')
|
||||||
|
|
|
@ -86,6 +86,9 @@
|
||||||
{% elif activity.activity_type == 'Follow' %}
|
{% elif activity.activity_type == 'Follow' %}
|
||||||
started following someone
|
started following someone
|
||||||
</h2>
|
</h2>
|
||||||
|
{% elif activity.activity_type == 'Note' %}
|
||||||
|
posted</h2>
|
||||||
|
{{ activity.content.object.content | safe }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{# generic handling for a misc activity, which perhaps should not be displayed at all #}
|
{# generic handling for a misc activity, which perhaps should not be displayed at all #}
|
||||||
did {{ activity.activity_type }}
|
did {{ activity.activity_type }}
|
||||||
|
|
Loading…
Reference in a new issue