def authorize( ctx: CliCtx, ssh_user_id: Optional[str], device_user_ids: List[str], device_user_all: bool, device_state_ons: List[str], device_state_always: bool, force: bool ) -> None: """Authorize a single *ssh user* to *device user(s)*.""" user_id = ensure_ssh_user_id_or_fallback_or_fail( ssh_user_id, ctx.user_id) dus = select_auth_device_users_where( ctx.repo, device_user_ids, device_user_all, device_state_ons, device_state_always) try: for du in dus: try: du.authorize_user_by_id(user_id, force=force) except SshAuthRepoUserAlreadyAuthorizedError: echo_warning( f"User '{user_id}' already authorized to *device user* " f"'{du.formatted_name}'. on '{du.formatted_state_name}' state. " "Skipping.") except SshAuthRepoInvalidUserError as e: raise CliError(str(e)) from e except SshUsersRepoAccessError as e: raise CliError(str(e)) from e
def authorize( ctx: CliCtx, ssh_group_id: str, device_user_ids: List[str], device_user_all: bool, device_state_ons: List[str], device_state_always: bool, force: bool ) -> None: """Authorize a *ssh group* to *device user(s)*.""" dus = select_auth_device_users_where( ctx.repo, device_user_ids, device_user_all, device_state_ons, device_state_always) try: for du in dus: try: du.authorize_group_by_id( ssh_group_id, force=force) except SshAuthRepoGroupAlreadyAuthorizedError: echo_warning( f"Group '{ssh_group_id}' already authorized to *device user* " f"'{du.formatted_name}'. on '{du.formatted_state_name}' state. " "Skipping.") except SshAuthRepoInvalidGroupError as e: raise CliError(str(e)) from e except SshGroupsRepoAccessError as e: raise CliError(str(e)) from e
def deauthorize( ctx: CliCtx, ssh_group_id: str, device_user_ids: List[str], device_user_all: bool, device_state_ons: List[str], device_state_always: bool, force: bool ) -> None: """De-authorize a *ssh group* from *device user(s)*.""" if (not device_user_ids and not device_user_all and not device_state_ons and not device_state_always): deauthorize_group_from_all_auth_device_users(ctx.repo, ssh_group_id) return dus = select_auth_device_users_where( ctx.repo, device_user_ids, device_user_all, device_state_ons, device_state_always) for du in dus: try: du.deauthorize_group_by_id( ssh_group_id, force=force) except SshAuthRepoKeyAccessError: echo_warning( f"Group '{ssh_group_id}' already not authorized to *device user* " f"'{du.formatted_name}' on '{du.formatted_state_name}' state. " "Skipping.") except SshAuthRepoInvalidGroupError as e: raise CliError(str(e)) from e
def _set(ctx: CliCtx, ssh_user_id: Optional[str], ssh_pubkey: Optional[str]) -> None: """Set a new *ssh public key* for the specified user. SSH_PUBKEY: The ssh public key. '-': Will read the pubkey from stdin. ValidPath: Will read pubkey from the specified file. NotAValidPath: Will assume the key was passed as input. Unspecified: In case the SSH_USER_ID is not specified, will assume the current user and read the ssh key directly from '~/.ssh/id_rsa.pub'. Otherwise, will attempt to copy it from the clipboard. """ pubkey = ensure_ssh_pubkey_or_fallback_or_fail(ssh_pubkey, ssh_user_id, ctx.user_id) user_id = ensure_ssh_user_id_or_fallback_or_fail(ssh_user_id, ctx.user_id) try: ctx.repo.users[user_id].pubkey_default = pubkey except (SshUsersRepoFileAccessError, SshUsersRepoKeyAccessError) as e: raise CliError(str(e)) from e
def ls(ctx: CliCtx, ssh_group_id: str) -> None: """List members for specified *ssh group*.""" try: for m_name in ctx.repo.groups[ssh_group_id].members_names: click.echo(m_name) except SshGroupsRepoAccessError as e: raise CliError(str(e)) from e
def ls(ctx: CliCtx) -> None: """List existing *ssh group*.""" try: for g_name in ctx.repo.groups.names: click.echo(g_name) except SshGroupsRepoAccessError as e: raise CliError(str(e)) from e
def deauthorize( ctx: CliCtx, ssh_user_id: Optional[str], device_user_ids: List[str], device_user_all: bool, device_state_ons: List[str], device_state_always: bool, force: bool ) -> None: """De-authorize a single *ssh user* from *device user(s)*.""" user_id = ensure_ssh_user_id_or_fallback_or_fail( ssh_user_id, ctx.user_id) if (not device_user_ids and not device_user_all and not device_state_ons and not device_state_always): deauthorize_user_from_all_auth_device_users(ctx.repo, user_id) return dus = select_auth_device_users_where( ctx.repo, device_user_ids, device_user_all, device_state_ons, device_state_always) for du in dus: try: du.deauthorize_user_by_id(user_id, force=force) except SshAuthRepoKeyAccessError: echo_warning( f"User '{user_id}' already not authorized to *device user* " f"'{du.formatted_name}' on '{du.formatted_state_name}' state. " "Skipping.") except SshAuthRepoInvalidUserError as e: raise CliError(str(e)) from e
def ls(ctx: CliCtx) -> None: """List existing *ssh user*.""" repo = ctx.repo try: for uname in repo.users.names: click.echo(uname) except SshUsersRepoFileAccessError as e: raise CliError(str(e)) from e
def add( ctx: CliCtx, ssh_group_id: str, force: bool ) -> None: """Add a new *ssh group*.""" try: ctx.repo.groups.add( ssh_group_id, exist_ok=force) except SshGroupsRepoDuplicateError as e: raise CliError(str(e)) from e
def rm( ctx: CliCtx, ssh_group_id: str, ssh_group_member_id: str, force: bool ) -> None: """Remove a *ssh user* from a *ssh group*.""" try: ctx.repo.groups[ssh_group_id].rm_member_by_id( ssh_group_member_id, force=force) except SshGroupsRepoAccessError as e: raise CliError(str(e)) from e
def print(ctx: CliCtx, ssh_user_id: Optional[str]) -> None: """Print the current *ssh public key* for the specified user.""" ssh_user_id = ensure_ssh_user_id_or_fallback_or_fail( ssh_user_id, ctx.user_id) repo = ctx.repo try: pk = repo.users[ssh_user_id].pubkey_default for l in pk.text_lines: click.echo(l.rstrip("\n")) except (SshUsersRepoFileAccessError, SshUsersRepoKeyAccessError) as e: raise CliError(str(e)) from e
def rm( ctx: CliCtx, ssh_group_id: str, force: bool ) -> None: """Remove and existing *ssh group*.""" deauthorize_group_from_all_auth_device_users(ctx.repo, ssh_group_id) try: ctx.repo.groups.rm(ssh_group_id) except SshGroupsRepoAccessError as e: if not force: raise CliError(str(e)) from e
def add( ctx: CliCtx, ssh_group_id: str, ssh_user_id: Optional[str], force: bool ) -> None: """Add a *ssh user* to a *ssh group*.""" user_id = ensure_ssh_user_id_or_fallback_or_fail( ssh_user_id, ctx.user_id) try: ctx.repo.groups[ssh_group_id].add_member_by_id( user_id, force=force) except (SshGroupsRepoAccessError, SshGroupsRepoDuplicateError) as e: raise CliError(str(e)) from e
def rm( ctx: CliCtx, ssh_user_id: Optional[str], force: bool ) -> None: """Remove an existing *ssh user*.""" user_id = ensure_ssh_user_id_or_fallback_or_fail( ssh_user_id, ctx.user_id) # Ensure the user exists before proceeding. try: ctx.repo.users.rm(user_id) except SshUsersRepoAccessError as e: if not force: raise CliError(str(e)) from e deauthorize_user_from_all_auth_device_users( ctx.repo, user_id, force=True) rm_user_from_all_groups(ctx.repo, user_id, force=True) try: ctx.repo.users.rm(user_id, force=force) except (SshUsersRepoFileAccessError, SshUsersRepoKeyAccessError) as e: raise CliError(str(e)) from e
def add( ctx: CliCtx, ssh_user_id: Optional[str], ssh_pubkey: Optional[str], user_group_ids: List[str], force: bool ) -> None: """Add a new *ssh user*. SSH_USER_ID: The textual id to give to this user. Ideally, use character that can be used in filesystem / url. No whitespaces either. SSH_PUBKEY: The ssh public key. '-': Will read the pubkey from stdin. ValidPath: Will read pubkey from the specified file. NotAValidPath: Will assume the key was passed as input. Unspecified: In case the SSH_USER_ID is not specified, will assume the current user and read the ssh key directly from '~/.ssh/id_rsa.pub'. Otherwise, will attempt to copy it from the clipboard. Use '-f/--force' to prevent the user already exists error and allow for automatic missing group creation (combined with '-g/--group'). """ user_id = ensure_ssh_user_id_or_fallback_or_fail( ssh_user_id, ctx.user_id) pubkey = ensure_ssh_pubkey_or_fallback_or_fail( ssh_pubkey, ssh_user_id, ctx.user_id) try: ctx.repo.users.add( user_id, pubkey, exist_ok=force) except SshUsersRepoDuplicateError as e: raise CliError(str(e)) from e add_user_to_groups( ctx.repo, user_id, user_group_ids, force=force )
def info(ctx: CliCtx, ssh_user_id: Optional[str]) -> None: """Print information about the *ssh public key* for the specified user.""" ssh_user_id = ensure_ssh_user_id_or_fallback_or_fail( ssh_user_id, ctx.user_id) repo = ctx.repo try: try: pk_selected_fn_str = str( repo.users[ssh_user_id].pubkeys.selected_filename) except SshUserPubkeysRepoAccessError: pk_selected_fn_str = "null" click.echo(f"{ssh_user_id}.pubkey.selected: " f"'{pk_selected_fn_str}'") try: pk_default_fn_str = str( repo.users[ssh_user_id].pubkeys.default_filename) except SshUserPubkeysRepoAccessError: pk_default_fn_str = "null" click.echo(f"{ssh_user_id}.pubkey.default: " f"'{pk_default_fn_str}'") except (SshUsersRepoFileAccessError, SshUsersRepoKeyAccessError) as e: raise CliError(str(e)) from e
def add_user_to_groups( repo: SshAuthDirRepo, user_id: str, group_ids: Iterable[str], force: bool) -> None: errors: List[Tuple[str, Exception]] = [] for gid in group_ids: if force: repo.groups.ensure(gid).add_member_by_id( user_id, force=force) else: try: repo.groups[gid].add_member_by_id(user_id) except (SshGroupsRepoAccessError, SshGroupsRepoDuplicateError) as e: errors.append((gid, e)) for gid, error in errors: echo_error(f"Error adding user to '{gid}':\n {str(error)}") if errors: raise CliError( f"Was unable to add '{user_id}' to some of the" "specified groups. See previous log for more details.")