Skip to content

Commit

Permalink
Add metadata serialization sub-package
Browse files Browse the repository at this point in the history
Add sub-package with 3 abstract base classes to:
- serialize Metadata objects to bytes (transport)
- deserialize Metadata objects from bytes (transport)
- serialize Signed objects to bytes (signatures)

pylint notes:
- configure tox to use api/pylintrc
- configure api/pylintrc to allow classes without public methods
  (default was 2)

Design considerations
---------------------
- Why not implement de/serialization on metadata classes?
  -> See ADR0006.

- Why use separate classes for serialization and deserialization?
  -> Some users might only need either one, e.g. client only needs
     Deserializer. Maybe there are use cases where different
     implementations are used to serialize and deserialize.

- Why use separate classes for Metadata- and Signed-Serialization?
  -> They require different concrete types, i.e. Metadata and
     Signed as parameters, and using these specific types seems to
     make the interface stronger.

- Why are de/serialize methods not class/staticmethods?
  -> In reality we only use classes to namespace and define a
     type annotated interface, thus it would be enough to make the
     methods classmethods. However, to keep the de/serialize
     interface minimal, we move any custom format configuration to
     the constructor. (See e.g. "compact" for JSONSerializer in
     subsequent commit).

Naming considerations
---------------------
- Why de/serialize?
  -> Implies byte stream as input or output to the function, which
     is what our interface needs.
- Why not marshaling?
  -> Synonym for serialize but implies transport, would be okay.
- Why not encoding?
  -> Too abstract and too many connotations (character, a/v).
- Why not parse?
  -> Too abstract and no good opposite terms (unparse, write,
     dump?)

Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
  • Loading branch information
lukpueh committed Feb 10, 2021
1 parent 4ae675c commit 79ce034
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
5 changes: 4 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ commands =

[testenv:lint]
commands =
pylint {toxinidir}/tuf --ignore={toxinidir}/tuf/api
# Use different pylint configs for legacy and new (tuf/api) code
# NOTE: Contrary to what the pylint docs suggest, ignoring full paths does
# work, unfortunately each subdirectory has to be ignored explicitly.
pylint {toxinidir}/tuf --ignore={toxinidir}/tuf/api,{toxinidir}/tuf/api/serialization
pylint {toxinidir}/tuf/api --rcfile={toxinidir}/tuf/api/pylintrc
bandit -r {toxinidir}/tuf
3 changes: 3 additions & 0 deletions tuf/api/pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ disable=fixme
[FORMAT]
indent-string=" "
max-line-length=79

[DESIGN]
min-public-methods=0
43 changes: 43 additions & 0 deletions tuf/api/serialization/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""TUF role metadata de/serialization.
This sub-package provides abstract base classes and concrete implementations to
serialize and deserialize TUF role metadata and metadata parts.
Any custom de/serialization implementations should inherit from the abstract
base classes defined in this __init__.py module.
- Metadata de/serializers are used to convert to and from wireline formats.
- Signed serializers are used to canonicalize data for cryptographic signatures
generation and verification.
"""
import abc

class MetadataDeserializer():
"""Abstract base class for deserialization of Metadata objects. """
__metaclass__ = abc.ABCMeta

@abc.abstractmethod
def deserialize(self, raw_data: bytes) -> "Metadata":
"""Deserialize passed bytes to Metadata object. """
raise NotImplementedError


class MetadataSerializer():
"""Abstract base class for serialization of Metadata objects. """
__metaclass__ = abc.ABCMeta

@abc.abstractmethod
def serialize(self, metadata_obj: "Metadata") -> bytes:
"""Serialize passed Metadata object to bytes. """
raise NotImplementedError


class SignedSerializer():
"""Abstract base class for serialization of Signed objects. """
__metaclass__ = abc.ABCMeta

@abc.abstractmethod
def serialize(self, signed_obj: "Signed") -> bytes:
"""Serialize passed Signed object to bytes. """
raise NotImplementedError

0 comments on commit 79ce034

Please sign in to comment.