Пример #1
0
    def __init__(self, jobs_ctx, claimer):
        super().__init__()
        self.setupUi(self)
        self.claimer = claimer
        self.jobs_ctx = jobs_ctx

        self.signify_trust_job = None
        self.wait_peer_trust_job = None
        self.get_greeter_sas_job = None
        self.get_claimer_sas_job = None

        self.widget_claimer_code.hide()

        font = self.line_edit_claimer_code.font()
        font.setBold(True)
        font.setLetterSpacing(QFont.PercentageSpacing, 180)
        self.line_edit_claimer_code.setFont(font)

        self.code_input_widget.good_code_clicked.connect(self._on_good_greeter_code_clicked)
        self.code_input_widget.wrong_code_clicked.connect(self._on_wrong_greeter_code_clicked)
        self.code_input_widget.none_clicked.connect(self._on_none_clicked)

        self.get_greeter_sas_success.connect(self._on_get_greeter_sas_success)
        self.get_greeter_sas_error.connect(self._on_get_greeter_sas_error)
        self.get_claimer_sas_success.connect(self._on_get_claimer_sas_success)
        self.get_claimer_sas_error.connect(self._on_get_claimer_sas_error)
        self.signify_trust_success.connect(self._on_signify_trust_success)
        self.signify_trust_error.connect(self._on_signify_trust_error)
        self.wait_peer_trust_success.connect(self._on_wait_peer_trust_success)
        self.wait_peer_trust_error.connect(self._on_wait_peer_trust_error)

        self.get_greeter_sas_job = self.jobs_ctx.submit_job(
            ThreadSafeQtSignal(self, "get_greeter_sas_success", QtToTrioJob),
            ThreadSafeQtSignal(self, "get_greeter_sas_error", QtToTrioJob),
            self.claimer.get_greeter_sas,
        )
    def on_share_clicked(self):
        user_name = self.line_edit_share.text()
        if not user_name:
            return
        if user_name == self.core.device.user_id:
            show_info(self, _("TEXT_WORKSPACE_SHARING_CANNOT_SHARE_WITH_YOURSELF"))
            return
        for i in range(self.scroll_content.layout().count()):
            item = self.scroll_content.layout().itemAt(i)
            if item and item.widget() and item.widget().user == user_name:
                show_info(
                    self, _("TEXT_WORKSPACE_SHARING_ALREADY_SHARED_user").format(user=user_name)
                )
                return

        self.jobs_ctx.submit_job(
            ThreadSafeQtSignal(self, "share_success", QtToTrioJob),
            ThreadSafeQtSignal(self, "share_error", QtToTrioJob),
            _do_share_workspace,
            user_fs=self.user_fs,
            workspace_fs=self.workspace_fs,
            user=user_name,
            role=_index_to_role(self.combo_role.currentIndex()),
        )
Пример #3
0
    def reencrypt_workspace(self, workspace_id, user_revoked, role_revoked,
                            reencryption_already_in_progress):
        if workspace_id in self.reencrypting or (
                not user_revoked and not role_revoked
                and not reencryption_already_in_progress):
            return

        question = ""
        if user_revoked:
            question += "{}\n".format(
                _("TEXT_WORKSPACE_NEED_REENCRYPTION_BECAUSE_USER_REVOKED"))
        if role_revoked:
            question += "{}\n".format(
                _("TEXT_WORKSPACE_NEED_REENCRYPTION_BECAUSE_USER_REMOVED"))
        question += _("TEXT_WORKSPACE_NEED_REENCRYPTION_INSTRUCTIONS")

        r = ask_question(
            self,
            _("TEXT_WORKSPACE_NEED_REENCRYPTION_TITLE"),
            question,
            [_("ACTION_WORKSPACE_REENCRYPTION_CONFIRM"),
             _("ACTION_CANCEL")],
        )
        if r != _("ACTION_WORKSPACE_REENCRYPTION_CONFIRM"):
            return

        @contextmanager
        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)

        async def _reencrypt(on_progress, workspace_id):
            with _handle_fs_errors():
                if reencryption_already_in_progress:
                    job = await self.core.user_fs.workspace_continue_reencryption(
                        workspace_id)
                else:
                    job = await self.core.user_fs.workspace_start_reencryption(
                        workspace_id)
            while True:
                with _handle_fs_errors():
                    total, done = await job.do_one_batch()
                on_progress.emit(workspace_id, total, done)
                if total == done:
                    break
            return workspace_id

        self.reencrypting.add(workspace_id)

        self.jobs_ctx.submit_job(
            ThreadSafeQtSignal(self, "workspace_reencryption_success",
                               QtToTrioJob),
            ThreadSafeQtSignal(self, "workspace_reencryption_error",
                               QtToTrioJob),
            _reencrypt,
            on_progress=ThreadSafeQtSignal(self,
                                           "workspace_reencryption_progress",
                                           EntryID, int, int),
            workspace_id=workspace_id,
        )
Пример #4
0
    def on_list_success(self, job):
        # Hide the spinner in case it was visible
        self.spinner.hide()
        workspaces = job.ret

        # Use temporary dict to update the workspace mapping
        new_mapping = {}
        old_mapping = dict(self.workspace_button_mapping)

        # Loop over the resulting workspaces
        for workspace_fs, workspace_name, ws_entry, users_roles, files, timestamped in workspaces:

            # Pop button from existing mapping
            key = (workspace_fs.workspace_id, getattr(workspace_fs, "timestamp", None))
            button = old_mapping.pop(key, None)

            # Create and bind button if it doesn't exist
            if button is None:
                button = WorkspaceButton(workspace_fs)
                button.clicked.connect(self.load_workspace)
                if self.core.device.is_outsider:
                    button.button_share.hide()
                else:
                    button.share_clicked.connect(self.share_workspace)
                button.reencrypt_clicked.connect(self.reencrypt_workspace)
                button.delete_clicked.connect(self.delete_workspace)
                button.rename_clicked.connect(self.rename_workspace)
                button.remount_ts_clicked.connect(self.remount_workspace_ts)
                button.open_clicked.connect(self.open_workspace)
                button.switch_clicked.connect(self._on_switch_clicked)

            # Apply new state
            button.apply_state(
                workspace_name=workspace_name,
                workspace_fs=workspace_fs,
                users_roles=users_roles,
                is_mounted=self.is_workspace_mounted(workspace_fs.workspace_id, None),
                files=files[:4],
                timestamped=timestamped,
            )

            # Use this opportunity to trigger the `get_reencryption_needs` routine
            if button.is_owner:
                try:
                    self.jobs_ctx.submit_job(
                        ThreadSafeQtSignal(self, "reencryption_needs_success", QtToTrioJob),
                        ThreadSafeQtSignal(self, "reencryption_needs_error", QtToTrioJob),
                        _get_reencryption_needs,
                        workspace_fs=workspace_fs,
                    )
                except JobSchedulerNotAvailable:
                    pass

            # Add the button to the new mapping
            # Note that the order of insertion matters as it corresponds to the order in which
            # the workspaces are displayed.
            new_mapping[key] = button

        # Set the new mapping
        self.workspace_button_mapping = new_mapping

        # Refresh the layout, taking the filtering into account
        self.refresh_workspace_layout()

        # Dereference the old buttons
        for button in old_mapping.values():
            button.setParent(None)