import datetime import maya from nucypher.characters.lawful import Bob from nucypher.config.characters import AliceConfiguration from nucypher.config.constants import TEMPORARY_DOMAIN_NAME from nucypher.crypto.powers import DecryptingPower, SigningPower from tests.constants import INSECURE_DEVELOPMENT_PASSWORD, MOCK_ETH_PROVIDER_URI from tests.utils.middleware import MockRestMiddleware def test_alices_powers_are_persistent(ursulas, temp_dir_path, accounts): # Create a non-learning AliceConfiguration config_root = temp_dir_path / 'nucypher-custom-alice-config' alice_config = AliceConfiguration( eth_endpoint=MOCK_ETH_PROVIDER_URI, config_root=config_root, network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI), domain=TEMPORARY_DOMAIN_NAME, checksum_address=accounts.alice_account, start_learning_now=False, save_metadata=False, reload_metadata=False, known_nodes=ursulas, ) # Generate keys and write them the disk alice_config.initialize(password=INSECURE_DEVELOPMENT_PASSWORD) # Unlock Alice's keystore alice_config.keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) # Produce an Alice alice = alice_config() # or alice_config.produce() # Save Alice's node configuration file to disk for later use alice_config_file = alice_config.to_configuration_file() # Let's save Alice's public keys too to check they are correctly restored later alices_verifying_key = alice.public_keys(SigningPower) alices_receiving_key = alice.public_keys(DecryptingPower) # Next, let's fix a label for all the policies we will create later. label = b"this_is_the_path_to_which_access_is_being_granted" # Even before creating the policies, we can know what will be its public key. # This can be used by Enrico (i.e., a Data Source) to encrypt messages # before Alice grants access to Bobs. policy_pubkey = alice.get_policy_encrypting_key_from_label(label) # Now, let's create a policy for some Bob. threshold, shares = 3, 4 policy_end_datetime = maya.now() + datetime.timedelta(days=5) bob = Bob( start_learning_now=False, domain=TEMPORARY_DOMAIN_NAME, eth_endpoint=MOCK_ETH_PROVIDER_URI, network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI), ) bob_policy = alice.grant(bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime) assert policy_pubkey == bob_policy.public_key # ... and Alice and her configuration disappear. alice.disenchant() del alice del alice_config ################################### # Some time passes. # # ... # # (jmyles plays the Song of Time) # # ... # # Alice appears again. # ################################### # A new Alice is restored from the configuration file new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI), start_learning_now=False, config_root=config_root, known_nodes=ursulas, ) # Alice unlocks her restored keystore from disk new_alice_config.keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) new_alice = new_alice_config() # First, we check that her public keys are correctly restored assert alices_verifying_key == new_alice.public_keys(SigningPower) assert alices_receiving_key == new_alice.public_keys(DecryptingPower) # Bob's eldest brother, Roberto, appears too roberto = Bob( domain=TEMPORARY_DOMAIN_NAME, eth_endpoint=MOCK_ETH_PROVIDER_URI, start_learning_now=False, network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI), ) # Alice creates a new policy for Roberto. Note how all the parameters # except for the label (i.e., recipient, m, n, policy_end) are different # from previous policy threshold, shares = 2, 5 policy_end_datetime = maya.now() + datetime.timedelta(days=3) roberto_policy = new_alice.grant(roberto, label, threshold=threshold, shares=shares, expiration=policy_end_datetime) # Both policies must share the same public key (i.e., the policy public key) assert policy_pubkey == roberto_policy.public_key new_alice.disenchant()