Skip to content

Commit

Permalink
fix following issues (#32)
Browse files Browse the repository at this point in the history
* try digest

* fix following issues

* fix tests

* bump version
  • Loading branch information
autogestion committed May 1, 2019
1 parent 3c223e4 commit c93945c
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 45 deletions.
6 changes: 3 additions & 3 deletions config/base_sample_conf.cfg
@@ -1,10 +1,10 @@
DOMAIN = "example.com:8000"
METHOD = "http"
REGISTRATION = "open" #options are: open, invite, closed
METHOD = "https" # could be http for development
REGISTRATION = "open" # options are: open, invite, closed
INVITE_CODE = "xyz"
PAGINATION_LIMIT = 30

DEBUG = True
DEBUG_INBOX = False # when True, skips verifying of http signature
LOG_INCOMING_REQUEST = False
LOG_OUTGOING_REQUEST = False

Expand Down
6 changes: 3 additions & 3 deletions config/extensions_sample_conf.cfg
@@ -1,10 +1,10 @@
DOMAIN = "example.com:8000"
METHOD = "http"
REGISTRATION = "open" #options are: open, invite, closed
METHOD = "https" # could be http for development
REGISTRATION = "open" # options are: open, invite, closed
INVITE_CODE = "xyz"
PAGINATION_LIMIT = 30

DEBUG = True
DEBUG_INBOX = False # when True, skips verifying of http signature
LOG_INCOMING_REQUEST = False
LOG_OUTGOING_REQUEST = False

Expand Down
22 changes: 17 additions & 5 deletions pubgate.postman_collection.json
Expand Up @@ -481,7 +481,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n\t\"username\": \"{{user}}\", \n\t\"password\":\"{{pass}}\", \n\t\"invite\": \"{{invite}}\",\n\t\"profile\": {\n\t\t\"type\": \"Person\",\n\t\t\"preferredUsername\": \"{{user}}\",\n\t\t\"summary\": \"activitypub federator, written on Python/ Sanic <br> <a href='https://github.com/autogestion/pubgate' target='blank'> https://github.com/autogestion/pubgate</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/jpeg\",\n\t \"url\": \"https://avatars2.githubusercontent.com/u/1098257\"\n\t }\t\t\n\t}\n}"
"raw": "{\n\t\"username\": \"{{user}}\", \n\t\"password\":\"{{pass}}\", \n\t\"invite\": \"{{invite}}\",\n\t\"profile\": {\n\t\t\"type\": \"Person\",\n\t\t\"name\": \"{{user}}\",\n\t\t\"summary\": \"activitypub federator, written on Python/ Sanic <br> <a href='https://github.com/autogestion/pubgate' target='blank'> https://github.com/autogestion/pubgate</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/jpeg\",\n\t \"url\": \"https://avatars2.githubusercontent.com/u/1098257\"\n\t }\t\t\n\t}\n}"
},
"url": {
"raw": "{{host}}/user",
Expand All @@ -502,7 +502,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n\t\"username\": \"{{user}}\", \n\t\"password\":\"{{pass}}\", \n\t\"email\": \"bu\",\n\t\"profile\": {\n\t\t\"type\": \"Person\",\n\t\t\"preferredUsername\": \"{{user}}\",\n\t\t\"summary\": \"activitypub federator, written on Python/ Sanic <a href='https://github.com/autogestion/pubgate' target='blank'> https://github.com/autogestion/pubgate</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/jpeg\",\n\t \"url\": \"https://avatars2.githubusercontent.com/u/1098257\"\n\t }\t\t\n\t}\t\n}"
"raw": "{\n\t\"username\": \"{{user}}\", \n\t\"password\":\"{{pass}}\", \n\t\"email\": \"bu\",\n\t\"profile\": {\n\t\t\"type\": \"Person\",\n\t\t\"name\": \"{{user}}\",\n\t\t\"summary\": \"activitypub federator, written on Python/ Sanic <a href='https://github.com/autogestion/pubgate' target='blank'> https://github.com/autogestion/pubgate</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/jpeg\",\n\t \"url\": \"https://avatars2.githubusercontent.com/u/1098257\"\n\t }\t\t\n\t}\t\n}"
},
"url": {
"raw": "{{host}}/user",
Expand All @@ -528,7 +528,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n\t\"profile\": {\n\t\t\"type\": \"Person\",\n\t\t\"preferredUsername\": \"{{user}}\",\n\t\t\"summary\": \"Gotta go fast! <br> <a href='https://github.com/autogestion/pubgate' target='blank'> https://github.com/autogestion/pubgate</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/jpeg\",\n\t \"url\": \"https://avatars2.githubusercontent.com/u/1098257\"\n\t }\t\t\n\t}\t\n}"
"raw": "{\n\t\"profile\": {\n\t\t\"type\": \"Person\",\n\t\t\"name\": \"{{user}}\",\n\t\t\"summary\": \"Gotta go fast! <br> <a href='https://github.com/autogestion/pubgate' target='blank'> https://github.com/autogestion/pubgate</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/jpeg\",\n\t \"url\": \"https://avatars2.githubusercontent.com/u/1098257\"\n\t }\t\t\n\t}\t\n}"
},
"url": {
"raw": "{{host}}/{{user}}",
Expand Down Expand Up @@ -960,7 +960,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n\t\"username\": \"{{user}}\",\n\t\"password\": \"{{pass}}\",\n\t\"email\": \"\",\n\t\"invite\": \"{{invite}}\",\n\t\"profile\": {\n\t\t\"type\": \"Service\",\n\t\t\"preferredUsername\": \"Xatarsis\",\n\t\t\"summary\": \"Blog of co-living. News, reflections, review and our expressions <br> Broadcast from <a href='https://xatarsis.blogspot.com' target='_blank'> https://xatarsis.blogspot.com</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/png\",\n\t \"url\": \"https://scontent-mxp1-1.xx.fbcdn.net/v/t1.0-1/p320x320/30762577_367140987121136_8721509227190812672_n.png?_nc_cat=102&_nc_ht=scontent-mxp1-1.xx&oh=4451ff8948c6e5d7161291695139381f&oe=5C442443\"\n\t }\t\t\n\t},\n\t\"details\": {\n\t\t\"rssbot\": {\n\t\t\t\"feed\": \"https://xatarsis.blogspot.com/feeds/posts/default?alt=rss\",\n\t\t\t\"enable\": true,\n\t\t\t\"tags\": [\"tag1\", \"tag2\"],\n\t\t\t\"html\": true \n\t\t}\n\t}\n}"
"raw": "{\n\t\"username\": \"{{user}}\",\n\t\"password\": \"{{pass}}\",\n\t\"email\": \"\",\n\t\"invite\": \"{{invite}}\",\n\t\"profile\": {\n\t\t\"type\": \"Service\",\n\t\t\"name\": \"Xatarsis\",\n\t\t\"summary\": \"Blog of co-living. News, reflections, review and our expressions <br> Broadcast from <a href='https://xatarsis.blogspot.com' target='_blank'> https://xatarsis.blogspot.com</a>\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/png\",\n\t \"url\": \"https://scontent-mxp1-1.xx.fbcdn.net/v/t1.0-1/p320x320/30762577_367140987121136_8721509227190812672_n.png?_nc_cat=102&_nc_ht=scontent-mxp1-1.xx&oh=4451ff8948c6e5d7161291695139381f&oe=5C442443\"\n\t }\t\t\n\t},\n\t\"details\": {\n\t\t\"rssbot\": {\n\t\t\t\"feed\": \"https://xatarsis.blogspot.com/feeds/posts/default?alt=rss\",\n\t\t\t\"enable\": true,\n\t\t\t\"tags\": [\"tag1\", \"tag2\"],\n\t\t\t\"html\": true \n\t\t}\n\t}\n}"
},
"url": {
"raw": "{{host}}/user",
Expand Down Expand Up @@ -1007,7 +1007,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n\t\"username\": \"{{user}}\",\n\t\"password\": \"{{pass}}\",\n\t\"email\": \"\",\n\t\"invite\": \"{{invite}}\",\n\t\"profile\": {\n\t\t\"type\": \"Service\",\n\t\t\"preferredUsername\": \"TelePub\",\n\t\t\"summary\": \"Broadcast from <a href='https://t.me/telapub' target='_blank'>Telegram channel\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/png\",\n\t \"url\": \"https://cdn1.iconfinder.com/data/icons/blockchain-8/48/icon0008_decentralize-512.png\"\n\t }\t\t\n\t},\n\t\"details\": {\n\t\t\"tgbot\": {\n\t\t\t\"channels\": [\"telapub\"],\n\t\t\t\"enable\": true,\n\t\t\t\"tags\": [\"перемога\", \"покріщення\"]\n\t\t}\n\t}\n}"
"raw": "{\n\t\"username\": \"{{user}}\",\n\t\"password\": \"{{pass}}\",\n\t\"email\": \"\",\n\t\"invite\": \"{{invite}}\",\n\t\"profile\": {\n\t\t\"type\": \"Service\",\n\t\t\"name\": \"TelePub\",\n\t\t\"summary\": \"Broadcast from <a href='https://t.me/telapub' target='_blank'>Telegram channel\",\n\t \"icon\": {\n\t \"type\": \"Image\",\n\t \"mediaType\": \"image/png\",\n\t \"url\": \"https://cdn1.iconfinder.com/data/icons/blockchain-8/48/icon0008_decentralize-512.png\"\n\t }\t\t\n\t},\n\t\"details\": {\n\t\t\"tgbot\": {\n\t\t\t\"channels\": [\"telapub\"],\n\t\t\t\"enable\": true,\n\t\t\t\"tags\": [\"перемога\", \"покріщення\"]\n\t\t}\n\t}\n}"
},
"url": {
"raw": "{{host}}/user",
Expand Down Expand Up @@ -1047,6 +1047,18 @@
},
"response": []
},
{
"name": "-------------------------------------",
"request": {
"method": "OPTIONS",
"header": [],
"body": {},
"url": {
"raw": ""
}
},
"response": []
},
{
"name": "---- Inbox tests in debug mode------",
"request": {
Expand Down
2 changes: 1 addition & 1 deletion pubgate/__init__.py
@@ -1,6 +1,6 @@
import os

__version__ = "0.2.11"
__version__ = "0.2.12"


KEY_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "storage")
Expand Down
12 changes: 11 additions & 1 deletion pubgate/activity.py
@@ -1,9 +1,10 @@
import asyncio
from datetime import datetime
from sanic.exceptions import SanicException

from pubgate.utils import random_object_id
from pubgate.utils.networking import deliver
from pubgate.db import Outbox
from pubgate.db import Outbox, Inbox


class BaseActivity:
Expand Down Expand Up @@ -46,6 +47,15 @@ class Follow(Activity):
async def recipients(self):
return [self.render["object"]]

async def save(self, **kwargs):
filters = self.user.following_filter
filters["activity.object.object"] = self.render["object"]
followed = await Inbox.find_one(filters)
if followed:
raise SanicException('This user is already followed', status_code=409)

await Outbox.save(self, **kwargs)


class Create(Activity):

Expand Down
4 changes: 2 additions & 2 deletions pubgate/api/inbox.py
Expand Up @@ -27,10 +27,10 @@ async def inbox_post(request, user):
# TODO The receiver must verify the notification by fetching its source from the origin server.
verified = await verify_request(request)
if not verified:
if request.app.config.DEBUG:
if getattr(request.app.config, 'DEBUG_INBOX', False):
logger.info("signature incorrect")
else:
return response.json({"zrada": "signature incorrect"}, status=401)
return response.json({"error": "signature incorrect"}, status=401)

# TODO skip blocked
# if Outbox.find_one(
Expand Down
2 changes: 1 addition & 1 deletion pubgate/api/outbox.py
Expand Up @@ -36,7 +36,7 @@ async def outbox_post(request, user):

return response.json({'peremoga': 'yep'},
status=201,
headers={'Location': activity.render["id"]}
headers={'Location': activity.render.get("id", '')}
)


Expand Down
13 changes: 11 additions & 2 deletions pubgate/crypto/httpsig.py
Expand Up @@ -82,13 +82,22 @@ def __init__(self, key, headers) -> None:
self.key = key
self.headers = headers

def sign(self, url):
def sign(self, url, body):
headers = self.headers.copy()
spl_url = urlsplit(url)

bh = hashlib.new("sha256")
try:
body = body.encode("utf-8")
except AttributeError:
pass
bh.update(body)

headers.update({
'(request-target)': f'post {spl_url.path}',
"date": datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT"),
'host': spl_url.netloc
'host': spl_url.netloc,
'digest': "SHA-256=" + base64.b64encode(bh.digest()).decode("utf-8")
})

sigheaders = headers.keys()
Expand Down
1 change: 1 addition & 0 deletions pubgate/db/boxes.py
Expand Up @@ -31,6 +31,7 @@ async def unfollow(cls, activity):
filters = activity.user.following_filter
filters["activity.object.object"] = \
activity.render["object"]["object"]

accept = await Inbox.find_one(filters)
if accept:
activity.render["object"] = accept.activity["object"]
Expand Down
24 changes: 11 additions & 13 deletions pubgate/logging.py
Expand Up @@ -6,7 +6,7 @@
from sanic.handlers import ErrorHandler


from traceback import format_exc
from traceback import format_exc, print_exc
from sanic.exceptions import INTERNAL_SERVER_ERROR_HTML, SanicException
from sanic.response import text, html

Expand Down Expand Up @@ -41,27 +41,25 @@ def log_response(self, response):
print(self.request.headers)
pprint(self.request.json)
# print(self.request.body)
logger.info("------")
# logger.info("------")


class PGErrorHandler(ErrorHandler):

def default(self, request, exception):
if not getattr(exception, 'status_code', None) == 404:
self.log(format_exc())

if issubclass(type(exception), SanicException):
return text(
'Error: {}'.format(exception),
{'error': '{}'.format(exception)},
status=getattr(exception, 'status_code', 500),
headers=getattr(exception, 'headers', dict())
)
elif self.debug:
html_output = self._render_traceback_html(exception, request)

response_message = ('Exception occurred while handling uri: '
'"%s"\n%s')
logger.error(response_message, request.url, format_exc())
return html(html_output, status=500)
# elif self.debug:
# html_output = self._render_traceback_html(exception, request)
#
# response_message = ('Exception occurred while handling uri: '
# '"%s"\n%s')
# logger.error(response_message, request.url, format_exc())
# return html(html_output, status=500)
else:
print_exc()
return html(INTERNAL_SERVER_ERROR_HTML, status=500)
2 changes: 1 addition & 1 deletion pubgate/renders.py
Expand Up @@ -13,13 +13,13 @@ def render(self):
actor = self.user.profile
actor.update({
"@context": context,
"preferredUsername": self.user.name,
"id": self.user.uri,
"following": self.user.following,
"followers": self.user.followers,
"inbox": self.user.inbox,
"outbox": self.user.outbox,
"liked": self.user.liked,
"name": "",
# "url": f"{base_url}/@{user_id}",
"manuallyApprovesFollowers": False,
"publicKey": self.user.key.to_dict(),
Expand Down
3 changes: 1 addition & 2 deletions pubgate/utils/networking.py
Expand Up @@ -46,9 +46,8 @@ async def deliver_task(recipient, http_sig, activity, debug=False):

profile = await fetch(recipient)
url = profile["inbox"]
headers = http_sig.sign(url)

body = json.dumps(activity)
headers = http_sig.sign(url, body)

async with aiohttp.ClientSession() as session:
async with session.post(url,
Expand Down
15 changes: 4 additions & 11 deletions tests/test_data/__init__.py
Expand Up @@ -9,7 +9,7 @@ def user_data():
"email": "bu",
"profile": {
"type": "Person",
"preferredUsername": "{{user}}",
"name": "Test User",
"summary": "activitypub federator, written on Python/ Sanic <a href='https://github.com/autogestion/pubgate' target='blank'> https://github.com/autogestion/pubgate</a>",
"icon": {
"type": "Image",
Expand All @@ -24,24 +24,17 @@ def user_data():
def user_profile(app, user, user_data):
return {
"type": user_data["profile"]["type"],
"preferredUsername": user_data["profile"]["preferredUsername"],
"preferredUsername": user_data['username'],
"summary": user_data["profile"]["summary"],
"icon": user_data["profile"]["icon"],
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"Hashtag": "as:Hashtag",
"sensitive": "as:sensitive"
}
],
"name": user_data["profile"]['name'],
"@context": "https://www.w3.org/ns/activitystreams",
"id": f"{app.base_url}/{user_data['username']}",
"following": f"{app.base_url}/{user_data['username']}/following",
"followers": f"{app.base_url}/{user_data['username']}/followers",
"inbox": f"{app.base_url}/{user_data['username']}/inbox",
"outbox": f"{app.base_url}/{user_data['username']}/outbox",
"liked": f"{app.base_url}/{user_data['username']}/liked",
"name": "",
"manuallyApprovesFollowers": False,
"publicKey": {
"id": f"{app.base_url}/{user_data['username']}#main-key",
Expand Down

0 comments on commit c93945c

Please sign in to comment.