Skip to content

Commit

Permalink
Rewrite FromPrior with validation using 'attrs' validators
Browse files Browse the repository at this point in the history
Signed-off-by: Sacha Kozma <[email protected]>
  • Loading branch information
yvgny committed Mar 6, 2023
1 parent e4393fe commit d7b08d1
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 65 deletions.
4 changes: 2 additions & 2 deletions didcomm/core/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ def _f(instance, attribute, value):


# TODO TEST
def validator__did(instance, attribute, value) -> None:
validator__check_f(is_did, "is not a did")(instance, attribute, value)
def validator__did() -> Callable:
return validator__check_f(is_did, "is not a did")


# TODO TEST
Expand Down
62 changes: 33 additions & 29 deletions didcomm/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
)
from didcomm.core.converters import converter__id, converter__didcomm_id
from didcomm.core.serialization import json_str_to_dict, json_bytes_to_dict
from didcomm.core.utils import dataclass_to_dict, attrs_to_dict, is_did
from didcomm.core.utils import dataclass_to_dict, attrs_to_dict
from didcomm.core.validators import (
validator__instance_of,
validator__deep_iterable,
validator__optional,
validator__deep_mapping,
validator__not_in_,
validator__and_,
validator__did,
)
from didcomm.errors import (
MalformedMessageError,
Expand Down Expand Up @@ -229,25 +230,46 @@ def from_dict(d: dict) -> Attachment:
return msg


@dataclass(frozen=True)
@dataclass
@attrs.define(auto_attribs=True)
class FromPrior:
iss: DID
sub: DID
aud: Optional[str] = None
exp: Optional[int] = None
nbf: Optional[int] = None
iat: Optional[int] = None
jti: Optional[str] = None
iss: DID = attr.ib(
validator=validator__and_(validator__instance_of(DID), validator__did()),
)
sub: DID = attr.ib(
validator=validator__and_(validator__instance_of(DID), validator__did()),
)
aud: Optional[str] = attr.ib(
validator=validator__optional(validator__instance_of(str)), default=None
)

exp: Optional[int] = attr.ib(
validator=validator__optional(validator__instance_of(int)), default=None
)

nbf: Optional[int] = attr.ib(
validator=validator__optional(validator__instance_of(int)), default=None
)

iat: Optional[int] = attr.ib(
validator=validator__optional(validator__instance_of(int)), default=None
)

jti: Optional[str] = attr.ib(
validator=validator__optional(validator__instance_of(str)), default=None
)

def as_dict(self) -> dict:
self._validate()
try:
attr.validate(self)
except Exception as exc:
raise DIDCommValueError(str(exc)) from exc
return dataclass_to_dict(self)

@staticmethod
def from_dict(d: dict) -> FromPrior:
try:
msg = FromPrior(**d)
msg._validate()
except Exception:
raise MalformedMessageError(
MalformedMessageCode.INVALID_PLAINTEXT,
Expand All @@ -256,24 +278,6 @@ def from_dict(d: dict) -> FromPrior:

return msg

def _validate(self):
if (
not is_did(self.iss)
or not is_did(self.sub)
or not isinstance(self.sub, str)
or self.aud is not None
and not isinstance(self.aud, str)
or self.exp is not None
and not isinstance(self.exp, int)
or self.nbf is not None
and not isinstance(self.nbf, int)
or self.iat is not None
and not isinstance(self.iat, int)
or self.jti is not None
and not isinstance(self.jti, str)
):
raise DIDCommValueError(f"FromPrior structure is invalid: {self}")


@attr.s(auto_attribs=True)
class GenericMessage(Generic[T]):
Expand Down
1 change: 0 additions & 1 deletion didcomm/protocols/routing/forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ async def wrap_in_forward(
# wrap forward msgs in reversed order so the message to final
# recipient 'to' will be the innermost one
for _to, _next in zip(routing_keys[::-1], (routing_keys[1:] + [to])[::-1]):
print(packed_msg, type(packed_msg))
fwd_attach = Attachment(data=AttachmentDataJson(packed_msg))

fwd_msg = ForwardMessage(
Expand Down
32 changes: 0 additions & 32 deletions tests/test_vectors/didcomm_messages/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,36 +94,6 @@
)


TEST_MESSAGE_INVALID_FROM_PRIOR_ISS = Message(
id="1234567890",
type="https://example.com/protocols/lets_do_lunch/1.0/proposal",
frm=ALICE_DID,
to=[BOB_DID],
created_time=1516269022,
expires_time=1516385931,
from_prior=FromPrior(
iss="invalid",
sub=ALICE_DID,
),
body={"messagespecificattribute": "and its value"},
)


TEST_MESSAGE_INVALID_FROM_PRIOR_SUB = Message(
id="1234567890",
type="https://example.com/protocols/lets_do_lunch/1.0/proposal",
frm=ALICE_DID,
to=[BOB_DID],
created_time=1516269022,
expires_time=1516385931,
from_prior=FromPrior(
iss=CHARLIE_DID,
sub="invalid",
),
body={"messagespecificattribute": "and its value"},
)


TEST_MESSAGE_INVALID_FROM_PRIOR_EQUAL_ISS_AND_SUB = Message(
id="1234567890",
type="https://example.com/protocols/lets_do_lunch/1.0/proposal",
Expand Down Expand Up @@ -155,8 +125,6 @@


INVALID_FROM_PRIOR_MESSAGES = [
TEST_MESSAGE_INVALID_FROM_PRIOR_ISS,
TEST_MESSAGE_INVALID_FROM_PRIOR_SUB,
TEST_MESSAGE_INVALID_FROM_PRIOR_EQUAL_ISS_AND_SUB,
TEST_MESSAGE_MISMATCHED_FROM_PRIOR_SUB,
]
Expand Down
16 changes: 15 additions & 1 deletion tests/unit/pack_common/test_message_negative.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
AttachmentDataLinks,
AttachmentDataBase64,
AttachmentDataJson,
FromPrior,
)
from didcomm.pack_encrypted import pack_encrypted
from didcomm.pack_plaintext import pack_plaintext
from didcomm.pack_signed import pack_signed
from tests.test_vectors.common import ALICE_DID, BOB_DID
from tests.test_vectors.common import ALICE_DID, BOB_DID, CHARLIE_DID
from tests.test_vectors.didcomm_messages.messages import (
TEST_MESSAGE,
TEST_ATTACHMENT,
Expand Down Expand Up @@ -186,6 +187,19 @@ async def test_message_invalid_from_prior_fields(
await check_invalid_pack_msg(msg, resolvers_config_alice)


@pytest.mark.asyncio
@pytest.mark.parametrize(
"iss, sub",
[
("invalid", ALICE_DID),
(CHARLIE_DID, "invalid"),
],
)
async def test_message_invalid_from_prior_construction(iss, sub):
with pytest.raises(DIDCommValueError):
FromPrior(iss, sub)


@pytest.mark.asyncio
@pytest.mark.parametrize(
"links, hashh, jws",
Expand Down

0 comments on commit d7b08d1

Please sign in to comment.