async def _do_claim_device(initial_ctx): async with spinner( "Initializing connection with greeter for claiming device"): in_progress_ctx = await initial_ctx.do_wait_peer() choices = in_progress_ctx.generate_greeter_sas_choices(size=3) for i, choice in enumerate(choices): display_choice = click.style(choice, fg="yellow") click.echo(f" {i} - {display_choice}") code = await aprompt("Select code provided by greeter", type=click.Choice( [str(x) for x in range(len(choices))])) if choices[int(code)] != in_progress_ctx.greeter_sas: click.secho("Wrong code provided", fg="red") return None in_progress_ctx = await in_progress_ctx.do_signify_trust() display_claimer_sas = click.style(str(in_progress_ctx.claimer_sas), fg="yellow") click.echo(f"Code to provide to greeter: {display_claimer_sas}") async with spinner("Waiting for greeter"): in_progress_ctx = await in_progress_ctx.do_wait_peer_trust() requested_device_label = await aprompt("Device label", default=platform.node()) async with spinner("Waiting for greeter (finalizing)"): new_device = await in_progress_ctx.do_claim_device( requested_device_label=requested_device_label) return new_device
async def _do_greet_device(device, initial_ctx): async with spinner("Waiting for claimer"): in_progress_ctx = await initial_ctx.do_wait_peer() display_greeter_sas = click.style(str(in_progress_ctx.greeter_sas), fg="yellow") click.echo(f"Code to provide to claimer: {display_greeter_sas}") async with spinner("Waiting for claimer"): in_progress_ctx = await in_progress_ctx.do_wait_peer_trust() choices = in_progress_ctx.generate_claimer_sas_choices(size=3) for i, choice in enumerate(choices): display_choice = click.style(choice, fg="yellow") click.echo(f" {i} - {display_choice}") code = await aprompt("Select code provided by claimer", type=click.Choice( [str(x) for x in range(len(choices))])) if choices[int(code)] != in_progress_ctx.claimer_sas: click.secho("Wrong code provided", fg="red") return False async with spinner("Waiting for claimer"): in_progress_ctx = await in_progress_ctx.do_signify_trust() in_progress_ctx = await in_progress_ctx.do_get_claim_requests() granted_device_label = await aprompt( "New device label", default=in_progress_ctx.requested_device_label) async with spinner("Creating the device in the backend"): await in_progress_ctx.do_create_new_device( author=device, device_label=granted_device_label) return True
async def _do_greet_user(device, initial_ctx): async with spinner("Waiting for claimer"): in_progress_ctx = await initial_ctx.do_wait_peer() display_greeter_sas = click.style(str(in_progress_ctx.greeter_sas), fg="yellow") click.echo(f"Code to provide to claimer: {display_greeter_sas}") async with spinner("Waiting for claimer"): in_progress_ctx = await in_progress_ctx.do_wait_peer_trust() choices = in_progress_ctx.generate_claimer_sas_choices(size=3) for i, choice in enumerate(choices): display_choice = click.style(choice, fg="yellow") click.echo(f" {i} - {display_choice}") code = await aprompt( "Select code provided by claimer", type=click.Choice([str(i) for i, _ in enumerate(choices)]), ) if choices[int(code)] != in_progress_ctx.claimer_sas: click.secho("Wrong code provided", fg="red") return False async with spinner("Waiting for claimer"): in_progress_ctx = await in_progress_ctx.do_signify_trust() in_progress_ctx = await in_progress_ctx.do_get_claim_requests() granted_label = await aprompt( "New user label", default=in_progress_ctx.requested_human_handle.label) granted_email = await aprompt( "New user email", default=in_progress_ctx.requested_human_handle.email) granted_device_label = await aprompt( "New user device label", default=in_progress_ctx.requested_device_label) choices = list(UserProfile) for i, choice in enumerate(UserProfile): display_choice = click.style(choice.value, fg="yellow") click.echo(f" {i} - {display_choice}") choice_index = await aprompt("New user profile", default="0", type=click.Choice( [str(i) for i, _ in enumerate(choices)])) granted_profile = choices[int(choice_index)] async with spinner("Creating the user in the backend"): await in_progress_ctx.do_create_new_user( author=device, device_label=granted_device_label, human_handle=HumanHandle(email=granted_email, label=granted_label), profile=granted_profile, ) return True
async def _claim_invitation(config, addr, password): async with backend_invited_cmds_factory( addr=addr, keepalive=config.backend_connection_keepalive) as cmds: try: async with spinner("Retrieving invitation info"): initial_ctx = await claimer_retrieve_info(cmds) except BackendConnectionRefused: raise RuntimeError("Invitation not found") if initial_ctx.greeter_human_handle: display_greeter = click.style(str( initial_ctx.greeter_human_handle), fg="yellow") else: display_greeter = click.style(initial_ctx.greeter_user_id, fg="yellow") click.echo(f"Invitation greeter: {display_greeter}") while True: try: if isinstance(initial_ctx, DeviceClaimInitialCtx): new_device = await _do_claim_device(initial_ctx) else: assert isinstance(initial_ctx, UserClaimInitialCtx) new_device = await _do_claim_user(initial_ctx) if new_device: break except InviteError as exc: click.secho(str(exc), fg="red") click.secho("Restarting the invitation process", fg="red") device_display = click.style(new_device.slughash, fg="yellow") with operation(f"Saving device {device_display}"): save_device_with_password(config.config_dir, new_device, password)
async def _greet_invitation(config, device, token): async with backend_authenticated_cmds_factory( addr=device.organization_addr, device_id=device.device_id, signing_key=device.signing_key, keepalive=config.backend_connection_keepalive, ) as cmds: async with spinner("Retrieving invitation info"): rep = await cmds.invite_list() if rep["status"] != "ok": raise RuntimeError(f"Backend error: {rep}") for invitation in rep["invitations"]: if invitation["token"] == token: break else: raise RuntimeError("Invitation not found") if invitation["type"] == InvitationType.USER: initial_ctx = UserGreetInitialCtx(cmds=cmds, token=token) do_greet = partial(_do_greet_user, device, initial_ctx) else: assert invitation["type"] == InvitationType.DEVICE initial_ctx = DeviceGreetInitialCtx(cmds=cmds, token=token) do_greet = partial(_do_greet_device, device, initial_ctx) while True: try: greet_done = await do_greet() if greet_done: break except InviteError as exc: click.secho(str(exc), fg="red") click.secho("Restarting the invitation process", fg="red")
async def _migrate(db): async with spinner("Migrate"): result = await apply_migrations(db, db_first_tries_number, db_first_tries_sleep, migrations, dry_run) for migration in result.already_applied: click.secho(f"{migration.file_name} (already applied)", fg="white") for migration in result.new_apply: click.secho(f"{migration.file_name} {ok}", fg="green") if result.error: migration, msg = result.error click.secho(f"{migration.file_name} {ko}: {msg}", fg="red")
async def _create_organization(debug, name, backend_addr, administration_token, expiration_date): async with spinner("Creating group in backend"): async with apiv1_backend_administration_cmds_factory( backend_addr, administration_token) as cmds: rep = await cmds.organization_create(name, expiration_date) if rep["status"] != "ok": raise RuntimeError(f"Backend refused to create group: {rep}") bootstrap_token = rep["bootstrap_token"] organization_addr = BackendOrganizationBootstrapAddr.build( backend_addr, name, bootstrap_token) organization_addr_display = click.style(organization_addr.to_url(), fg="yellow") click.echo(f"Bootstrap group url: {organization_addr_display}")
async def _invite_device(config, device): async with spinner("Creating device invitation"): async with backend_authenticated_cmds_factory( addr=device.organization_addr, device_id=device.device_id, signing_key=device.signing_key, keepalive=config.backend_connection_keepalive, ) as cmds: rep = await cmds.invite_new(type=InvitationType.DEVICE) if rep["status"] != "ok": raise RuntimeError( f"Backend refused to create device invitation: {rep}") action_addr = BackendInvitationAddr.build( backend_addr=device.organization_addr, organization_id=device.organization_id, invitation_type=InvitationType.DEVICE, token=rep["token"], ) action_addr_display = click.style(action_addr.to_url(), fg="yellow") click.echo(f"url: {action_addr_display}")