From 24f6b4ce5eb2b03568c8b73563fd155b825211c0 Mon Sep 17 00:00:00 2001 From: "Kieran R. Prasch" Date: Wed, 18 Nov 2020 19:32:57 -0800 Subject: [PATCH] Expand alice confguration options to include policy storage and stay current with signed tmaps --- nucypher/cli/painting/policies.py | 3 +- nucypher/config/characters.py | 4 +-- nucypher/policy/identity.py | 36 +++++++++---------- nucypher/policy/policies.py | 20 ++++++----- .../characters/test_decentralized_grant.py | 1 - 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/nucypher/cli/painting/policies.py b/nucypher/cli/painting/policies.py index f6bfb5c33..0ad7d518f 100644 --- a/nucypher/cli/painting/policies.py +++ b/nucypher/cli/painting/policies.py @@ -15,7 +15,8 @@ along with nucypher. If not, see . """ -from typing import List + +from typing import List, Optional from tabulate import tabulate diff --git a/nucypher/config/characters.py b/nucypher/config/characters.py index 91ca1d970..e0cc682eb 100644 --- a/nucypher/config/characters.py +++ b/nucypher/config/characters.py @@ -185,8 +185,8 @@ class AliceConfiguration(CharacterConfiguration): payload = dict( m=self.m, n=self.n, - store_policy_credentials=self.store_policies, - store_character_cards=self.store_cards + store_policies=self.store_policies, + store_cards=self.store_cards ) if not self.federated_only: if self.rate: diff --git a/nucypher/policy/identity.py b/nucypher/policy/identity.py index af156f2d4..7b79b2c79 100644 --- a/nucypher/policy/identity.py +++ b/nucypher/policy/identity.py @@ -17,6 +17,8 @@ import base64 import json + +import maya from pathlib import Path from typing import Union, Optional, Dict, Callable @@ -32,7 +34,7 @@ from nucypher.characters.base import Character from nucypher.characters.lawful import Alice, Bob from nucypher.config.constants import DEFAULT_CONFIG_ROOT from nucypher.crypto.powers import SigningPower, DecryptingPower -from nucypher.policy.collections import TreasureMap +from nucypher.policy.collections import TreasureMap, SignedTreasureMap class Card: @@ -55,7 +57,7 @@ class Card: __ID_LENGTH = 20 # TODO: Review this size (bytes of hex len?) __MAX_NICKNAME_SIZE = 10 __BASE_PAYLOAD_SIZE = sum(length[1] for length in _specification.values() if isinstance(length[1], int)) - __MAX_CARD_LENGTH = __BASE_PAYLOAD_SIZE + __MAX_NICKNAME_SIZE + __MAX_CARD_LENGTH = __BASE_PAYLOAD_SIZE + __MAX_NICKNAME_SIZE + 2 __FILE_EXTENSION = 'card' __DELIMITER = ':' CARD_DIR = Path(DEFAULT_CONFIG_ROOT) / 'cards' @@ -153,7 +155,8 @@ class Card: @classmethod def from_bytes(cls, card_bytes: bytes) -> 'Card': if len(card_bytes) > cls.__MAX_CARD_LENGTH: - raise cls.InvalidCard(f'Card exceeds maximum size. Verify the card filepath and contents.') + raise cls.InvalidCard(f'Card exceeds maximum size (max is {cls.__MAX_CARD_LENGTH} bytes card is {len(card_bytes)} bytes). ' + f'Verify the card filepath and contents.') return BytestringKwargifier(cls, **cls._specification)(card_bytes) @classmethod @@ -333,7 +336,7 @@ class Card: os.remove(str(self.filepath)) -class PolicyCredential: +class PolicyCredential: # TODO: Rename this. It is not a credential in any way. """ A portable structure that contains information necessary for Alice or Bob to utilize the policy on the network that the credential describes. @@ -365,26 +368,21 @@ class PolicyCredential: @classmethod def from_json(cls, data: str): - """ - Deserializes the PolicyCredential from JSON. - """ + """Deserializes the PolicyCredential from JSON.""" cred_json = json.loads(data) - - alice_verifying_key = UmbralPublicKey.from_bytes( - cred_json['alice_verifying_key'], - decoder=bytes().fromhex) - label = bytes().fromhex(cred_json['label']) + alice_verifying_key = UmbralPublicKey.from_bytes(cred_json['alice_verifying_key'], decoder=bytes.fromhex) + label = bytes.fromhex(cred_json['label']) expiration = maya.MayaDT.from_iso8601(cred_json['expiration']) - policy_pubkey = UmbralPublicKey.from_bytes( - cred_json['policy_pubkey'], - decoder=bytes().fromhex) + policy_pubkey = UmbralPublicKey.from_bytes(cred_json['policy_pubkey'], decoder=bytes.fromhex) treasure_map = None - if 'treasure_map' in cred_json: - treasure_map = TreasureMap.from_bytes( - bytes().fromhex(cred_json['treasure_map'])) + # TODO: Support unsigned treasuremaps? + treasure_map = SignedTreasureMap.from_bytes(bytes.fromhex(cred_json['treasure_map'])) - return cls(alice_verifying_key, label, expiration, policy_pubkey, + return cls(alice_verifying_key, + label, + expiration, + policy_pubkey, treasure_map) def __eq__(self, other): diff --git a/nucypher/policy/policies.py b/nucypher/policy/policies.py index fd2bd4b86..398208444 100644 --- a/nucypher/policy/policies.py +++ b/nucypher/policy/policies.py @@ -31,7 +31,7 @@ from twisted._threads import AlreadyQuit from twisted.internet import reactor from twisted.internet.defer import ensureDeferred, Deferred from twisted.python.threadpool import ThreadPool -from typing import Callable +from typing import Callable, Tuple from typing import Generator, List, Set, Optional from umbral.keys import UmbralPublicKey from umbral.kfrags import KFrag @@ -47,6 +47,7 @@ from nucypher.crypto.utils import construct_policy_id from nucypher.network.exceptions import NodeSeemsToBeDown from nucypher.network.middleware import RestMiddleware from nucypher.utilities.logging import Logger +from nucypher.policy.collections import TreasureMap, SignedTreasureMap class Arrangement: @@ -331,6 +332,7 @@ class Policy(ABC): POLICY_ID_LENGTH = 16 _arrangement_class = NotImplemented + _treasure_map_class = SignedTreasureMap log = Logger("Policy") @@ -338,11 +340,11 @@ class Policy(ABC): """Too many Ursulas rejected""" def __init__(self, - alice, - label, + alice: Alice, + label: bytes, expiration: maya.MayaDT, - bob=None, - kfrags=(UNKNOWN_KFRAG,), + bob: 'Bob' = None, + kfrags: Tuple[KFrag, ...] = (UNKNOWN_KFRAG,), public_key=None, m: int = None, alice_signature=NOT_SIGNED) -> None: @@ -351,10 +353,10 @@ class Policy(ABC): :param kfrags: A list of KFrags to distribute per this Policy. :param label: The identity of the resource to which Bob is granted access. """ - self.alice = alice # type: Alice - self.label = label # type: bytes - self.bob = bob # type: Bob - self.kfrags = kfrags # type: List[KFrag] + self.alice = alice + self.label = label + self.bob = bob + self.kfrags = kfrags self.public_key = public_key self._id = construct_policy_id(self.label, bytes(self.bob.stamp)) self.treasure_map = self._treasure_map_class(m=m) diff --git a/tests/acceptance/characters/test_decentralized_grant.py b/tests/acceptance/characters/test_decentralized_grant.py index 8f21aa1fe..d491757fc 100644 --- a/tests/acceptance/characters/test_decentralized_grant.py +++ b/tests/acceptance/characters/test_decentralized_grant.py @@ -22,7 +22,6 @@ import pytest from nucypher.crypto.api import keccak_digest from nucypher.datastore.models import PolicyArrangement from nucypher.datastore.models import TreasureMap as DatastoreTreasureMap -from nucypher.policy.collections import PolicyCredential from nucypher.policy.collections import SignedTreasureMap as DecentralizedTreasureMap from nucypher.policy.identity import PolicyCredential from tests.utils.middleware import MockRestMiddleware