diff --git a/nucypher/characters/base.py b/nucypher/characters/base.py index 2c1e87b25..0920b6f3b 100644 --- a/nucypher/characters/base.py +++ b/nucypher/characters/base.py @@ -201,9 +201,7 @@ class Character(Learner): # # Character Control # - self._control_protocol = NO_CONTROL_PROTOCOL - self._wsgi_app = NO_WSGI_APP - self._captured_status_codes = NO_WSGI_APP + self.controller = NO_CONTROL_PROTOCOL def __eq__(self, other) -> bool: try: @@ -227,10 +225,6 @@ class Character(Learner): def name(self): return self.__class__.__name__ - @property - def control(self): - return self._control_protocol - @property def rest_interface(self): return self.rest_server.rest_url() diff --git a/nucypher/characters/lawful.py b/nucypher/characters/lawful.py index d1b5d6e01..d9e3cade8 100644 --- a/nucypher/characters/lawful.py +++ b/nucypher/characters/lawful.py @@ -38,7 +38,7 @@ from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve from cryptography.hazmat.primitives.serialization import Encoding from cryptography.x509 import load_pem_x509_certificate, Certificate, NameOID from eth_utils import to_checksum_address -from flask import Flask, request, Response +from flask import request, Response from twisted.internet import threads from twisted.logger import Logger from umbral.keys import UmbralPublicKey @@ -50,8 +50,8 @@ from nucypher.blockchain.eth.actors import PolicyAuthor, Miner from nucypher.blockchain.eth.agents import MinerAgent from nucypher.characters.banners import ALICE_BANNER, BOB_BANNER, ENRICO_BANNER, URSULA_BANNER from nucypher.characters.base import Character, Learner -from nucypher.characters.control.controllers import AliceJSONControl, BobJSONControl -from nucypher.characters.control.wsgi import WSGIController +from nucypher.characters.control.controllers import AliceJSONController, BobJSONController, EnricoJSONController, \ + WebController from nucypher.config.constants import GLOBAL_DOMAIN from nucypher.config.storages import NodeStorage, ForgetfulNodeStorage from nucypher.crypto.api import keccak_digest, encrypt_and_sign @@ -69,10 +69,10 @@ from nucypher.network.server import ProxyRESTServer, TLSHostingPower, make_rest_ from nucypher.utilities.decorators import validate_checksum_address -class Alice(Character, PolicyAuthor, WSGIController): +class Alice(Character, PolicyAuthor): banner = ALICE_BANNER - _default_controller_class = AliceJSONControl + _controller_class = AliceJSONController _default_crypto_powerups = [SigningPower, DecryptingPower, DelegatingPower] def __init__(self, @@ -95,12 +95,12 @@ class Alice(Character, PolicyAuthor, WSGIController): PolicyAuthor.__init__(self, checksum_address=checksum_address) if is_me and controller: - WSGIController.__init__(self, app_name='alice-control') + self.controller = self._controller_class(alice=self) self.log = Logger(self.__class__.__name__) self.log.info(self.banner) - def generate_kfrags(self, bob, label: bytes, m: int, n: int) -> List: + def generate_kfrags(self, bob: 'Bob', label: bytes, m: int, n: int) -> List: """ Generates re-encryption key frags ("KFrags") and returns them. @@ -226,20 +226,37 @@ class Alice(Character, PolicyAuthor, WSGIController): failed_revocations[node_id] = (revocation, UnexpectedResponse) return failed_revocations - def make_wsgi_app(drone_alice, *args, **kwargs): + def make_web_controller(drone_alice, crash_on_error: bool = False): - alice_control = super().make_wsgi_app() + app_name = bytes(drone_alice.stamp).hex()[:6] + controller = WebController(app_name=app_name, + character_contoller=drone_alice.controller, + crash_on_error=crash_on_error) + drone_alice.controller = controller + + # Register Flask Decorator + alice_control = controller.make_web_controller() + + # + # Character Control HTTP Endpoints + # + + @alice_control.route('/public_keys', methods=['GET']) + def public_keys(): + """ + Character control endpoint for getting Alice's encrypting and signing public keys + """ + return controller(interface=controller._internal_controller.public_keys, + control_request=request) @alice_control.route("/create_policy", methods=['PUT']) def create_policy() -> Response: """ Character control endpoint for creating a policy and making arrangements with Ursulas. - - TODO: This is an unfinished API endpoint. You are probably looking for grant. """ - response = drone_alice._handle_request(interface=drone_alice._control_protocol.create_policy, - control_request=request) + response = controller(interface=controller._internal_controller.create_policy, + control_request=request) return response @alice_control.route('/derive_policy/