kopia lustrzana https://github.com/tsileo/little-boxes
Cleanup
rodzic
587e580755
commit
bcf4d14326
|
@ -5,7 +5,7 @@ install:
|
|||
- pip install -r requirements.txt
|
||||
- pip install -r dev-requirements.txt
|
||||
script:
|
||||
# - mypy --ignore-missing-imports little_boxes
|
||||
- mypy --ignore-missing-imports little_boxes
|
||||
- flake8 little_boxes
|
||||
- black --check .
|
||||
- python -m pytest -vv --cov=little_boxes
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def strtobool(s: str) -> bool:
|
||||
def strtobool(s: str) -> bool: # pragma: no cover
|
||||
if s in ["y", "yes", "true", "on", "1"]:
|
||||
return True
|
||||
if s in ["n", "no", "false", "off", "0"]:
|
||||
|
|
|
@ -367,7 +367,7 @@ class BaseActivity(object, metaclass=_ActivityMeta):
|
|||
actor_id = self._actor_id(actor)
|
||||
return Person(**BACKEND.fetch_iri(actor_id))
|
||||
|
||||
def _pre_post_to_outbox(self) -> None:
|
||||
def _pre_post_to_outbox(self, as_actor: "Person") -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def _post_to_outbox(
|
||||
|
@ -407,7 +407,7 @@ class BaseActivity(object, metaclass=_ActivityMeta):
|
|||
)
|
||||
return
|
||||
|
||||
if BACKEND.inbox_get_by_iri(as_actor, self.id):
|
||||
if BACKEND.inbox_check_duplicate(as_actor, self.id):
|
||||
# The activity is already in the inbox
|
||||
logger.info(f"received duplicate activity {self}, dropping it")
|
||||
return
|
||||
|
@ -438,7 +438,7 @@ class BaseActivity(object, metaclass=_ActivityMeta):
|
|||
self.outbox_set_id(BACKEND.activity_url(obj_id), obj_id)
|
||||
|
||||
try:
|
||||
self._pre_post_to_outbox()
|
||||
self._pre_post_to_outbox(self.get_actor())
|
||||
logger.debug(f"called pre post to outbox hook")
|
||||
except NotImplementedError:
|
||||
logger.debug("pre post to outbox hook not implemented")
|
||||
|
@ -671,12 +671,12 @@ class Undo(BaseActivity):
|
|||
except NotImplementedError:
|
||||
pass
|
||||
|
||||
def _pre_post_to_outbox(self) -> None:
|
||||
def _pre_post_to_outbox(self, as_actor: "Person") -> None:
|
||||
"""Ensures an Undo activity references an activity owned by the instance."""
|
||||
if BACKEND is None:
|
||||
raise UninitializedBackendError
|
||||
|
||||
if not BACKEND.is_from_outbox(self):
|
||||
if not BACKEND.is_from_outbox(as_actor, self):
|
||||
raise NotFromOutboxError(f"object {self!r} is not owned by this instance")
|
||||
|
||||
def _post_to_outbox(
|
||||
|
@ -774,6 +774,9 @@ class Announce(BaseActivity):
|
|||
)
|
||||
return
|
||||
|
||||
if BACKEND is None:
|
||||
raise UninitializedBackendError
|
||||
|
||||
BACKEND.inbox_announce(as_actor, self)
|
||||
|
||||
def _undo_inbox(self, as_actor: "Person") -> None:
|
||||
|
@ -789,6 +792,9 @@ class Announce(BaseActivity):
|
|||
activity: ObjectType,
|
||||
recipients: List[str],
|
||||
) -> None:
|
||||
if BACKEND is None:
|
||||
raise UninitializedBackendError
|
||||
|
||||
BACKEND.outbox_announce(as_actor, self)
|
||||
|
||||
def _undo_outbox(self, as_actor: "Person") -> None:
|
||||
|
@ -834,14 +840,14 @@ class Delete(BaseActivity):
|
|||
BACKEND.inbox_delete(as_actor, self)
|
||||
# FIXME(tsileo): handle the delete_threads here?
|
||||
|
||||
def _pre_post_to_outbox(self) -> None:
|
||||
def _pre_post_to_outbox(self, as_actor: "Person") -> None:
|
||||
"""Ensures the Delete activity references a activity from the outbox (i.e. owned by the instance)."""
|
||||
if BACKEND is None:
|
||||
raise UninitializedBackendError
|
||||
|
||||
obj = self._get_actual_object()
|
||||
|
||||
if not BACKEND.is_from_outbox(self):
|
||||
if not BACKEND.is_from_outbox(as_actor, self):
|
||||
raise NotFromOutboxError(
|
||||
f'object {obj["id"]} is not owned by this instance'
|
||||
)
|
||||
|
@ -878,11 +884,11 @@ class Update(BaseActivity):
|
|||
|
||||
BACKEND.inbox_update(as_actor, self)
|
||||
|
||||
def _pre_post_to_outbox(self) -> None:
|
||||
def _pre_post_to_outbox(self, as_actor: "Person") -> None:
|
||||
if BACKEND is None:
|
||||
raise UninitializedBackendError
|
||||
|
||||
if not BACKEND.is_from_outbox(self):
|
||||
if not BACKEND.is_from_outbox(as_actor, self):
|
||||
raise NotFromOutboxError(f"object {self!r} is not owned by this instance")
|
||||
|
||||
def _post_to_outbox(
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import abc
|
||||
import typing
|
||||
import os
|
||||
import binascii
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -13,6 +15,10 @@ class Backend(abc.ABC):
|
|||
def user_agent(self) -> str:
|
||||
return f"Little Boxes {__version__} (+http://github.com/tsileo/little-boxes)"
|
||||
|
||||
def random_object_id(self) -> str:
|
||||
"""Generates a random object ID."""
|
||||
return binascii.hexlify(os.urandom(8)).decode("utf-8")
|
||||
|
||||
def fetch_json(self, url: str, **kwargs):
|
||||
resp = requests.get(
|
||||
url,
|
||||
|
@ -21,6 +27,15 @@ class Backend(abc.ABC):
|
|||
)
|
||||
return resp
|
||||
|
||||
def is_from_outbox(self, as_actor: "ap.Person", activity: "ap.BaseActivity") -> bool:
|
||||
return activity.get_actor().id == as_actor.id
|
||||
|
||||
@abc.abstractmethod
|
||||
def post_to_remote_inbox(
|
||||
self, as_actor: "ap.Person", payload_encoded: str, recp: str
|
||||
) -> None:
|
||||
pass # pragma: no cover
|
||||
|
||||
@abc.abstractmethod
|
||||
def base_url(self) -> str:
|
||||
pass # pragma: no cover
|
||||
|
@ -29,6 +44,10 @@ class Backend(abc.ABC):
|
|||
def fetch_iri(self, iri: str) -> "ap.ObjectType":
|
||||
pass # pragma: no cover
|
||||
|
||||
@abc.abstractmethod
|
||||
def inbox_check_duplicate(self, as_actor: "ap.Person", iri: str) -> bool:
|
||||
pass # pragma: no cover
|
||||
|
||||
@abc.abstractmethod
|
||||
def activity_url(self, obj_id: str) -> str:
|
||||
pass # pragma: no cover
|
||||
|
|
|
@ -39,6 +39,9 @@ def mentionify(content: str) -> Tuple[str, List[Dict[str, str]]]:
|
|||
for mention in re.findall(MENTION_REGEX, content):
|
||||
_, username, domain = mention.split("@")
|
||||
actor_url = get_actor_url(mention)
|
||||
if not actor_url:
|
||||
# FIXME(tsileo): raise an error?
|
||||
continue
|
||||
p = get_backend().fetch_iri(actor_url)
|
||||
tags.append(dict(type="Mention", href=p["id"], name=mention))
|
||||
link = f'<span class="h-card"><a href="{p["url"]}" class="u-url mention">@<span>{username}</span></a></span>'
|
||||
|
|
|
@ -55,7 +55,7 @@ def _verify_h(signed_string, signature, pubkey):
|
|||
|
||||
def _body_digest(body: str) -> str:
|
||||
h = hashlib.new("sha256")
|
||||
h.update(body)
|
||||
h.update(body) # type: ignore
|
||||
return "SHA-256=" + base64.b64encode(h.digest()).decode("utf-8")
|
||||
|
||||
|
||||
|
|
|
@ -67,10 +67,6 @@ class InMemBackend(Backend):
|
|||
|
||||
return calls
|
||||
|
||||
def random_object_id(self) -> str:
|
||||
"""Generates a random object ID."""
|
||||
return binascii.hexlify(os.urandom(8)).decode("utf-8")
|
||||
|
||||
def setup_actor(self, name, pusername):
|
||||
"""Create a new actor in this backend."""
|
||||
p = ap.Person(
|
||||
|
@ -126,7 +122,7 @@ class InMemBackend(Backend):
|
|||
return True
|
||||
return False
|
||||
|
||||
def inbox_get_by_iri(
|
||||
def inbox_check_duplicate(
|
||||
self, as_actor: ap.Person, iri: str
|
||||
) -> Optional[ap.BaseActivity]:
|
||||
for activity in self.DB[as_actor.id]["inbox"]:
|
||||
|
@ -194,10 +190,6 @@ class InMemBackend(Backend):
|
|||
as_actor = ap.parse_activity(self.fetch_iri(recp.replace("/inbox", "")))
|
||||
act.process_from_inbox(as_actor)
|
||||
|
||||
def is_from_outbox(self, activity: ap.BaseActivity) -> bool:
|
||||
# return as_actor.id == activity.get_actor().id
|
||||
return True # FIXME(tsileo): implement this
|
||||
|
||||
@track_call
|
||||
def inbox_like(self, as_actor: ap.Person, activity: ap.Like) -> None:
|
||||
pass
|
||||
|
|
Ładowanie…
Reference in New Issue