Skip to content
Snippets Groups Projects
Commit d678f777 authored by Vincent Texier's avatar Vincent Texier
Browse files

[enh] #95 add optional signing_key argument in Document sub-classes

argument is Optional[SigningKey] with default=None
parent 3a49eca8
No related branches found
No related tags found
No related merge requests found
Pipeline #12881 passed
...@@ -176,6 +176,7 @@ class Block(Document): ...@@ -176,6 +176,7 @@ class Block(Document):
transactions: List[Transaction], transactions: List[Transaction],
inner_hash: str, inner_hash: str,
nonce: int, nonce: int,
signing_key: SigningKey = None,
) -> None: ) -> None:
""" """
Constructor Constructor
...@@ -206,6 +207,7 @@ class Block(Document): ...@@ -206,6 +207,7 @@ class Block(Document):
:param transactions: transactions documents :param transactions: transactions documents
:param inner_hash: the block hash :param inner_hash: the block hash
:param nonce: the nonce value of the block :param nonce: the nonce value of the block
:param signing_key: SigningKey instance to sign the document (default=None)
""" """
super().__init__(version, currency) super().__init__(version, currency)
...@@ -247,6 +249,9 @@ class Block(Document): ...@@ -247,6 +249,9 @@ class Block(Document):
self.inner_hash = inner_hash self.inner_hash = inner_hash
self.nonce = nonce self.nonce = nonce
if signing_key is not None:
self.sign(signing_key)
@property @property
def blockUID(self) -> BlockUID: def blockUID(self) -> BlockUID:
""" """
......
...@@ -63,6 +63,7 @@ class Certification(Document): ...@@ -63,6 +63,7 @@ class Certification(Document):
pubkey_from: str, pubkey_from: str,
identity: Union[Identity, str], identity: Union[Identity, str],
timestamp: BlockUID, timestamp: BlockUID,
signing_key: SigningKey = None,
) -> None: ) -> None:
""" """
Constructor Constructor
...@@ -72,6 +73,7 @@ class Certification(Document): ...@@ -72,6 +73,7 @@ class Certification(Document):
:param pubkey_from: Pubkey of the certifier :param pubkey_from: Pubkey of the certifier
:param identity: Document instance of the certified identity or identity pubkey string :param identity: Document instance of the certified identity or identity pubkey string
:param timestamp: the blockuid :param timestamp: the blockuid
:param signing_key: SigningKey instance to sign the document (default=None)
""" """
super().__init__(version, currency) super().__init__(version, currency)
self.pubkey_from = pubkey_from self.pubkey_from = pubkey_from
...@@ -79,6 +81,9 @@ class Certification(Document): ...@@ -79,6 +81,9 @@ class Certification(Document):
self.pubkey_to = identity.pubkey if isinstance(identity, Identity) else identity self.pubkey_to = identity.pubkey if isinstance(identity, Identity) else identity
self.timestamp = timestamp self.timestamp = timestamp
if signing_key is not None:
self.sign(signing_key)
@classmethod @classmethod
def from_signed_raw( def from_signed_raw(
cls: Type[CertificationType], signed_raw: str cls: Type[CertificationType], signed_raw: str
......
...@@ -17,10 +17,12 @@ import re ...@@ -17,10 +17,12 @@ import re
from typing import Type, TypeVar from typing import Type, TypeVar
from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX, UID_REGEX from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX, UID_REGEX
# required to type hint cls in classmethod
from ..key import SigningKey
from .block_uid import BlockUID from .block_uid import BlockUID
from .document import Document, MalformedDocumentError from .document import Document, MalformedDocumentError
# required to type hint cls in classmethod
IdentityType = TypeVar("IdentityType", bound="Identity") IdentityType = TypeVar("IdentityType", bound="Identity")
...@@ -77,7 +79,13 @@ class Identity(Document): ...@@ -77,7 +79,13 @@ class Identity(Document):
} }
def __init__( def __init__(
self, version: int, currency: str, pubkey: str, uid: str, timestamp: BlockUID self,
version: int,
currency: str,
pubkey: str,
uid: str,
timestamp: BlockUID,
signing_key: SigningKey = None,
) -> None: ) -> None:
""" """
Create an identity document Create an identity document
...@@ -87,6 +95,7 @@ class Identity(Document): ...@@ -87,6 +95,7 @@ class Identity(Document):
:param pubkey: Public key of the account linked to the identity :param pubkey: Public key of the account linked to the identity
:param uid: Unique identifier :param uid: Unique identifier
:param timestamp: BlockUID instance :param timestamp: BlockUID instance
:param signing_key: SigningKey instance to sign the document (default=None)
""" """
super().__init__(version, currency) super().__init__(version, currency)
...@@ -94,6 +103,9 @@ class Identity(Document): ...@@ -94,6 +103,9 @@ class Identity(Document):
self.timestamp = timestamp self.timestamp = timestamp
self.uid = uid self.uid = uid
if signing_key is not None:
self.sign(signing_key)
@classmethod @classmethod
def from_inline( def from_inline(
cls: Type[IdentityType], version: int, currency: str, inline: str cls: Type[IdentityType], version: int, currency: str, inline: str
......
...@@ -17,10 +17,12 @@ import re ...@@ -17,10 +17,12 @@ import re
from typing import Type, TypeVar from typing import Type, TypeVar
from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX
# required to type hint cls in classmethod
from ..key import SigningKey
from .block_uid import BlockUID from .block_uid import BlockUID
from .document import Document, MalformedDocumentError from .document import Document, MalformedDocumentError
# required to type hint cls in classmethod
MembershipType = TypeVar("MembershipType", bound="Membership") MembershipType = TypeVar("MembershipType", bound="Membership")
...@@ -82,6 +84,7 @@ class Membership(Document): ...@@ -82,6 +84,7 @@ class Membership(Document):
membership_type: str, membership_type: str,
uid: str, uid: str,
identity_ts: BlockUID, identity_ts: BlockUID,
signing_key: SigningKey = None,
) -> None: ) -> None:
""" """
Create a membership document Create a membership document
...@@ -93,6 +96,7 @@ class Membership(Document): ...@@ -93,6 +96,7 @@ class Membership(Document):
:param membership_type: "IN" or "OUT" to enter or quit the community :param membership_type: "IN" or "OUT" to enter or quit the community
:param uid: Unique identifier of the identity :param uid: Unique identifier of the identity
:param identity_ts: BlockUID of the identity :param identity_ts: BlockUID of the identity
:param signing_key: SigningKey instance to sign the document (default=None)
""" """
super().__init__(version, currency) super().__init__(version, currency)
...@@ -102,6 +106,9 @@ class Membership(Document): ...@@ -102,6 +106,9 @@ class Membership(Document):
self.uid = uid self.uid = uid
self.identity_ts = identity_ts self.identity_ts = identity_ts
if signing_key is not None:
self.sign(signing_key)
@classmethod @classmethod
def from_inline( def from_inline(
cls: Type[MembershipType], cls: Type[MembershipType],
......
...@@ -19,10 +19,12 @@ from typing import List, Type, TypeVar ...@@ -19,10 +19,12 @@ from typing import List, Type, TypeVar
from duniterpy.api.endpoint import Endpoint, endpoint from duniterpy.api.endpoint import Endpoint, endpoint
from ..constants import BLOCK_HASH_REGEX, PUBKEY_REGEX from ..constants import BLOCK_HASH_REGEX, PUBKEY_REGEX
# required to type hint cls in classmethod
from ..key import SigningKey
from .block_uid import BlockUID from .block_uid import BlockUID
from .document import Document, MalformedDocumentError from .document import Document, MalformedDocumentError
# required to type hint cls in classmethod
PeerType = TypeVar("PeerType", bound="Peer") PeerType = TypeVar("PeerType", bound="Peer")
...@@ -69,6 +71,7 @@ class Peer(Document): ...@@ -69,6 +71,7 @@ class Peer(Document):
pubkey: str, pubkey: str,
block_uid: BlockUID, block_uid: BlockUID,
endpoints: List[Endpoint], endpoints: List[Endpoint],
signing_key: SigningKey = None,
) -> None: ) -> None:
""" """
Init Peer instance Init Peer instance
...@@ -78,6 +81,7 @@ class Peer(Document): ...@@ -78,6 +81,7 @@ class Peer(Document):
:param pubkey: Public key of the issuer :param pubkey: Public key of the issuer
:param block_uid: BlockUID instance timestamp :param block_uid: BlockUID instance timestamp
:param endpoints: List of endpoints string :param endpoints: List of endpoints string
:param signing_key: SigningKey instance to sign the document (default=None)
""" """
super().__init__(version, currency) super().__init__(version, currency)
...@@ -85,6 +89,9 @@ class Peer(Document): ...@@ -85,6 +89,9 @@ class Peer(Document):
self.blockUID = block_uid self.blockUID = block_uid
self.endpoints: List[Endpoint] = endpoints self.endpoints: List[Endpoint] = endpoints
if signing_key is not None:
self.sign(signing_key)
@classmethod @classmethod
def from_signed_raw(cls: Type[PeerType], raw: str) -> PeerType: def from_signed_raw(cls: Type[PeerType], raw: str) -> PeerType:
""" """
......
...@@ -61,7 +61,11 @@ class Revocation(Document): ...@@ -61,7 +61,11 @@ class Revocation(Document):
} }
def __init__( def __init__(
self, version: int, currency: str, identity: Union[Identity, str] self,
version: int,
currency: str,
identity: Union[Identity, str],
signing_key: SigningKey = None,
) -> None: ) -> None:
""" """
Init Revocation instance Init Revocation instance
...@@ -69,12 +73,16 @@ class Revocation(Document): ...@@ -69,12 +73,16 @@ class Revocation(Document):
:param version: Version number :param version: Version number
:param currency: Name of the currency :param currency: Name of the currency
:param identity: Identity instance or identity pubkey :param identity: Identity instance or identity pubkey
:param signing_key: SigningKey instance to sign the document (default=None)
""" """
super().__init__(version, currency) super().__init__(version, currency)
self.identity = identity if isinstance(identity, Identity) else None self.identity = identity if isinstance(identity, Identity) else None
self.pubkey = identity.pubkey if isinstance(identity, Identity) else identity self.pubkey = identity.pubkey if isinstance(identity, Identity) else identity
if signing_key is not None:
self.sign(signing_key)
@classmethod @classmethod
def from_inline( def from_inline(
cls: Type[RevocationType], version: int, currency: str, inline: str cls: Type[RevocationType], version: int, currency: str, inline: str
......
...@@ -548,6 +548,7 @@ class Transaction(Document): ...@@ -548,6 +548,7 @@ class Transaction(Document):
outputs: List[OutputSource], outputs: List[OutputSource],
comment: str, comment: str,
time: Optional[int] = None, time: Optional[int] = None,
signing_key: SigningKey = None,
) -> None: ) -> None:
""" """
Init Transaction instance Init Transaction instance
...@@ -562,6 +563,7 @@ class Transaction(Document): ...@@ -562,6 +563,7 @@ class Transaction(Document):
:param outputs: List of OutputSource instances :param outputs: List of OutputSource instances
:param comment: Comment field :param comment: Comment field
:param time: time when the transaction enters the blockchain :param time: time when the transaction enters the blockchain
:param signing_key: SigningKey instance to sign the document (default=None)
""" """
super().__init__(version, currency) super().__init__(version, currency)
self.blockstamp = blockstamp self.blockstamp = blockstamp
...@@ -574,6 +576,9 @@ class Transaction(Document): ...@@ -574,6 +576,9 @@ class Transaction(Document):
self.time = time self.time = time
self.signatures: List[str] = list() self.signatures: List[str] = list()
if signing_key is not None:
self.sign(signing_key)
def __eq__(self, other: Any) -> bool: def __eq__(self, other: Any) -> bool:
""" """
Check Transaction instances equality Check Transaction instances equality
......
...@@ -84,10 +84,9 @@ def get_signed_raw_revocation_document( ...@@ -84,10 +84,9 @@ def get_signed_raw_revocation_document(
:rtype: str :rtype: str
""" """
revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity)
key = SigningKey.from_credentials(salt, password) key = SigningKey.from_credentials(salt, password)
revocation.sign(key) revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity, key)
return revocation.signed_raw() return revocation.signed_raw()
...@@ -122,7 +121,7 @@ def save_revoke_document(): ...@@ -122,7 +121,7 @@ def save_revoke_document():
# capture current block to get currency name # capture current block to get currency name
current_block = client(bma.blockchain.current) current_block = client(bma.blockchain.current)
# create our Identity document to sign the Certification document # create our Identity document to sign the revocation document
identity = get_identity_document(client, current_block, pubkey) identity = get_identity_document(client, current_block, pubkey)
if identity is None: if identity is None:
print("Identity not found for pubkey {0}".format(pubkey)) print("Identity not found for pubkey {0}".format(pubkey))
......
...@@ -57,14 +57,14 @@ def get_identity_document( ...@@ -57,14 +57,14 @@ def get_identity_document(
def get_certification_document( def get_certification_document(
current_block: dict, self_cert_document: Identity, from_pubkey: str current_block: dict, identity: Identity, signing_key: SigningKey
) -> Certification: ) -> Certification:
""" """
Create and return a Certification document Create and return a Certification document
:param current_block: Current block data :param current_block: Current block data
:param self_cert_document: Identity document :param identity: Identity document instance
:param from_pubkey: Pubkey of the certifier :param signing_key: Signing key of the certifier
:rtype: Certification :rtype: Certification
""" """
...@@ -72,9 +72,10 @@ def get_certification_document( ...@@ -72,9 +72,10 @@ def get_certification_document(
return Certification( return Certification(
version=10, version=10,
currency=current_block["currency"], currency=current_block["currency"],
pubkey_from=from_pubkey, pubkey_from=signing_key.pubkey,
identity=self_cert_document, identity=identity,
timestamp=BlockUID(current_block["number"], current_block["hash"]), timestamp=BlockUID(current_block["number"], current_block["hash"]),
signing_key=signing_key,
) )
...@@ -97,7 +98,6 @@ def send_certification(): ...@@ -97,7 +98,6 @@ def send_certification():
# create key from credentials # create key from credentials
key = SigningKey.from_credentials(salt, password) key = SigningKey.from_credentials(salt, password)
pubkey_from = key.pubkey
# prompt entry # prompt entry
pubkey_to = input("Enter pubkey to certify: ") pubkey_to = input("Enter pubkey to certify: ")
...@@ -113,10 +113,7 @@ def send_certification(): ...@@ -113,10 +113,7 @@ def send_certification():
return return
# send the Certification document to the node # send the Certification document to the node
certification = get_certification_document(current_block, identity, pubkey_from) certification = get_certification_document(current_block, identity, key)
# sign document
certification.sign([key])
# Here we request for the path wot/certify # Here we request for the path wot/certify
try: try:
......
...@@ -57,11 +57,9 @@ def get_identity_document( ...@@ -57,11 +57,9 @@ def get_identity_document(
pubkey=key.pubkey, pubkey=key.pubkey,
uid=uid, uid=uid,
timestamp=timestamp, timestamp=timestamp,
signing_key=key,
) )
# sign document
identity.sign(key)
return identity return identity
......
...@@ -65,11 +65,9 @@ def get_membership_document( ...@@ -65,11 +65,9 @@ def get_membership_document(
membership_type=membership_type, membership_type=membership_type,
uid=uid, uid=uid,
identity_ts=identity_timestamp, identity_ts=identity_timestamp,
signing_key=key,
) )
# sign document
membership.sign(key)
return membership return membership
......
...@@ -42,7 +42,11 @@ TRANSACTION_VERSION = 10 ...@@ -42,7 +42,11 @@ TRANSACTION_VERSION = 10
def get_transaction_document( def get_transaction_document(
current_block: dict, source: dict, from_pubkey: str, to_pubkey: str current_block: dict,
source: dict,
from_pubkey: str,
to_pubkey: str,
signing_key: SigningKey,
) -> Transaction: ) -> Transaction:
""" """
Return a Transaction document Return a Transaction document
...@@ -51,6 +55,7 @@ def get_transaction_document( ...@@ -51,6 +55,7 @@ def get_transaction_document(
:param source: Source to send :param source: Source to send
:param from_pubkey: Public key of the issuer :param from_pubkey: Public key of the issuer
:param to_pubkey: Public key of the receiver :param to_pubkey: Public key of the receiver
:param signing_key: Signing key of the issuer
:return: Transaction :return: Transaction
""" """
...@@ -97,6 +102,7 @@ def get_transaction_document( ...@@ -97,6 +102,7 @@ def get_transaction_document(
unlocks=unlocks, unlocks=unlocks,
outputs=outputs, outputs=outputs,
comment="", comment="",
signing_key=signing_key,
) )
return transaction return transaction
...@@ -141,12 +147,9 @@ def send_transaction(): ...@@ -141,12 +147,9 @@ def send_transaction():
# create the transaction document # create the transaction document
transaction = get_transaction_document( transaction = get_transaction_document(
current_block, source, pubkey_from, pubkey_to current_block, source, pubkey_from, pubkey_to, key
) )
# sign document
transaction.sign([key])
# send the Transaction document to the node # send the Transaction document to the node
try: try:
client(bma.tx.process, transaction.signed_raw()) client(bma.tx.process, transaction.signed_raw())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment