Remove SignedMixin in favour of base entity signing by default

While the signing methods are empty at the moment, preparation for ActivityPub, where every object would need to be signed separately (as signature is not in payload header but in the object itself), get rid of separate SignedMixin and just have signature and sign() on the base entity. Diaspora entities provide the necessary methods for signing and validation for DiasporaComment currently.
merge-requests/130/head
Jason Robinson 2017-05-01 10:53:36 +03:00
rodzic ce9c3c7ba4
commit 9e9ded2c3d
5 zmienionych plików z 22 dodań i 39 usunięć

Wyświetl plik

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
import warnings
@ -16,6 +15,8 @@ class BaseEntity(object):
_allowed_children = ()
_source_protocol = ""
_source_object = None
_sender_key = ""
signature = ""
def __init__(self, *args, **kwargs):
self._required = []
@ -89,6 +90,10 @@ class BaseEntity(object):
"""Override in subclasses where necessary"""
pass
def sign(self, private_key):
"""Implement in subclasses."""
pass
class GUIDMixin(BaseEntity):
guid = ""
@ -167,23 +172,6 @@ class OptionalRawContentMixin(RawContentMixin):
self._required.remove("raw_content")
class SignedMixin(BaseEntity):
"""Adds a signature string or object (depending on protocol).
This will be needed to for example when relaying content.
"""
_sender_key = ""
signature = ""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._required += ["signature"]
def sign(self, private_key):
"""Implement in subclasses."""
pass
class Image(GUIDMixin, HandleMixin, PublicMixin, OptionalRawContentMixin, CreatedAtMixin, BaseEntity):
"""Reflects a single image, possibly linked to another object."""
remote_path = ""
@ -225,14 +213,14 @@ class ParticipationMixin(TargetGUIDMixin):
))
class Comment(RawContentMixin, GUIDMixin, ParticipationMixin, CreatedAtMixin, HandleMixin, SignedMixin):
class Comment(RawContentMixin, GUIDMixin, ParticipationMixin, CreatedAtMixin, HandleMixin):
"""Represents a comment, linked to another object."""
participation = "comment"
_allowed_children = (Image,)
class Reaction(GUIDMixin, ParticipationMixin, CreatedAtMixin, HandleMixin, SignedMixin):
class Reaction(GUIDMixin, ParticipationMixin, CreatedAtMixin, HandleMixin):
"""Represents a reaction to another object, for example a like."""
participation = "reaction"
reaction = ""

Wyświetl plik

@ -1,6 +1,6 @@
from lxml import etree
from federation.entities.base import Comment, Post, Reaction, Relationship, Profile, Retraction, BaseEntity, SignedMixin
from federation.entities.base import Comment, Post, Reaction, Relationship, Profile, Retraction, BaseEntity
from federation.entities.diaspora.utils import format_dt, struct_to_xml, get_base_attributes
from federation.exceptions import SignatureVerificationError
from federation.protocols.diaspora.signatures import verify_relayable_signature, create_relayable_signature
@ -31,7 +31,11 @@ class DiasporaEntityMixin(BaseEntity):
return attributes
class DiasporaRelayableMixin(SignedMixin, DiasporaEntityMixin):
class DiasporaRelayableMixin(DiasporaEntityMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._required += ["signature"]
def _validate_signatures(self):
super()._validate_signatures()
if not self._sender_key:

Wyświetl plik

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
import logging
from datetime import datetime
from lxml import etree
from federation.entities.base import Image, Relationship, Post, Reaction, Comment, Profile, Retraction, SignedMixin
from federation.entities.base import Image, Relationship, Post, Reaction, Comment, Profile, Retraction
from federation.entities.diaspora.entities import (
DiasporaPost, DiasporaComment, DiasporaLike, DiasporaRequest, DiasporaProfile, DiasporaRetraction)
DiasporaPost, DiasporaComment, DiasporaLike, DiasporaRequest, DiasporaProfile, DiasporaRetraction,
DiasporaRelayableMixin)
from federation.utils.diaspora import retrieve_and_parse_profile
logger = logging.getLogger("federation")
@ -66,8 +66,8 @@ def element_to_objects(tree, sender_key_fetcher=None):
entity._source_protocol = "diaspora"
# Save element object to entity for possible later use
entity._source_object = element
# If signable, fetch sender key
if issubclass(cls, SignedMixin):
# If relayable, fetch sender key for validation
if issubclass(cls, DiasporaRelayableMixin):
if sender_key_fetcher:
entity._sender_key = sender_key_fetcher(entity.handle)
else:
@ -204,6 +204,6 @@ def get_outbound_entity(entity, private_key):
outbound = DiasporaRetraction.from_base(entity)
if not outbound:
raise ValueError("Don't know how to convert this base entity to Diaspora protocol entities.")
if issubclass(cls, SignedMixin):
if issubclass(cls, DiasporaRelayableMixin):
outbound.sign(private_key)
return outbound

Wyświetl plik

@ -13,7 +13,8 @@ class TestGetBaseAttributes():
entity = Post()
attrs = get_base_attributes(entity).keys()
assert set(attrs) == {
'created_at', 'guid', 'handle', 'location', 'photos', 'provider_display_name', 'public', 'raw_content'
"created_at", "guid", "handle", "location", "photos", "provider_display_name", "public", "raw_content",
"signature",
}

Wyświetl plik

@ -4,7 +4,6 @@ import pytest
from federation.entities.base import (
BaseEntity, Relationship, Profile, RawContentMixin, GUIDMixin, HandleMixin, PublicMixin, Image, Retraction,
SignedMixin,
)
from federation.tests.factories.entities import TaggedPostFactory, PostFactory
@ -70,15 +69,6 @@ class TestPublicMixinValidate():
public.validate()
class TestSignedMixinValidate():
def test_required_validates(self):
signed = SignedMixin()
with pytest.raises(ValueError):
signed.validate()
signed.signature = "foobar"
signed.validate()
class TestEntityRequiredAttributes():
def test_entity_checks_for_required_attributes(self):
entity = BaseEntity()