Пример #1
0
    async def _finalize_enrollment(self, context):
        try:
            context = await context.finalize()
        except PkiEnrollmentCertificateNotFoundError:
            # Nothing to do, the user cancelled the certificate selection prompt
            return
        except PkiEnrollmentCertificatePinCodeUnavailableError:
            # Nothing to do, the user cancelled the pin code prompt
            return
        except Exception as exc:
            show_error(self,
                       _("TEXT_ENROLLMENT_CANNOT_FINALIZE"),
                       exception=exc)
            return

        try:
            await save_device_with_smartcard_in_config(
                config_dir=self.config.config_dir,
                device=context.new_device,
                certificate_id=context.x509_certificate.certificate_id,
                certificate_sha1=context.x509_certificate.certificate_sha1,
            )
        except Exception as exc:
            show_error(self, _("TEXT_CANNOT_SAVE_DEVICE"), exception=exc)
            return

        await self._remove_enrollment(context)
        SnackbarManager.inform(_("TEXT_CLAIM_DEVICE_SUCCESSFUL"))
Пример #2
0
 def on_list_error(self, job):
     status = job.status
     if status == "offline":
         return
     else:
         errmsg = _("TEXT_USER_LIST_RETRIEVABLE_FAILURE")
     show_error(self, errmsg, exception=job.exc)
Пример #3
0
    def on_claim_error(self):
        assert self.claim_user_job
        assert self.claim_user_job.is_finished()
        assert self.claim_user_job.status != "ok"

        status = self.claim_user_job.status
        if status != "cancelled":
            if status == "not_found":
                errmsg = _("TEXT_CLAIM_USER_NOT_FOUND")
            elif status == "password-mismatch":
                errmsg = _("TEXT_CLAIM_USER_PASSWORD_MISMATCH")
            elif status == "password-size":
                errmsg = _("TEXT_CLAIM_USER_PASSWORD_COMPLEXITY")
            elif status == "bad-url":
                errmsg = _("TEXT_CLAIM_USER_INVALID_URL")
            elif status == "bad-device_name":
                errmsg = _("TEXT_CLAIM_USER_BAD_DEVICE_NAME")
            elif status == "bad-user_id":
                errmsg = _("TEXT_CLAIM_USER_BAD_USER_NAME")
            elif status == "refused-by-backend":
                errmsg = _("TEXT_CLAIM_USER_BACKEND_REFUSAL")
            elif status == "backend-offline":
                errmsg = _("TEXT_CLAIM_USER_BACKEND_OFFLINE")
            else:
                errmsg = _("TEXT_CLAIM_USER_UNKNOWN_FAILURE")
            show_error(self, errmsg, exception=self.claim_user_job.exc)
        self.claim_user_job = None
        self.check_infos()
Пример #4
0
 def go_to_file_link(self, action_addr):
     for idx in range(self.tab_center.count()):
         if self.tab_center.tabText(idx) == _("TEXT_TAB_TITLE_LOG_IN_SCREEN"):
             continue
         w = self.tab_center.widget(idx)
         if (
             not w
             or not w.core
             or w.core.device.organization_addr.organization_id != action_addr.organization_id
         ):
             continue
         user_manifest = w.core.user_fs.get_user_manifest()
         for wk in user_manifest.workspaces:
             if not wk.role:
                 continue
             if wk.id != action_addr.workspace_id:
                 continue
             central_widget = w.get_central_widget()
             try:
                 central_widget.show_mount_widget()
                 central_widget.mount_widget.show_files_widget(
                     w.core.user_fs.get_workspace(wk.id), action_addr.path, selected=True
                 )
                 self.switch_to_tab(idx)
             except AttributeError:
                 logger.exception("Central widget is not available")
             return
     show_error(
         self,
         _("TEXT_FILE_LINK_NOT_FOUND_organization").format(
             organization=action_addr.organization_id
         ),
     )
Пример #5
0
    def _on_req_error(self):
        assert self.req_job
        assert self.req_job.is_finished()
        assert self.req_job.status != "ok"

        status = self.req_job.status

        if status == "cancelled":
            return

        errmsg = None
        if status == "email_already_exists":
            errmsg = _("TEXT_ORG_WIZARD_EMAIL_ALREADY_EXISTS")
        elif status == "organization_already_exists":
            errmsg = _("TEXT_ORG_WIZARD_ORGANIZATION_ALREADY_EXISTS")
        elif status == "invalid_email":
            errmsg = _("TEXT_ORG_WIZARD_INVALID_EMAIL")
        elif status == "invalid_organization_id":
            errmsg = _("TEXT_ORG_WIZARD_INVALID_ORGANIZATION_ID")
        elif status == "invalid_response":
            errmsg = _("TEXT_ORG_WIZARD_INVALID_RESPONSE")
        elif status == "offline":
            errmsg = _("TEXT_ORG_WIZARD_OFFLINE")
        else:
            errmsg = _("TEXT_ORG_WIZARD_UNKNOWN_FAILURE")
        exc = self.req_job.exc
        if exc.params.get("exc"):
            exc = exc.params.get("exc")
        show_error(self, errmsg, exception=exc)
        self.req_job = None
        self.button_validate.setEnabled(True)
        self.button_previous.show()
 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
Пример #7
0
 async def prepare_enrollment_request(self):
     try:
         self.context = await PkiEnrollmentSubmitterInitialCtx.new(self.addr
                                                                   )
         self.widget_user_info.setVisible(True)
         self.label_cert_error.setVisible(False)
         self.line_edit_user_name.setText(
             self.context.x509_certificate.subject_common_name)
         self.line_edit_user_email.setText(
             self.context.x509_certificate.subject_email_address)
         self.line_edit_device.setText(desktop.get_default_device())
         self.button_select_cert.setText(
             str(self.context.x509_certificate.certificate_id))
     except PkiEnrollmentCertificateNotFoundError:
         # User did not provide a certificate (cancelled the prompt). We do nothing.
         pass
     except PkiEnrollmentCertificatePinCodeUnavailableError:
         # User did not provide a pin code (cancelled the prompt). We do nothing.
         pass
     except Exception as exc:
         show_error(self,
                    translate("TEXT_ENROLLMENT_ERROR_LOADING_CERTIFICATE"),
                    exception=exc)
         self.widget_user_info.setVisible(False)
         self.label_cert_error.setText(
             translate("TEXT_ENROLLMENT_ERROR_LOADING_CERTIFICATE"))
         self.label_cert_error.setVisible(True)
         self.button_ask_to_join.setEnabled(False)
Пример #8
0
    def _on_claim_device_clicked(self, action_addr=None):
        if not action_addr:
            url = get_text_input(
                parent=self,
                title=_("TEXT_CLAIM_DEVICE_URL_TITLE"),
                message=_("TEXT_CLAIM_DEVICE_URL_INSTRUCTIONS"),
                placeholder=_("TEXT_CLAIM_DEVICE_URL_PLACEHOLDER"),
            )
            if url is None:
                return
            elif url == "":
                show_error(self, _("TEXT_CLAIM_DEVICE_INVALID_URL"))
                return

            action_addr = None
            try:
                action_addr = BackendOrganizationClaimDeviceAddr.from_url(url)
            except ValueError as exc:
                show_error(self, _("TEXT_CLAIM_DEVICE_INVALID_URL"), exception=exc)
                return
        ret = ClaimDeviceWidget.exec_modal(
            jobs_ctx=self.jobs_ctx, config=self.config, addr=action_addr, parent=self
        )
        if ret:
            self.reload_login_devices()
Пример #9
0
 def _on_claim_clicked(self):
     # No try/except given `self.line_edit_device` has already been validated against `DeviceLabel`
     device_label = DeviceLabel(
         validators.trim_user_name(self.line_edit_device.text()))
     try:
         user_name = validators.trim_user_name(
             self.line_edit_user_full_name.text())
         human_handle = HumanHandle(email=self.line_edit_user_email.text(),
                                    label=user_name)
         device_label = DeviceLabel(self.line_edit_device.text())
     except ValueError as exc:
         show_error(self,
                    _("TEXT_CLAIM_USER_INVALID_HUMAN_HANDLE"),
                    exception=exc)
         return
     self.button_ok.setDisabled(True)
     self.widget_info.setDisabled(True)
     self.label_wait.show()
     self.claim_job = self.jobs_ctx.submit_job(
         self.claim_success,
         self.claim_error,
         self.claimer.claim_user,
         device_label=device_label,
         human_handle=human_handle,
     )
Пример #10
0
 def _on_create_user_clicked(self):
     assert not self.create_user_job
     handle = None
     # No try/except given `self.line_edit_device` has already been validated against `DeviceLabel`
     device_label = DeviceLabel(
         validators.trim_user_name(self.line_edit_device.text()))
     try:
         user_name = validators.trim_user_name(
             self.line_edit_user_full_name.text())
         handle = HumanHandle(label=user_name,
                              email=self.line_edit_user_email.text())
     except ValueError as exc:
         show_error(self,
                    _("TEXT_GREET_USER_INVALID_HUMAN_HANDLE"),
                    exception=exc)
         return
     self.button_create_user.setDisabled(True)
     self.button_create_user.setText(_("TEXT_GREET_USER_WAITING"))
     self.create_user_job = self.jobs_ctx.submit_job(
         self.create_user_success,
         self.create_user_error,
         self.greeter.create_new_user,
         human_handle=handle,
         device_label=device_label,
         profile=self.combo_profile.currentData(),
     )
Пример #11
0
    def login_with_password(self, key_file, password):
        message = None
        exception = None
        try:
            device = load_device_with_password(key_file, password)
            if ParsecApp.is_device_connected(
                device.organization_addr.organization_id, device.device_id
            ):
                message = _("TEXT_LOGIN_ERROR_ALREADY_CONNECTED")
            else:
                self.start_core(device)
        except LocalDeviceError as exc:
            message = _("TEXT_LOGIN_ERROR_AUTHENTICATION_FAILED")
            exception = exc

        except (RuntimeError, MountpointConfigurationError, MountpointDriverCrash) as exc:
            message = _("TEXT_LOGIN_MOUNTPOINT_ERROR")
            exception = exc

        except Exception as exc:
            message = _("TEXT_LOGIN_UNKNOWN_ERROR")
            exception = exc
            logger.exception("Unhandled error during login")
        finally:
            if message:
                show_error(self, message, exception=exception)
                self.login_failed.emit()
Пример #12
0
 def _on_rename_error(self, job):
     if job.exc.params.get("multi"):
         show_error(self,
                    _("TEXT_FILE_RENAME_MULTIPLE_ERROR"),
                    exception=job.exc)
     else:
         show_error(self, _("TEXT_FILE_RENAME_ERROR"), exception=job.exc)
Пример #13
0
 def on_get_version_error(self):
     if self.versions_job and self.versions_job.status != "cancelled":
         show_error(self,
                    _("TEXT_FILE_HISTORY_LIST_FAILURE"),
                    exception=self.versions_job.exc)
     self.versions_job = None
     self.dialog.reject()
Пример #14
0
 async def login_with_smartcard(self, key_file):
     message = None
     exception = None
     try:
         device = await load_device_with_smartcard(key_file)
         if ParsecApp.is_device_connected(
             device.organization_addr.organization_id, device.device_id
         ):
             message = _("TEXT_LOGIN_ERROR_ALREADY_CONNECTED")
         else:
             self.start_core(device)
     except LocalDeviceCertificatePinCodeUnavailableError:
         # User cancelled the prompt
         self.login_failed.emit()
     except LocalDeviceError as exc:
         message = _("TEXT_LOGIN_ERROR_AUTHENTICATION_FAILED")
         exception = exc
     except ModuleNotFoundError as exc:
         message = _("TEXT_LOGIN_SMARTCARD_NOT_AVAILABLE")
         exception = exc
     except (RuntimeError, MountpointConfigurationError, MountpointDriverCrash) as exc:
         message = _("TEXT_LOGIN_MOUNTPOINT_ERROR")
         exception = exc
     except Exception as exc:
         message = _("TEXT_LOGIN_UNKNOWN_ERROR")
         exception = exc
         logger.exception("Unhandled error during login")
     finally:
         if message:
             show_error(self, message, exception=exception)
             self.login_failed.emit()
Пример #15
0
    def goto_file_clicked(self):
        file_link = get_text_input(
            self,
            _("TEXT_WORKSPACE_GOTO_FILE_LINK_TITLE"),
            _("TEXT_WORKSPACE_GOTO_FILE_LINK_INSTRUCTIONS"),
            placeholder=_("TEXT_WORKSPACE_GOTO_FILE_LINK_PLACEHOLDER"),
            default_text="",
            button_text=_("ACTION_GOTO_FILE_LINK"),
        )
        if not file_link:
            return

        url = None
        try:
            url = BackendOrganizationFileLinkAddr.from_url(file_link)
        except ValueError as exc:
            show_error(self,
                       _("TEXT_WORKSPACE_GOTO_FILE_LINK_INVALID_LINK"),
                       exception=exc)
            return

        for widget in self._iter_workspace_buttons():
            if widget.workspace_fs.workspace_id == url.workspace_id:
                self.load_workspace(widget.workspace_fs,
                                    path=url.path,
                                    selected=True)
                return
        show_error(self,
                   _("TEXT_WORKSPACE_GOTO_FILE_LINK_WORKSPACE_NOT_FOUND"))
Пример #16
0
    def add_instance(self, start_arg: Optional[str] = None) -> None:
        action_addr = None
        if start_arg:
            try:
                action_addr = BackendActionAddr.from_url(start_arg, allow_http_redirection=True)
            except ValueError as exc:
                show_error(self, _("TEXT_INVALID_URL"), exception=exc)

        self.show_top()
        if not action_addr:
            self.switch_to_login_tab()
        elif isinstance(action_addr, BackendOrganizationFileLinkAddr):
            self.go_to_file_link(action_addr)
        elif isinstance(action_addr, BackendOrganizationBootstrapAddr):
            self.show_create_org_widget(action_addr)
        elif (
            isinstance(action_addr, BackendInvitationAddr)
            and action_addr.invitation_type == InvitationType.USER
        ):
            self.show_claim_user_widget(action_addr)
        elif (
            isinstance(action_addr, BackendInvitationAddr)
            and action_addr.invitation_type == InvitationType.DEVICE
        ):
            self.show_claim_device_widget(action_addr)
        else:
            show_error(self, _("TEXT_INVALID_URL"))
Пример #17
0
    def _on_import_key(self):
        key_file, _ = QFileDialog.getOpenFileName(
            parent=self,
            caption=translate("ACTION_IMPORT_KEY"),
            filter=translate("IMPORT_KEY_FILTERS"),
            initialFilter=translate("IMPORT_KEY_INITIAL_FILTER"),
        )
        if not key_file:
            return
        new_device = load_device_file(Path(key_file))
        if new_device is None:
            show_error(self, translate("TEXT_INVALID_DEVICE_KEY"))
            return
        rep = ask_question(
            parent=self,
            title=translate("ASK_IMPORT_KEY"),
            message=translate("TEXT_IMPORT_KEY_CONFIRM_organization-user-device").format(
                organization=new_device.organization_id,
                user=new_device.short_user_display,
                device=new_device.device_label,
            ),
            button_texts=(translate("ACTION_IMPORT_YES"), translate("ACTION_IMPORT_NO")),
        )
        if rep == translate("ACTION_IMPORT_YES"):
            key_name = new_device.slughash + ".keys"
            dest = get_devices_dir(self.config.config_dir).joinpath(key_name)
            if self._overwrite_key(dest):

                shutil.copyfile(
                    new_device.key_file_path,
                    os.path.join(get_devices_dir(self.config.config_dir), key_name),
                )
                self.reload_devices()
                self.key_imported.emit()
Пример #18
0
 def _on_claimer_error(self, job):
     assert job
     assert job.is_finished()
     assert job.status != "ok"
     # This callback can be called after the creation of a new claimer job in the case
     # of a restart, due to Qt signals being called later.
     if job.status == "cancelled":
         return
     # Safety net for concurrency issues
     if self.claimer_job is not job:
         return
     self.claimer_job = None
     msg = ""
     exc = None
     if job.status == "invitation-not-found":
         msg = _("TEXT_CLAIM_USER_INVITATION_NOT_FOUND")
     elif job.status == "invitation-already-used":
         msg = _("TEXT_INVITATION_ALREADY_USED")
     elif job.status == "backend-not-available":
         msg = _("TEXT_INVITATION_BACKEND_NOT_AVAILABLE")
     elif job.status == "out-of-ballpark":
         msg = _("TEXT_BACKEND_STATE_DESYNC")
     else:
         msg = _("TEXT_CLAIM_USER_UNKNOWN_ERROR")
     if job.exc:
         exc = job.exc.params.get("origin", None)
     show_error(self, msg, exception=exc)
     # No point in retrying since the claimer job itself failed, simply close the dialog
     self.dialog.reject()
Пример #19
0
    def add_instance(self, start_arg: Optional[str] = None):
        action_addr = None
        if start_arg:
            try:
                action_addr = BackendActionAddr.from_url(start_arg)
            except ValueError as exc:
                show_error(self, _("TEXT_INVALID_URL"), exception=exc)

        idx = self._get_login_tab_index()
        if idx != -1:
            self.switch_to_tab(idx)
        else:
            tab = self.add_new_tab()
            tab.show_login_widget()
            self.on_tab_state_changed(tab, "login")
            self.switch_to_tab(self.tab_center.count() - 1)
            idx = self.tab_center.count() - 1

        self.show_top()
        if action_addr and isinstance(action_addr, BackendOrganizationFileLinkAddr):
            self.go_to_file_link(action_addr)
        elif action_addr:
            if isinstance(action_addr, BackendOrganizationBootstrapAddr):
                self._on_bootstrap_org_clicked(action_addr)
            elif isinstance(action_addr, BackendOrganizationClaimUserAddr):
                self._on_claim_user_clicked(action_addr)
            elif isinstance(action_addr, BackendOrganizationClaimDeviceAddr):
                self._on_claim_device_clicked(action_addr)
Пример #20
0
    def _on_bootstrap_org_clicked(self, action_addr=None):
        if not action_addr:
            url = get_text_input(
                parent=self,
                title=_("TEXT_BOOTSTRAP_ORG_URL_TITLE"),
                message=_("TEXT_BOOTSTRAP_ORG_URL_INSTRUCTIONS"),
                placeholder=_("TEXT_BOOTSTRAP_ORG_URL_PLACEHOLDER"),
                validator=validators.BackendOrganizationBootstrapAddrValidator(),
            )
            if url is None:
                return
            elif url == "":
                show_error(self, _("TEXT_BOOTSTRAP_ORG_INVALID_URL"))
                return

            action_addr = None
            try:
                action_addr = BackendOrganizationBootstrapAddr.from_url(url)
            except ValueError as exc:
                show_error(self, _("TEXT_BOOTSTRAP_ORG_INVALID_URL"), exception=exc)
                return
        ret = BootstrapOrganizationWidget.exec_modal(
            jobs_ctx=self.jobs_ctx, config=self.config, addr=action_addr, parent=self
        )
        if ret:
            self.reload_login_devices()
            self.try_login(ret[0], ret[1])
Пример #21
0
    def on_registration_error(self):
        self.line_edit_token.setText("")
        self.line_edit_url.setText("")
        self.line_edit_user.setText("")
        self.widget_registration.hide()
        self.checkbox_is_admin.show()
        self.button_register.show()
        self.line_edit_username.show()

        if not self.registration_job:
            return
        assert self.registration_job.is_finished()

        status = self.registration_job.status
        if status == "cancelled":
            self.registration_job = None
            return

        if status == "registration-invite-bad-value":
            errmsg = _("TEXT_INVITE_USER_BAD_USER_NAME")
        elif status == "registration-invite-already-exists":
            errmsg = _("TEXT_INVITE_USER_ALREADY_EXISTS")
        elif status == "registration-invite-error":
            errmsg = _("TEXT_INVITE_USER_WRONG_PARAMETERS")
        elif status == "registration-invite-offline":
            errmsg = _("TEXT_INVITE_USER_HOST_OFFLINE")
        elif status == "registration-invite-timeout":
            errmsg = _("TEXT_INVITE_USER_TIMEOUT")
        else:
            errmsg = _("TEXT_INVITE_USER_UNKNOWN_FAILURE")
        show_error(self, errmsg, exception=self.registration_job.exc)
        self.registration_job = None
Пример #22
0
 def _on_finalize_clicked(self):
     password = self.widget_password.password
     try:
         save_device_with_password(self.config.config_dir, self.new_device, password)
         self.succeeded.emit(self.new_device, password)
     except LocalDeviceAlreadyExistsError as exc:
         show_error(self, _("TEXT_CLAIM_USER_DEVICE_ALREADY_EXISTS"), exception=exc)
         self.failed.emit(None)
Пример #23
0
    def open_error_large(self):
        exc = None
        try:
            1337 / 0
        except ZeroDivisionError as e:
            exc = e

        custom_dialogs.show_error(self, message=LARGE_TEXT, exception=exc)
Пример #24
0
    def open_error_small(self):
        exc = None
        try:
            1337 / 0
        except ZeroDivisionError as e:
            exc = e

        custom_dialogs.show_error(self, message=SMALL_TEXT, exception=exc)
Пример #25
0
    def _on_get_users_error(self, job):
        assert job.is_finished()
        assert job.status != "ok"

        if job.status == "offline":
            show_error(self, _("TEXT_WORKSPACE_SHARING_OFFLINE"))
        self.spinner.hide()
        self.widget_users.show()
Пример #26
0
 def on_mount_error(self, job):
     if isinstance(job.exc, MountpointError):
         workspace_id = job.arguments.get("workspace_id")
         timestamp = job.arguments.get("timestamp")
         wb = self.get_workspace_button(workspace_id, timestamp)
         if wb:
             wb.set_mountpoint_state(False)
         show_error(self, _("TEXT_WORKSPACE_CANNOT_MOUNT"), exception=job.exc)
 def _on_unshare_error(self, job):
     exc = job.exc
     show_error(
         self,
         _("TEXT_WORKSPACE_SHARING_UNSHARE_ERROR_workspace-user").format(
             workspace=exc.params.get("workspace_name"),
             user=exc.params.get("user")),
     )
Пример #28
0
 def on_rename_error(self, job):
     if job.status == "invalid-name":
         show_error(self,
                    _("TEXT_WORKSPACE_RENAME_INVALID_NAME"),
                    exception=job.exc)
     else:
         show_error(self,
                    _("TEXT_WORKSPACE_RENAME_UNKNOWN_ERROR"),
                    exception=job.exc)
Пример #29
0
 def _on_delete_error(self, job):
     if not getattr(job.exc, "params", None):
         return
     if job.exc.params.get("multi"):
         show_error(self,
                    _("TEXT_FILE_DELETE_MULTIPLE_ERROR"),
                    exception=job.exc)
     else:
         show_error(self, _("TEXT_FILE_DELETE_ERROR"), exception=job.exc)
Пример #30
0
    def _on_move_error(self, job):
        exc = job.exc
        if exc and isinstance(exc.params.get("last_exc", None),
                              FSInvalidArgumentError):
            show_error(self, _("TEXT_FILE_FOLDER_MOVED_INTO_ITSELF_ERROR"))
        else:
            show_error(self, _("TEXT_FILE_PASTE_ERROR"))

        self.reset()