diff --git a/newsfragments/2987.removal.rst b/newsfragments/2987.removal.rst new file mode 100644 index 000000000..7c4865f48 --- /dev/null +++ b/newsfragments/2987.removal.rst @@ -0,0 +1,8 @@ +Removals: +- RPC servers +- character WebControllers +- unused literature +- unused CLI option definitions +- CLI helper functions for Alice, Bob, Contacts interactivity +- interactive Ursula mode +- enrico CLI commands diff --git a/nucypher/blockchain/eth/interfaces.py b/nucypher/blockchain/eth/interfaces.py index 087c7b7ef..3abf6a932 100644 --- a/nucypher/blockchain/eth/interfaces.py +++ b/nucypher/blockchain/eth/interfaces.py @@ -17,16 +17,20 @@ along with nucypher. If not, see . import math -import os import pprint from pathlib import Path - -from eth.typing import TransactionDict from typing import Callable, NamedTuple, Tuple, Union, Optional from typing import List from urllib.parse import urlparse import requests +from constant_sorrow.constants import ( + INSUFFICIENT_ETH, + NO_BLOCKCHAIN_CONNECTION, + NO_COMPILATION_PERFORMED, + UNKNOWN_TX_STATUS +) +from eth.typing import TransactionDict from eth_tester import EthereumTester from eth_tester.exceptions import TransactionFailed as TestTransactionFailed from eth_typing import ChecksumAddress @@ -39,15 +43,6 @@ from web3.middleware import geth_poa_middleware from web3.providers import BaseProvider from web3.types import TxReceipt -from constant_sorrow.constants import ( - INSUFFICIENT_ETH, - NO_BLOCKCHAIN_CONNECTION, - NO_COMPILATION_PERFORMED, - READ_ONLY_INTERFACE, - UNKNOWN_TX_STATUS -) - -from nucypher.crypto.powers import TransactingPower from nucypher.blockchain.eth.clients import EthereumClient, POA_CHAINS, InfuraClient from nucypher.blockchain.eth.decorators import validate_checksum_address from nucypher.blockchain.eth.providers import ( @@ -63,7 +58,8 @@ from nucypher.blockchain.eth.sol.compile.compile import multiversion_compile from nucypher.blockchain.eth.sol.compile.constants import SOLIDITY_SOURCE_ROOT from nucypher.blockchain.eth.sol.compile.types import SourceBundle from nucypher.blockchain.eth.utils import get_transaction_name, prettify_eth_amount -from nucypher.control.emitters import StdoutEmitter, JSONRPCStdoutEmitter +from nucypher.control.emitters import StdoutEmitter +from nucypher.crypto.powers import TransactingPower from nucypher.utilities.ethereum import encode_constructor_arguments from nucypher.utilities.gas_strategies import ( construct_datafeed_median_strategy, diff --git a/nucypher/characters/banners.py b/nucypher/characters/banners.py index 7cf31a64d..0ac9be1db 100644 --- a/nucypher/characters/banners.py +++ b/nucypher/characters/banners.py @@ -93,16 +93,3 @@ Yb, `88 88 IP'`Yb the Untrusted Re-Encryption Proxy. {} ''' - - -STAKEHOLDER_BANNER = r""" - ____ __ __ -/\ _`\ /\ \__ /\ \ -\ \,\L\_\ \ ,_\ __ \ \ \/'\ __ _ __ - \/_\__ \\ \ \/ /'__`\\ \ , < /'__`\/\`'__\ - /\ \L\ \ \ \_/\ \L\.\\ \ \\`\ /\ __/\ \ \/ - \ `\____\ \__\ \__/.\_\ \_\ \_\ \____\\ \_\ - \/_____/\/__/\/__/\/_/\/_/\/_/\/____/ \/_/ - -The Holder of Stakes. -""" diff --git a/nucypher/characters/base.py b/nucypher/characters/base.py index 3295e37f3..0872009dc 100644 --- a/nucypher/characters/base.py +++ b/nucypher/characters/base.py @@ -18,7 +18,7 @@ along with nucypher. If not, see . from contextlib import suppress from pathlib import Path -from typing import ClassVar, Dict, List, Optional, Union +from typing import ClassVar, Dict, List, Optional from constant_sorrow.constants import ( NO_BLOCKCHAIN_CONNECTION, @@ -29,15 +29,12 @@ from constant_sorrow.constants import ( ) from eth_keys import KeyAPI as EthKeyAPI from eth_utils import to_canonical_address - from nucypher_core import MessageKit from nucypher_core.umbral import PublicKey from nucypher.acumen.nicknames import Nickname from nucypher.blockchain.eth.registry import BaseContractRegistry, InMemoryContractRegistry from nucypher.blockchain.eth.signers.base import Signer -from nucypher.characters.control.controllers import CharacterCLIController -from nucypher.control.controllers import JSONRPCController from nucypher.crypto.keystore import Keystore from nucypher.crypto.powers import ( CryptoPower, @@ -380,24 +377,6 @@ class Character(Learner): raise RuntimeError('Federated address can only be derived for federated characters.') return federated_address - def make_rpc_controller(self, crash_on_error: bool = False): - app_name = bytes(self.stamp).hex()[:6] - controller = JSONRPCController(app_name=app_name, - crash_on_error=crash_on_error, - interface=self.interface) - - self.controller = controller - return controller - - def make_cli_controller(self, crash_on_error: bool = False): - app_name = bytes(self.stamp).hex()[:6] - controller = CharacterCLIController(app_name=app_name, - crash_on_error=crash_on_error, - interface=self.interface) - - self.controller = controller - return controller - def disenchant(self): self.log.debug(f"Disenchanting {self}") Learner.stop_learning_loop(self) diff --git a/nucypher/characters/control/__init__.py b/nucypher/characters/control/__init__.py deleted file mode 100644 index 821da6352..000000000 --- a/nucypher/characters/control/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" diff --git a/nucypher/characters/control/controllers.py b/nucypher/characters/control/controllers.py deleted file mode 100644 index b81cf1dc2..000000000 --- a/nucypher/characters/control/controllers.py +++ /dev/null @@ -1,38 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from nucypher.control.controllers import CLIController -from nucypher.control.emitters import StdoutEmitter - - -class CharacterCLIController(CLIController): - - _emitter_class = StdoutEmitter - - def __init__(self, - interface: 'CharacterPublicInterface', - *args, - **kwargs): - super().__init__(interface=interface, *args, **kwargs) - - def _perform_action(self, *args, **kwargs) -> dict: - try: - response_data = super()._perform_action(*args, **kwargs) - finally: - self.log.debug(f"Finished action '{kwargs['action']}', stopping {self.interface.implementer}") - self.interface.implementer.disenchant() - return response_data diff --git a/nucypher/characters/control/interfaces.py b/nucypher/characters/control/interfaces.py deleted file mode 100644 index e6f6dfc89..000000000 --- a/nucypher/characters/control/interfaces.py +++ /dev/null @@ -1,184 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from typing import Union, List - -import maya - -from nucypher_core import MessageKit, HRAC, EncryptedTreasureMap -from nucypher_core.umbral import PublicKey - -from nucypher.characters.base import Character -from nucypher.characters.control.specifications import alice, bob, enrico -from nucypher.control.interfaces import attach_schema, ControlInterface -from nucypher.crypto.powers import DecryptingPower, SigningPower -from nucypher.network.middleware import RestMiddleware - - -class CharacterPublicInterface(ControlInterface): - - def __init__(self, character: Character = None, *args, **kwargs): - super().__init__(implementer=character, *args, **kwargs) - - -class AliceInterface(CharacterPublicInterface): - - @attach_schema(alice.CreatePolicy) - def create_policy(self, - bob_encrypting_key: PublicKey, - bob_verifying_key: PublicKey, - label: bytes, - threshold: int, - shares: int, - expiration: maya.MayaDT, - value: int = None - ) -> dict: - - from nucypher.characters.lawful import Bob - bob = Bob.from_public_keys(encrypting_key=bob_encrypting_key, - verifying_key=bob_verifying_key) - - new_policy = self.implementer.create_policy( - bob=bob, - label=label, - threshold=threshold, - shares=shares, - expiration=expiration, - value=value - ) - response_data = {'label': new_policy.label, 'policy_encrypting_key': new_policy.public_key} - return response_data - - @attach_schema(alice.DerivePolicyEncryptionKey) - def derive_policy_encrypting_key(self, label: bytes) -> dict: - policy_encrypting_key = self.implementer.get_policy_encrypting_key_from_label(label) - response_data = {'policy_encrypting_key': policy_encrypting_key, 'label': label} - return response_data - - @attach_schema(alice.GrantPolicy) - def grant(self, - bob_encrypting_key: PublicKey, - bob_verifying_key: PublicKey, - label: bytes, - threshold: int, - shares: int, - expiration: maya.MayaDT, - value: int = None, - rate: int = None, - ) -> dict: - - from nucypher.characters.lawful import Bob - bob = Bob.from_public_keys(encrypting_key=bob_encrypting_key, - verifying_key=bob_verifying_key) - - new_policy = self.implementer.grant(bob=bob, - label=label, - threshold=threshold, - shares=shares, - value=value, - rate=rate, - expiration=expiration) - - response_data = {'treasure_map': new_policy.treasure_map, - 'policy_encrypting_key': new_policy.public_key, - # For the users of this interface, Publisher is always the same as Alice, - # so we are only returning the Alice's key. - 'alice_verifying_key': self.implementer.stamp.as_umbral_pubkey()} - - return response_data - - @attach_schema(alice.Revoke) - def revoke(self, label: bytes, bob_verifying_key: PublicKey) -> dict: - - # TODO: Move deeper into characters - policy_hrac = HRAC(self.implementer.stamp.as_umbral_pubkey(), bob_verifying_key, label) - policy = self.implementer.active_policies[policy_hrac] - - receipt, failed_revocations = self.implementer.revoke(policy) - if len(failed_revocations) > 0: - for node_id, attempt in failed_revocations.items(): - revocation, fail_reason = attempt - if fail_reason == RestMiddleware.NotFound: - del (failed_revocations[node_id]) - if len(failed_revocations) <= (policy.shares - policy.threshold + 1): - del (self.implementer.active_policies[policy_hrac]) - - response_data = {'failed_revocations': len(failed_revocations)} - return response_data - - @attach_schema(alice.Decrypt) - def decrypt(self, label: bytes, message_kit: MessageKit) -> dict: - """ - Character control endpoint to allow Alice to decrypt her own data. - """ - plaintexts = self.implementer.decrypt_message_kit( - message_kit=message_kit, - label=label - ) - - response = {'cleartexts': plaintexts} - return response - - @attach_schema(alice.PublicKeys) - def public_keys(self) -> dict: - """ - Character control endpoint for getting Alice's public keys. - """ - verifying_key = self.implementer.public_keys(SigningPower) - response_data = {'alice_verifying_key': verifying_key} - return response_data - - -class BobInterface(CharacterPublicInterface): - - @attach_schema(bob.RetrieveAndDecrypt) - def retrieve_and_decrypt(self, - alice_verifying_key: PublicKey, - message_kits: List[MessageKit], - encrypted_treasure_map: EncryptedTreasureMap) -> dict: - """ - Character control endpoint for re-encrypting and decrypting policy data. - """ - plaintexts = self.implementer.retrieve_and_decrypt(message_kits, - alice_verifying_key=alice_verifying_key, - encrypted_treasure_map=encrypted_treasure_map) - - response_data = {'cleartexts': plaintexts} - return response_data - - @attach_schema(bob.PublicKeys) - def public_keys(self) -> dict: - """ - Character control endpoint for getting Bob's encrypting and signing public keys - """ - verifying_key = self.implementer.public_keys(SigningPower) - encrypting_key = self.implementer.public_keys(DecryptingPower) - response_data = {'bob_encrypting_key': encrypting_key, 'bob_verifying_key': verifying_key} - return response_data - - -class EnricoInterface(CharacterPublicInterface): - - @attach_schema(enrico.EncryptMessage) - def encrypt_message(self, plaintext: Union[str, bytes]) -> dict: - """ - Character control endpoint for encrypting data for a policy and - receiving the messagekit (and signature) to give to Bob. - """ - message_kit = self.implementer.encrypt_message(plaintext=plaintext) - response_data = {'message_kit': message_kit} - return response_data diff --git a/nucypher/characters/control/specifications/__init__.py b/nucypher/characters/control/specifications/__init__.py deleted file mode 100644 index 821da6352..000000000 --- a/nucypher/characters/control/specifications/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" diff --git a/nucypher/characters/control/specifications/alice.py b/nucypher/characters/control/specifications/alice.py deleted file mode 100644 index c5c5b96b3..000000000 --- a/nucypher/characters/control/specifications/alice.py +++ /dev/null @@ -1,151 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - - -import click -from marshmallow import validates_schema - -from nucypher.characters.control.specifications import fields as character_fields -from nucypher.control.specifications import fields as base_fields -from nucypher.control.specifications.base import BaseSchema -from nucypher.control.specifications.exceptions import InvalidArgumentCombo -from nucypher.cli import options, types - - -class PolicyBaseSchema(BaseSchema): - - bob_encrypting_key = character_fields.Key( - required=True, load_only=True, - click=click.option( - '--bob-encrypting-key', - '-bek', - help="Bob's encrypting key as a hexadecimal string", - type=click.STRING, required=False)) - bob_verifying_key = character_fields.Key( - required=True, load_only=True, - click=click.option( - '--bob-verifying-key', - '-bvk', - help="Bob's verifying key as a hexadecimal string", - type=click.STRING, required=False)) - threshold = base_fields.PositiveInteger( - required=True, load_only=True, - click=options.option_threshold) - shares = base_fields.PositiveInteger( - required=True, load_only=True, - click=options.option_shares) - expiration = character_fields.DateTime( - required=True, load_only=True, - click=click.option( - '--expiration', - help="Expiration Datetime of a policy", - type=click.DateTime()) - ) - - # optional input - value = character_fields.Wei( - load_only=True, - click=click.option('--value', help="Total policy value (in Wei)", type=types.WEI)) - - rate = character_fields.Wei( - load_only=True, - required=False, - click=options.option_rate - ) - - # output - policy_encrypting_key = character_fields.Key(dump_only=True) - - @validates_schema - def check_valid_n_and_m(self, data, **kwargs): - # ensure that n is greater than or equal to m - if not (0 < data['threshold'] <= data['shares']): - raise InvalidArgumentCombo(f"`shares` and `threshold` must satisfy 0 < threshold ≤ shares") - - @validates_schema - def check_rate_or_value_not_both(self, data, **kwargs): - - if (data.get('rate') is not None) and (data.get('value') is not None): - raise InvalidArgumentCombo("Choose either rate (per period in duration) OR value (total for duration)") - - # TODO: decide if we should inject config defaults before this validation - # if not (data.get('rate', 0) ^ data.get('value', 0)): - # raise InvalidArgumentCombo("Either rate or value must be greater than zero.") - - -class CreatePolicy(PolicyBaseSchema): - - label = character_fields.Label( - required=True, - click=options.option_label(required=True)) - - -class GrantPolicy(PolicyBaseSchema): - - label = character_fields.Label( - load_only=True, required=True, - click=options.option_label(required=False)) - - # output fields - # treasure map only used for serialization so no need to provide federated/non-federated context - treasure_map = character_fields.EncryptedTreasureMap(dump_only=True) - - alice_verifying_key = character_fields.Key(dump_only=True) - - -class DerivePolicyEncryptionKey(BaseSchema): - - label = character_fields.Label( - required=True, - click=options.option_label(required=True)) - - # output - policy_encrypting_key = character_fields.Key(dump_only=True) - - -class Revoke(BaseSchema): - - label = character_fields.Label( - required=True, load_only=True, - click=options.option_label(required=True)) - bob_verifying_key = character_fields.Key( - required=True, load_only=True, - click=click.option( - '--bob-verifying-key', - '-bvk', - help="Bob's verifying key as a hexadecimal string", type=click.STRING, - required=True)) - - # output - failed_revocations = base_fields.Integer(dump_only=True) - - -class Decrypt(BaseSchema): - label = character_fields.Label( - required=True, load_only=True, - click=options.option_label(required=True)) - message_kit = character_fields.MessageKit( - load_only=True, - click=options.option_message_kit(required=True)) - - # output - cleartexts = base_fields.List(character_fields.Cleartext(), dump_only=True) - - -class PublicKeys(BaseSchema): - - alice_verifying_key = character_fields.Key(dump_only=True) diff --git a/nucypher/characters/control/specifications/bob.py b/nucypher/characters/control/specifications/bob.py deleted file mode 100644 index 6ec121678..000000000 --- a/nucypher/characters/control/specifications/bob.py +++ /dev/null @@ -1,48 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -import nucypher.control.specifications.fields as base_fields -from nucypher.characters.control.specifications import fields as character_fields -from nucypher.characters.control.specifications.fields.treasuremap import EncryptedTreasureMap -from nucypher.cli import options -from nucypher.control.specifications.base import BaseSchema - - -class RetrieveAndDecrypt(BaseSchema): - - alice_verifying_key = character_fields.Key( - required=True, - load_only=True, - click=options.option_alice_verifying_key(required=True) - ) - message_kits = base_fields.StringList( - character_fields.MessageKit(), - required=True, - load_only=True, - click=options.option_message_kit(required=True, multiple=True) - ) - encrypted_treasure_map = EncryptedTreasureMap(required=True, - load_only=True, - click=options.option_treasure_map) - - # output - cleartexts = base_fields.List(character_fields.Cleartext(), dump_only=True) - - -class PublicKeys(BaseSchema): - bob_encrypting_key = character_fields.Key(dump_only=True) - bob_verifying_key = character_fields.Key(dump_only=True) diff --git a/nucypher/characters/control/specifications/enrico.py b/nucypher/characters/control/specifications/enrico.py deleted file mode 100644 index 55841b0a3..000000000 --- a/nucypher/characters/control/specifications/enrico.py +++ /dev/null @@ -1,68 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -import click -from marshmallow import post_load - -import nucypher.control.specifications.exceptions -from nucypher.characters.control.specifications import fields -from nucypher.cli import options -from nucypher.cli.types import EXISTING_READABLE_FILE -from nucypher.control.specifications.base import BaseSchema - - -class EncryptMessage(BaseSchema): - - # input - message = fields.Cleartext( - load_only=True, - allow_none=True, - click=click.option('--message', help="A unicode message to encrypt for a policy") - ) - - file = fields.FileField( - load_only=True, - allow_none=True, - click=click.option('--file', help="Filepath to plaintext file to encrypt", type=EXISTING_READABLE_FILE) - ) - - policy_encrypting_key = fields.Key( - required=False, - load_only=True, - click=options.option_policy_encrypting_key() - ) - - @post_load() - def format_method_arguments(self, data, **kwargs): - """ - input can be through either the file input or a raw message, - we output one of them as the "plaintext" arg to enrico.encrypt_message - """ - - if data.get('message') and data.get('file'): - raise nucypher.control.specifications.exceptions.InvalidArgumentCombo( - "Choose either a message or a filepath but not both.") - - if data.get('message'): - data = bytes(data['message'], encoding='utf-8') - else: - data = data['file'] - - return {"plaintext": data} - - # output - message_kit = fields.MessageKit(dump_only=True) diff --git a/nucypher/characters/control/specifications/fields/__init__.py b/nucypher/characters/control/specifications/fields/__init__.py deleted file mode 100644 index ae5e73bab..000000000 --- a/nucypher/characters/control/specifications/fields/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from nucypher.characters.control.specifications.fields.key import * -from nucypher.characters.control.specifications.fields.treasuremap import * -from nucypher.characters.control.specifications.fields.messagekit import * -from nucypher.characters.control.specifications.fields.datetime import * -from nucypher.characters.control.specifications.fields.label import * -from nucypher.characters.control.specifications.fields.cleartext import * -from nucypher.characters.control.specifications.fields.misc import * -from nucypher.characters.control.specifications.fields.file import * diff --git a/nucypher/characters/control/specifications/fields/cleartext.py b/nucypher/characters/control/specifications/fields/cleartext.py deleted file mode 100644 index f51b4c891..000000000 --- a/nucypher/characters/control/specifications/fields/cleartext.py +++ /dev/null @@ -1,31 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from base64 import b64encode - -from marshmallow import fields - -from nucypher.control.specifications.fields.base import BaseField - - -class Cleartext(BaseField, fields.String): - - def _serialize(self, value, attr, obj, **kwargs): - return value.decode() - - def _deserialize(self, value, attr, data, **kwargs): - return b64encode(bytes(value, encoding='utf-8')).decode() diff --git a/nucypher/characters/control/specifications/fields/datetime.py b/nucypher/characters/control/specifications/fields/datetime.py deleted file mode 100644 index 1814c3777..000000000 --- a/nucypher/characters/control/specifications/fields/datetime.py +++ /dev/null @@ -1,34 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -import maya -from marshmallow import fields - -from nucypher.control.specifications.exceptions import InvalidInputData -from nucypher.control.specifications.fields.base import BaseField - - -class DateTime(BaseField, fields.Field): - - def _serialize(self, value, attr, obj, **kwargs): - return value.iso8601() - - def _deserialize(self, value, attr, data, **kwargs): - try: - return maya.MayaDT.from_iso8601(iso8601_string=value) - except maya.pendulum.parsing.ParserError as e: - raise InvalidInputData(f"Could not convert input for {self.name} to a valid date time: {e}") diff --git a/nucypher/characters/control/specifications/fields/file.py b/nucypher/characters/control/specifications/fields/file.py deleted file mode 100644 index 7132d33cc..000000000 --- a/nucypher/characters/control/specifications/fields/file.py +++ /dev/null @@ -1,36 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from pathlib import Path - -from marshmallow import fields - -from nucypher.control.specifications.exceptions import InvalidInputData -from nucypher.control.specifications.fields.base import BaseField - - -class FileField(BaseField, fields.String): - def _deserialize(self, value, attr, data, **kwargs): - p = Path(value) - if not p.exists(): - raise InvalidInputData(f"Filepath {value} does not exist") - if not p.is_file(): - raise InvalidInputData(f"Filepath {value} does not map to a file") - - with p.open(mode='rb') as plaintext_file: - plaintext = plaintext_file.read() # TODO: #2106 Handle large files - return plaintext diff --git a/nucypher/characters/control/specifications/fields/label.py b/nucypher/characters/control/specifications/fields/label.py deleted file mode 100644 index 480ce5bb7..000000000 --- a/nucypher/characters/control/specifications/fields/label.py +++ /dev/null @@ -1,31 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from marshmallow import fields - -from nucypher.control.specifications.fields.base import BaseField - - -class Label(BaseField, fields.Field): - - def _serialize(self, value, attr, obj, **kwargs): - return value.decode('utf-8') - - def _deserialize(self, value, attr, data, **kwargs): - if isinstance(value, bytes): - return value - return value.encode() diff --git a/nucypher/characters/control/specifications/fields/misc.py b/nucypher/characters/control/specifications/fields/misc.py deleted file mode 100644 index be2849e9a..000000000 --- a/nucypher/characters/control/specifications/fields/misc.py +++ /dev/null @@ -1,23 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from nucypher.control.specifications.fields.base import Integer -from nucypher.cli import types - - -class Wei(Integer): - click_type = types.WEI diff --git a/nucypher/characters/control/specifications/fields/treasuremap.py b/nucypher/characters/control/specifications/fields/treasuremap.py deleted file mode 100644 index 01b7f31f9..000000000 --- a/nucypher/characters/control/specifications/fields/treasuremap.py +++ /dev/null @@ -1,45 +0,0 @@ -""" - This file is part of nucypher. - - nucypher is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - nucypher is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with nucypher. If not, see . -""" - -from nucypher_core import EncryptedTreasureMap as EncryptedTreasureMapClass, TreasureMap as TreasureMapClass - -from nucypher.control.specifications.exceptions import InvalidInputData -from nucypher.control.specifications.fields.base import Base64BytesRepresentation - - -class EncryptedTreasureMap(Base64BytesRepresentation): - """ - JSON Parameter representation of EncryptedTreasureMap. - """ - def _deserialize(self, value, attr, data, **kwargs): - try: - encrypted_treasure_map_bytes = super()._deserialize(value, attr, data, **kwargs) - return EncryptedTreasureMapClass.from_bytes(encrypted_treasure_map_bytes) - except Exception as e: - raise InvalidInputData(f"Could not convert input for {self.name} to an EncryptedTreasureMap: {e}") from e - - -class TreasureMap(Base64BytesRepresentation): - """ - JSON Parameter representation of (unencrypted) TreasureMap. - """ - def _deserialize(self, value, attr, data, **kwargs): - try: - treasure_map_bytes = super()._deserialize(value, attr, data, **kwargs) - return TreasureMapClass.from_bytes(treasure_map_bytes) - except Exception as e: - raise InvalidInputData(f"Could not convert input for {self.name} to a TreasureMap: {e}") from e diff --git a/nucypher/characters/lawful.py b/nucypher/characters/lawful.py index 4aefd2253..83a4ab8c0 100644 --- a/nucypher/characters/lawful.py +++ b/nucypher/characters/lawful.py @@ -19,9 +19,6 @@ along with nucypher. If not, see . import contextlib import json import time -from base64 import b64encode -from http import HTTPStatus -from json.decoder import JSONDecodeError from pathlib import Path from queue import Queue from typing import ( @@ -50,7 +47,6 @@ from cryptography.hazmat.primitives.serialization import Encoding from cryptography.x509 import Certificate, NameOID from eth_typing.evm import ChecksumAddress from eth_utils import to_checksum_address -from flask import Response, request from nucypher_core import ( Address, HRAC, @@ -83,14 +79,7 @@ from nucypher.characters.banners import ( URSULA_BANNER, ) from nucypher.characters.base import Character, Learner -from nucypher.characters.control.interfaces import ( - AliceInterface, - BobInterface, - EnricoInterface, -) -from nucypher.cli.processes import UrsulaCommandProtocol from nucypher.config.storages import NodeStorage -from nucypher.control.controllers import WebController from nucypher.control.emitters import StdoutEmitter from nucypher.crypto.keypairs import HostingKeypair from nucypher.crypto.powers import ( @@ -117,7 +106,6 @@ from nucypher.utilities.networking import validate_operator_ip class Alice(Character, BlockchainPolicyAuthor): banner = ALICE_BANNER - _interface_class = AliceInterface _default_crypto_powerups = [SigningPower, DecryptingPower, DelegatingPower] def __init__(self, @@ -142,12 +130,10 @@ class Alice(Character, BlockchainPolicyAuthor): # Policy Storage store_policy_credentials: bool = None, - store_character_cards: bool = None, # Middleware timeout: int = 10, # seconds # TODO: configure NRN network_middleware: RestMiddleware = None, - controller: bool = True, *args, **kwargs) -> None: @@ -192,8 +178,6 @@ class Alice(Character, BlockchainPolicyAuthor): self.log = Logger(self.__class__.__name__) if is_me: - if controller: - self.make_cli_controller() # Policy Payment if federated_only and not payment_method: @@ -209,15 +193,9 @@ class Alice(Character, BlockchainPolicyAuthor): self.active_policies = dict() self.revocation_kits = dict() self.store_policy_credentials = store_policy_credentials - self.store_character_cards = store_character_cards self.log.info(self.banner) - def get_card(self) -> 'Card': - from nucypher.policy.identity import Card - card = Card.from_character(self) - return card - def add_active_policy(self, active_policy): """ Adds a Policy object that is active on the NuCypher network to Alice's @@ -453,74 +431,9 @@ class Alice(Character, BlockchainPolicyAuthor): # Shouldn't it be able to take a list of them too? return [cleartext] - def make_web_controller(drone_alice, crash_on_error: bool = False): - app_name = bytes(drone_alice.stamp).hex()[:6] - controller = WebController(app_name=app_name, - crash_on_error=crash_on_error, - interface=drone_alice._interface_class(character=drone_alice)) - drone_alice.controller = controller - - # Register Flask Decorator - alice_flask_control = controller.make_control_transport() - - # - # Character Control HTTP Endpoints - # - - @alice_flask_control.route('/public_keys', methods=['GET']) - def public_keys(): - """ - Character control endpoint for getting Alice's encrypting and signing public keys - """ - return controller(method_name='public_keys', control_request=request) - - @alice_flask_control.route("/create_policy", methods=['PUT']) - def create_policy() -> Response: - """ - Character control endpoint for creating an enacted network policy - """ - response = controller(method_name='create_policy', control_request=request) - return response - - @alice_flask_control.route("/decrypt", methods=['POST']) - def decrypt(): - """ - Character control endpoint for decryption of Alice's own policy data. - """ - response = controller(method_name='decrypt', control_request=request) - return response - - @alice_flask_control.route('/derive_policy_encrypting_key/