示例#1
0
async def _do_get_organization_stats(core: LoggedCore) -> OrganizationStats:
    try:
        return await core.get_organization_stats()
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc
    except BackendConnectionError as exc:
        raise JobResultError("error") from exc
示例#2
0
async def _do_list_devices(core):
    try:
        return await core.get_user_devices_info()
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc
    except BackendConnectionError as exc:
        raise JobResultError("error") from exc
 async def _create_new_device(self, device_label, file_path, passphrase):
     try:
         recovery_device = await load_recovery_device(file_path, passphrase)
         new_device = await generate_new_device_from_recovery(
             recovery_device, device_label)
         return new_device
     except LocalDeviceError as exc:
         self.button_validate.setEnabled(True)
         if "Decryption failed" in str(exc):
             show_error(self,
                        translate("TEXT_IMPORT_KEY_WRONG_PASSPHRASE"),
                        exception=exc)
         else:
             show_error(self,
                        translate("IMPORT_KEY_LOCAL_DEVICE_ERROR"),
                        exception=exc)
         raise JobResultError("error") from exc
     except BackendNotAvailable as exc:
         show_error(self,
                    translate("IMPORT_KEY_BACKEND_OFFLINE"),
                    exception=exc)
         raise JobResultError("backend-error") from exc
     except BackendConnectionError as exc:
         show_error(self,
                    translate("IMPORT_KEY_BACKEND_ERROR"),
                    exception=exc)
         raise JobResultError("backend-error") from exc
     except Exception as exc:
         show_error(self, translate("IMPORT_KEY_ERROR"), exception=exc)
         raise JobResultError("error") from exc
示例#4
0
async def _do_cancel_invitation(core, token):
    try:
        await core.delete_invitation(token=token)
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc
    except BackendConnectionError as exc:
        raise JobResultError("error") from exc
 async def _export_recovery_device(self, config_dir, device, export_path):
     try:
         recovery_device = await generate_recovery_device(device)
         file_name = get_recovery_device_file_name(recovery_device)
         file_path = export_path / file_name
         passphrase = await save_recovery_device(file_path, recovery_device)
         return recovery_device, file_path, passphrase
     except BackendNotAvailable as exc:
         show_error(self,
                    translate("EXPORT_KEY_BACKEND_OFFLINE"),
                    exception=exc)
         raise JobResultError("backend-error") from exc
     except BackendConnectionError as exc:
         show_error(self,
                    translate("EXPORT_KEY_BACKEND_ERROR"),
                    exception=exc)
         raise JobResultError("backend-error") from exc
     except LocalDeviceAlreadyExistsError as exc:
         show_error(self,
                    translate("TEXT_RECOVERY_DEVICE_FILE_ALREADY_EXISTS"),
                    exception=exc)
         raise JobResultError("already-exists") from exc
     except Exception as exc:
         show_error(self, translate("EXPORT_KEY_ERROR"), exception=exc)
         raise JobResultError("error") from exc
     self.button_validate.setEnabled(True)
示例#6
0
async def _do_list_users_and_invitations(core,
                                         page,
                                         pattern=None,
                                         omit_revoked=False,
                                         omit_invitation=False):
    try:
        if not pattern:
            users, total = await core.find_humans(page=page,
                                                  per_page=USERS_PER_PAGE,
                                                  omit_revoked=omit_revoked)
            invitations = [] if omit_invitation else await core.list_invitations(
            )
            return total, users, [
                inv for inv in invitations
                if inv["type"] == InvitationType.USER
            ]
        else:
            users, total = await core.find_humans(page=page,
                                                  per_page=USERS_PER_PAGE,
                                                  query=pattern,
                                                  omit_revoked=omit_revoked)
            return total, users, []
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc

    except BackendConnectionError as exc:
        raise JobResultError("error") from exc
示例#7
0
async def _do_revoke_user(core, user_info):
    try:
        await core.revoke_user(user_info.user_id)
        user_info = await core.get_user_info(user_info.user_id)
        return user_info
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc
    except BackendConnectionError as exc:
        raise JobResultError("error") from exc
示例#8
0
async def _do_invite_device(core):
    try:
        addr, email_sent_status = await core.new_device_invitation(
            send_email=False)
        return addr, email_sent_status
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc
    except BackendConnectionError as exc:
        raise JobResultError("error") from exc
示例#9
0
    async def _do_import(self, sources: Iterable[str], dest: FsPath) -> None:
        # The file list is used in the error handler
        files = []
        try:
            # Get the list of files to import with the corresponding size
            files, total_size = await self._get_files_from_sources(
                sources, dest)

            # Make the job cancellable
            with trio.CancelScope() as cancel_scope:

                # Create loading dialog and connect to the cancel scope
                wl = LoadingWidget(total_size=total_size + len(files))
                loading_dialog = GreyedDialog(
                    wl, _("TEXT_FILE_IMPORT_LOADING_TITLE"), parent=self)
                wl.cancelled.connect(cancel_scope.cancel)

                # Control the visibility andl life-cyle of the loading dialog
                try:
                    loading_dialog.show()

                    # Actually perform the import
                    errors = await self._import_all(files, loading_dialog)

                finally:
                    loading_dialog.hide()
                    loading_dialog.setParent(None)

                # Process the errors
                if errors:
                    text = (_("TEXT_FILE_IMPORT_ONE_PERMISSION_ERROR")
                            if len(files) == 1 else
                            _("TEXT_FILE_IMPORT_MULTIPLE_PERMISSION_ERROR"))
                    show_error(self, text, exception=errors[0])
                    raise JobResultError("error", exceptions=errors)

            if cancel_scope.cancel_called:
                raise JobResultError("cancelled")

        # Propagate job result errors
        except JobResultError:
            raise

        # Disk full
        except FSLocalStorageOperationalError as exc:
            text = _("TEXT_FILE_IMPORT_LOCAL_STORAGE_ERROR")
            show_error(self, text, exception=exc)
            raise JobResultError("error") from exc

        # Show a dialog when an unexpected error occurs
        except Exception as exc:
            text = (_("TEXT_FILE_IMPORT_ONE_ERROR") if len(files) == 1 else
                    _("TEXT_FILE_IMPORT_MULTIPLE_ERROR"))
            show_error(self, text, exception=exc)
            raise
示例#10
0
async def _do_rename(workspace_fs, paths):
    new_names = {}
    for (old_path, new_path, entry_id) in paths:
        try:
            await workspace_fs.rename(old_path, new_path)
            new_names[entry_id] = FsPath(new_path).name
        except FileExistsError as exc:
            raise JobResultError("already-exists",
                                 multi=len(paths) > 1) from exc
        except OSError as exc:
            raise JobResultError("not-empty", multi=len(paths) > 1) from exc
示例#11
0
async def _do_invite_user(core, email):
    try:
        invitation_addr, email_sent_status = await core.new_user_invitation(
            email=email, send_email=True)
        return email, invitation_addr, email_sent_status
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc
    except BackendInvitationOnExistingMember as exc:
        raise JobResultError("already_member") from exc
    except BackendConnectionError as exc:
        raise JobResultError("error") from exc
示例#12
0
async def _do_workspace_rename(core, workspace_id, new_name, button):
    try:
        new_name = EntryName(new_name)
    except ValueError:
        # This should never occurs given new_name is checked by a validator in the GUI
        # TODO: improve this logic ?
        raise JobResultError("invalid-name")
    try:
        await core.user_fs.workspace_rename(workspace_id, new_name)
        return button, new_name
    except Exception as exc:
        raise JobResultError("rename-error") from exc
示例#13
0
 async def claim_device(self, device_label: DeviceLabel) -> LocalDevice:
     await self.main_oob_send.send(self.Step.ClaimDevice)
     await self.main_oob_send.send(device_label)
     r, exc, new_device = await self.job_oob_recv.receive()
     if not r:
         raise JobResultError(status="claim-device-failed", origin=exc)
     return new_device
示例#14
0
 async def create_new_user(self, human_handle: HumanHandle,
                           device_label: DeviceLabel,
                           profile: UserProfile) -> None:
     await self.main_mc_send.send(self.Step.CreateNewUser)
     await self.main_mc_send.send((human_handle, device_label, profile))
     r, exc = await self.job_mc_recv.receive()
     if not r:
         raise JobResultError(status="create-new-user-failed", origin=exc)
示例#15
0
 async def claim_user(self, device_label: DeviceLabel,
                      human_handle: HumanHandle):
     await self.main_oob_send.send(self.Step.ClaimUser)
     await self.main_oob_send.send((device_label, human_handle))
     r, exc, new_device = await self.job_oob_recv.receive()
     if not r:
         raise JobResultError(status="claim-user-failed", origin=exc)
     return new_device
示例#16
0
async def _do_workspace_create(core, workspace_name):
    try:
        workspace_name = EntryName(workspace_name)
    except ValueError:
        # This should never occurs given new_name is checked by a validator in the GUI
        # TODO: improve this logic ?
        raise JobResultError("invalid-name")
    workspace_id = await core.user_fs.workspace_create(workspace_name)
    return workspace_id
示例#17
0
 def _handle_fs_errors():
     try:
         yield
     except FSBackendOfflineError as exc:
         raise JobResultError(ret=workspace_id,
                              status="offline-backend",
                              origin=exc)
     except FSWorkspaceNoAccess as exc:
         raise JobResultError(ret=workspace_id,
                              status="access-error",
                              origin=exc)
     except FSWorkspaceNotFoundError as exc:
         raise JobResultError(ret=workspace_id,
                              status="not-found",
                              origin=exc)
     except FSError as exc:
         raise JobResultError(ret=workspace_id,
                              status="fs-error",
                              origin=exc)
示例#18
0
async def _do_delete(workspace_fs, files, silent=False):
    for path, file_type in files:
        try:
            if file_type == FileType.Folder:
                await workspace_fs.rmtree(path)
            else:
                await workspace_fs.unlink(path)
        except Exception as exc:
            if not silent:
                raise JobResultError("error", multi=len(files) > 1) from exc
示例#19
0
async def _do_create_org(
    config,
    human_handle: HumanHandle,
    device_label: DeviceLabel,
    backend_addr: BackendOrganizationBootstrapAddr,
):
    try:
        new_device = await bootstrap_organization(backend_addr,
                                                  human_handle=human_handle,
                                                  device_label=device_label)
        # The organization is brand new, of course there is no existing
        # remote user manifest, hence our placeholder is non-speculative.
        await user_storage_non_speculative_init(
            data_base_dir=config.data_base_dir, device=new_device)
        return new_device
    except InviteNotFoundError as exc:
        raise JobResultError("invite-not-found", exc=exc)
    except InviteAlreadyUsedError as exc:
        raise JobResultError("invite-already-used", exc=exc)
    except BackendConnectionRefused as exc:
        raise JobResultError("connection-refused", exc=exc)
    except BackendNotAvailable as exc:
        raise JobResultError("connection-error", exc=exc)
    except BackendOutOfBallparkError as exc:
        raise JobResultError("out-of-ballpark", exc=exc)
    except InviteError as exc:
        raise JobResultError("invite-error", exc=exc)
示例#20
0
    async def run(self, core, token):
        try:
            r = await self.main_mc_recv.receive()

            assert r == self.Step.WaitPeer
            try:
                in_progress_ctx = await core.start_greeting_device(token=token)
                await self.job_mc_send.send((True, None))
            except Exception as exc:
                await self.job_mc_send.send((False, exc))

            r = await self.main_mc_recv.receive()

            assert r == self.Step.GetGreeterSas
            await self.job_mc_send.send(in_progress_ctx.greeter_sas)

            r = await self.main_mc_recv.receive()

            assert r == self.Step.WaitPeerTrust
            try:
                in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()
                await self.job_mc_send.send((True, None))
            except Exception as exc:
                await self.job_mc_send.send((False, exc))

            r = await self.main_mc_recv.receive()

            assert r == self.Step.GetClaimerSas
            try:
                choices = in_progress_ctx.generate_claimer_sas_choices(size=4)
                await self.job_mc_send.send(
                    (True, None, in_progress_ctx.claimer_sas, choices))
            except Exception as exc:
                await self.job_mc_send.send((False, exc, None, None))

            r = await self.main_mc_recv.receive()

            assert r == self.Step.SignifyTrust
            try:
                in_progress_ctx = await in_progress_ctx.do_signify_trust()
                in_progress_ctx = await in_progress_ctx.do_get_claim_requests()
                await in_progress_ctx.do_create_new_device(
                    author=core.device,
                    device_label=in_progress_ctx.requested_device_label)
                await self.job_mc_send.send((True, None))
            except InviteError as exc:
                await self.job_mc_send.send((False, exc))
            except Exception as exc:
                await self.job_mc_send.send((False, exc))

        except BackendNotAvailable as exc:
            raise JobResultError(status="backend-not-available", origin=exc)
示例#21
0
async def _do_share_workspace(user_fs, workspace_fs, user_info, role):
    workspace_name = workspace_fs.get_workspace_name()

    try:
        await user_fs.workspace_share(workspace_fs.workspace_id, user_info.user_id, role)
        return user_info, role, workspace_name
    except ValueError as exc:
        raise JobResultError(
            "invalid-user", user_info=user_info, role=role, workspace_name=workspace_name
        ) from exc
    except FSBackendOfflineError as exc:
        raise JobResultError(
            "offline", user_info=user_info, role=role, workspace_name=workspace_name
        ) from exc
    except FSError as exc:
        raise JobResultError(
            "fs-error", user_info=user_info, role=role, workspace_name=workspace_name
        ) from exc
    except Exception as exc:
        raise JobResultError(
            "error", user_info=user_info, role=role, workspace_name=workspace_name
        ) from exc
示例#22
0
async def _do_copy_files(workspace_fs, target_dir, source_files,
                         source_workspace):
    last_exc = None
    error_count = 0
    for src, src_type in source_files:
        # In order to be able to rename the file if a file of the same name already exists
        # we need the name without extensions.
        name_we, *_ = src.name.str.split(".", 1)
        count = 2
        file_name = src.name
        while True:
            try:
                dst = target_dir / file_name
                if src_type == FileType.Folder:
                    await workspace_fs.copytree(src, dst, source_workspace)
                else:
                    await workspace_fs.copyfile(src, dst, source_workspace)
                break
            except FileExistsError:
                # File already exists, we append a counter at the end of its name
                file_name = EntryName("{} ({}){}".format(
                    name_we, count,
                    "".join(pathlib.Path(src.name.str).suffixes)))
                count += 1
            except FSInvalidArgumentError as exc:
                # Move a file onto itself
                # Not a big deal for files, we just do nothing and pretend we
                # actually did something
                # For folders we have to warn the user
                if src_type == FileType.Folder:
                    error_count += 1
                    last_exc = exc
                break
            except Exception as exc:
                # No idea what happened, we'll just warn the user that we encountered an
                # unexcepted error and log it
                error_count += 1
                last_exc = exc
                logger.exception("Unhandled error while cut/copy file",
                                 exc_info=exc)
                break
    if error_count:
        raise JobResultError("error",
                             last_exc=last_exc,
                             error_count=error_count)
示例#23
0
async def _do_get_users(core, workspace_fs):
    ret = {}
    try:
        participants = await workspace_fs.get_user_roles()
        updated_participants = {}
        for user, role in participants.items():
            user_info = await core.get_user_info(user)
            updated_participants[user_info] = role
        # TODO: handle pagination
        users, _ = await core.find_humans()

        for user_info, role in updated_participants.items():
            ret[user_info] = role
        for user_info in users:
            if user_info not in ret:
                ret[user_info] = NOT_SHARED_KEY
        return ret
    except BackendNotAvailable as exc:
        raise JobResultError("offline") from exc
示例#24
0
 async def get_claim_requests(self):
     await self.main_mc_send.send(self.Step.GetClaimRequests)
     r, exc, human_handle, device_label = await self.job_mc_recv.receive()
     if not r:
         raise JobResultError(status="get-claim-request-failed", origin=exc)
     return human_handle, device_label
示例#25
0
 async def signify_trust(self):
     await self.main_mc_send.send(self.Step.SignifyTrust)
     r, exc = await self.job_mc_recv.receive()
     if not r:
         raise JobResultError(status="signify-trust-failed", origin=exc)
示例#26
0
 async def get_claimer_sas(self):
     await self.main_mc_send.send(self.Step.GetClaimerSas)
     r, exc, claimer_sas, choices = await self.job_mc_recv.receive()
     if not r:
         raise JobResultError(status="get-claimer-sas-failed", origin=exc)
     return claimer_sas, choices
示例#27
0
 async def wait_peer_trust(self):
     await self.main_mc_send.send(self.Step.WaitPeerTrust)
     r, exc = await self.job_mc_recv.receive()
     if not r:
         raise JobResultError(status="wait-peer-trust-failed", origin=exc)
示例#28
0
    async def run(self, addr, config):
        try:
            async with backend_invited_cmds_factory(
                    addr=addr,
                    keepalive=config.backend_connection_keepalive) as cmds:
                # Trigger handshake
                await cmds.ping()
                r = await self.main_oob_recv.receive()

                assert r == self.Step.RetrieveInfo
                try:
                    initial_ctx = await claimer_retrieve_info(cmds)
                    await self.job_oob_send.send(
                        (True, None, initial_ctx.claimer_email))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.WaitPeer
                try:
                    in_progress_ctx = await initial_ctx.do_wait_peer()
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.GetGreeterSas
                try:
                    choices = in_progress_ctx.generate_greeter_sas_choices(
                        size=4)
                    await self.job_oob_send.send(
                        (True, None, in_progress_ctx.greeter_sas, choices))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None, None))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.SignifyTrust
                try:
                    in_progress_ctx = await in_progress_ctx.do_signify_trust()
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.GetClaimerSas
                await self.job_oob_send.send(in_progress_ctx.claimer_sas)

                r = await self.main_oob_recv.receive()

                assert r == self.Step.WaitPeerTrust
                try:
                    in_progress_ctx = await in_progress_ctx.do_wait_peer_trust(
                    )
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()
                assert r == self.Step.ClaimUser

                try:
                    device_label, human_handle = await self.main_oob_recv.receive(
                    )

                    new_device = await in_progress_ctx.do_claim_user(
                        requested_device_label=device_label,
                        requested_human_handle=human_handle)
                    # Claiming a user means we are it first device, hence we know there
                    # is no existing user manifest (hence our placeholder is non-speculative)
                    await user_storage_non_speculative_init(
                        data_base_dir=config.data_base_dir, device=new_device)
                    await self.job_oob_send.send((True, None, new_device))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None))
        except BackendNotAvailable as exc:
            raise JobResultError(status="backend-not-available", origin=exc)
        except BackendInvitationAlreadyUsed as exc:
            raise JobResultError(status="invitation-already-used", origin=exc)
        except BackendConnectionRefused as exc:
            raise JobResultError(status="invitation-not-found", origin=exc)
        except BackendOutOfBallparkError as exc:
            raise JobResultError(status="out-of-ballpark", origin=exc)
示例#29
0
 async def get_greeter_sas(self):
     await self.main_oob_send.send(self.Step.GetGreeterSas)
     r, exc, greeter_sas, choices = await self.job_oob_recv.receive()
     if not r:
         raise JobResultError(status="get-greeter-sas-failed", origin=exc)
     return greeter_sas, choices
示例#30
0
 async def wait_peer(self):
     await self.main_oob_send.send(self.Step.WaitPeer)
     r, exc = await self.job_oob_recv.receive()
     if not r:
         raise JobResultError(status="wait-peer-failed", origin=exc)