def grant(general_config, bob, bob_encrypting_key, bob_verifying_key, label, value, rate, expiration, threshold, shares, character_options, config_file, force): """Create and enact an access policy for Bob.""" # Setup emitter = setup_emitter(general_config) ALICE = character_options.create_character( emitter=emitter, config_file=config_file, json_ipc=general_config.json_ipc) validate_grant_command(emitter=emitter, alice=ALICE, force=force, bob=bob, label=label, rate=rate, value=value, expiration=expiration, bob_encrypting_key=bob_encrypting_key, bob_verifying_key=bob_verifying_key) # Collect bob_public_keys = collect_bob_public_keys( emitter=emitter, force=force, card_identifier=bob, bob_encrypting_key=bob_encrypting_key, bob_verifying_key=bob_verifying_key) policy = collect_policy_parameters( emitter=emitter, alice=ALICE, force=force, bob_identifier=bob_public_keys.verifying_key[:8], label=label, threshold=threshold, shares=shares, rate=rate, value=value, expiration=expiration) grant_request = { 'bob_encrypting_key': bob_public_keys.encrypting_key, 'bob_verifying_key': bob_public_keys.verifying_key, 'label': policy.label, 'threshold': policy.threshold, 'shares': policy.shares, 'expiration': policy.expiration, } if not ALICE.federated_only: # These values can be 0 if policy.value is not None: grant_request['value'] = policy.value elif policy.rate is not None: grant_request['rate'] = policy.rate # in wei # Grant if not force and not general_config.json_ipc: confirm_staged_grant( emitter=emitter, grant_request=grant_request, federated=ALICE.federated_only, seconds_per_period=(None if ALICE.federated_only else ALICE.economics.seconds_per_period)) emitter.echo(f'Granting Access to {bob_public_keys.verifying_key[:8]}', color='yellow') return ALICE.controller.grant(request=grant_request)
def grant(general_config, bob, bob_encrypting_key, bob_verifying_key, label, value, rate, expiration, m, n, character_options, config_file, force): """Create and enact an access policy for some Bob. """ # Setup emitter = setup_emitter(general_config) ALICE = character_options.create_character(emitter, config_file, general_config.json_ipc) # Policy option validation if ALICE.federated_only: if any((value, rate)): message = "Can't use --value or --rate with a federated Alice." raise click.BadOptionUsage(option_name="--value, --rate", message=message) elif bool(value) and bool(rate): raise click.BadOptionUsage(option_name="--rate", message="Can't use --value if using --rate") # Grantee selection if bob and any((bob_encrypting_key, bob_verifying_key)): message = '--bob cannot be used with --bob-encrypting-key or --bob-veryfying key' raise click.BadOptionUsage(option_name='--bob', message=message) if bob: card = Card.load(identifier=bob) if card.character is not Bob: emitter.error('Grantee card is not a Bob.') raise click.Abort paint_single_card(emitter=emitter, card=card) if not force: click.confirm('Is this the correct grantee (Bob)?', abort=True) bob_encrypting_key = card.encrypting_key.hex() bob_verifying_key = card.verifying_key.hex() # Interactive collection follows: # TODO: Extricate to support modules # - Disclaimer # - Label # - Expiration Date & Time # - M of N # - Policy Value (ETH) # Policy Expiration # TODO: Remove this line when the time is right. paint_probationary_period_disclaimer(emitter) # Label if not label: label = click.prompt(f'Enter label to grant Bob {bob_verifying_key[:8]}', type=click.STRING) if not force and not expiration: if ALICE.duration_periods: # TODO: use a default in days or periods? expiration = maya.now() + timedelta(days=ALICE.duration_periods) # default if not click.confirm(f'Use default policy duration (expires {expiration})?'): expiration = click.prompt('Enter policy expiration datetime', type=click.DateTime()) else: # No policy duration default default available; Go interactive expiration = click.prompt('Enter policy expiration datetime', type=click.DateTime()) # TODO: Remove this line when the time is right. enforce_probationary_period(emitter=emitter, expiration=expiration) # Policy Threshold and Shares if not n: n = ALICE.n if not force and not click.confirm(f'Use default value for N ({n})?', default=True): n = click.prompt('Enter total number of shares (N)', type=click.INT) if not m: m = ALICE.m if not force and not click.confirm(f'Use default value for M ({m})?', default=True): m = click.prompt('Enter threshold (M)', type=click.IntRange(1, n)) # Policy Value policy_value_provided = bool(value) or bool(rate) if not ALICE.federated_only and not policy_value_provided: rate = ALICE.default_rate # TODO #1709 - Fine tuning and selection of default rates if not force: default_gwei = Web3.fromWei(rate, 'gwei') prompt = "Confirm rate of {node_rate} gwei ({total_rate} gwei per period)?" if not click.confirm(prompt.format(node_rate=default_gwei, total_rate=default_gwei*n), default=True): interactive_rate = click.prompt('Enter rate per period in gwei', type=GWEI) # TODO: Validate interactively collected rate (#1709) click.confirm(prompt.format(node_rate=rate, total_rate=rate*n), default=True, abort=True) rate = Web3.toWei(interactive_rate, 'gwei') # Request grant_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, 'expiration': expiration, } if not ALICE.federated_only: if value: grant_request['value'] = value elif rate: grant_request['rate'] = rate # in wei if not force and not general_config.json_ipc: confirm_staged_grant(emitter=emitter, grant_request=grant_request) emitter.echo(f'Granting Access to {bob_verifying_key[:8]}', color='yellow') return ALICE.controller.grant(request=grant_request)