Esempio n. 1
0
def test_load_bad_data(config_dir, alice):
    alice_key = get_default_key_file(config_dir, alice)
    alice_key.parent.mkdir(parents=True)
    alice_key.write_bytes(b"dummy")

    with pytest.raises(LocalDevicePackingError):
        load_device_with_password(alice_key, "S3Cr37")
Esempio n. 2
0
def test_change_password(config_dir, alice):
    old_password = "******"
    new_password = "******"

    save_device_with_password_in_config(config_dir, alice, old_password)
    key_file = get_key_file(config_dir, alice)

    change_device_password(key_file, old_password, new_password)

    alice_reloaded = load_device_with_password(key_file, new_password)
    assert alice == alice_reloaded

    with pytest.raises(LocalDeviceCryptoError):
        load_device_with_password(key_file, old_password)
Esempio n. 3
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()
Esempio n. 4
0
def test_password_save_and_load(path_exists, config_dir, alice):
    config_dir = config_dir if path_exists else config_dir / "dummy"
    save_device_with_password_in_config(config_dir, alice, "S3Cr37")

    key_file = get_key_file(config_dir, alice)
    alice_reloaded = load_device_with_password(key_file, "S3Cr37")
    assert alice == alice_reloaded
Esempio n. 5
0
    def wrapper(**kwargs):
        config = kwargs["config"]
        password = kwargs["password"]

        organization_id, device_id, slugname = kwargs["device"]
        devices = [
            (o, d, t, kf)
            for o, d, t, kf in list_available_devices(config.config_dir)
            if (not organization_id or o == organization_id) and d == device_id
        ]
        if not devices:
            raise SystemExit(f"Device `{slugname}` not found")
        elif len(devices) > 1:
            found = "\n".join([str(kf.parent) for *_, kf in devices])
            raise SystemExit(
                f"Multiple devices found for `{slugname}`:\n{found}")
        else:
            _, _, cipher, key_file = devices[0]

        try:
            if cipher != "password":
                raise SystemExit(
                    f"Device {slugname} is ciphered with {cipher}.")

            if password is None:
                password = click.prompt("password", hide_input=True)
            device = load_device_with_password(key_file, password)

        except LocalDeviceError as exc:
            raise SystemExit(f"Cannot load device {slugname}: {exc}")

        kwargs["device"] = device
        return fn(**kwargs)
Esempio n. 6
0
    def wrapper(**kwargs):
        config = kwargs["config"]
        password = kwargs["password"]
        device_slughash = kwargs.pop("device")

        all_available_devices = list_available_devices(config.config_dir)
        devices = []
        for device in all_available_devices:
            if device.slughash.startswith(device_slughash):
                devices.append(device)

        if not devices:
            raise SystemExit(
                f"Device `{device_slughash}` not found, available devices:\n"
                f"{format_available_devices(all_available_devices)}")
        elif len(devices) > 1:
            raise SystemExit(
                f"Multiple devices found for `{device_slughash}`:\n"
                f"{format_available_devices(devices)}")

        try:
            if password is None:
                password = click.prompt("password", hide_input=True)
            device = load_device_with_password(devices[0].key_file_path,
                                               password)

        except LocalDeviceError as exc:
            raise SystemExit(f"Cannot load device {device_slughash}: {exc}")

        kwargs["device"] = device
        return fn(**kwargs)
Esempio n. 7
0
def test_available_devices_slughash_uniqueness(organization_factory,
                                               local_device_factory,
                                               config_dir):
    def _to_available(device):
        return AvailableDevice(
            key_file_path=get_default_key_file(config_dir, device),
            organization_id=device.organization_id,
            device_id=device.device_id,
            human_handle=device.human_handle,
            device_label=device.device_label,
            slug=device.slug,
            type=DeviceFileType.PASSWORD,
        )

    def _assert_different_as_available(d1, d2):
        available_device_d1 = _to_available(d1)
        available_device_d2 = _to_available(d2)
        assert available_device_d1.slughash != available_device_d2.slughash
        # Make sure slughash is consistent between LocalDevice and AvailableDevice
        assert available_device_d1.slughash == d1.slughash
        assert available_device_d2.slughash == d2.slughash

    o1 = organization_factory("org1")
    o2 = organization_factory("org2")

    # Different user id
    o1u1d1 = local_device_factory("u1@d1", o1)
    o1u2d1 = local_device_factory("u2@d1", o1)
    _assert_different_as_available(o1u1d1, o1u2d1)

    # Different device name
    o1u1d2 = local_device_factory("u1@d2", o1)
    _assert_different_as_available(o1u1d1, o1u1d2)

    # Different organization id
    o2u1d1 = local_device_factory("u1@d1", o2)
    _assert_different_as_available(o1u1d1, o2u1d1)

    # Same organization_id, but different root verify key !
    dummy_key = SigningKey.generate().verify_key
    o1u1d1_bad_rvk = o1u1d1.evolve(
        organization_addr=o1u1d1.organization_addr.build(
            backend_addr=o1u1d1.organization_addr.get_backend_addr(),
            organization_id=o1u1d1.organization_addr.organization_id,
            root_verify_key=dummy_key,
        ))
    _assert_different_as_available(o1u1d1, o1u1d1_bad_rvk)

    # Finally make sure slughash is stable through save/load
    save_device_with_password_in_config(config_dir, o1u1d1, "S3Cr37")
    key_file = get_key_file(config_dir, o1u1d1)
    o1u1d1_reloaded = load_device_with_password(key_file, "S3Cr37")
    available_device = _to_available(o1u1d1)
    available_device_reloaded = _to_available(o1u1d1_reloaded)
    assert available_device.slughash == available_device_reloaded.slughash
Esempio n. 8
0
def test_same_device_id_different_orginazations(config_dir, alice, otheralice):
    devices = (alice, otheralice)

    for device in devices:
        save_device_with_password_in_config(
            config_dir, device, f"S3Cr37-{device.organization_id}")

    for device in devices:
        key_file = get_key_file(config_dir, device)
        device_reloaded = load_device_with_password(
            key_file, f"S3Cr37-{device.organization_id}")
        assert device == device_reloaded
Esempio n. 9
0
async def main():

    # Config
    config_dir = get_default_config_dir(os.environ)
    config = load_config(config_dir)
    devices = list_available_devices(config_dir)
    key_file = next(key_file for _, device_id, _, key_file in devices if device_id == DEVICE_ID)
    device = load_device_with_password(key_file, PASSWORD)

    # Log in
    async with logged_core_factory(config, device) as core:

        # Get workspace
        user_manifest = core.user_fs.get_user_manifest()
        workspace_entry = user_manifest.workspaces[0]
        workspace = core.user_fs.get_workspace(workspace_entry.id)

        # await make_workspace_dir_inconsistent(device, workspace, "/bar")
        await make_workspace_dir_simple_versions(device, workspace, "/foo")
Esempio n. 10
0
    async def show_modal(cls, core, jobs_ctx, parent, on_finished=None):
        available_device = get_available_device(core.config.config_dir,
                                                core.device)
        loaded_device = None

        try:
            if available_device.type == DeviceFileType.PASSWORD:
                password = get_text_input(
                    parent,
                    _("TEXT_DEVICE_UNLOCK_TITLE"),
                    _("TEXT_DEVICE_UNLOCK_FOR_AUTH_CHANGE_LABEL"),
                    placeholder="",
                    default_text="",
                    completion=None,
                    button_text=None,
                    validator=None,
                    hidden=True,
                )
                if not password:
                    return
                loaded_device = load_device_with_password(
                    available_device.key_file_path, password)
            else:
                loaded_device = await load_device_with_smartcard(
                    available_device.key_file_path)
        except LocalDeviceError:
            show_error(parent, _("TEXT_LOGIN_ERROR_AUTHENTICATION_FAILED"))
            return

        w = cls(core=core, jobs_ctx=jobs_ctx, loaded_device=loaded_device)
        d = GreyedDialog(w,
                         title=_("TEXT_CHANGE_AUTHENTICATION_TITLE"),
                         parent=parent)
        w.dialog = d

        if on_finished:
            d.finished.connect(on_finished)
        # Unlike exec_, show is asynchronous and works within the main Qt loop
        d.show()
        return w
    async def _on_validate_clicked(self):
        if isinstance(self.current_page, DeviceRecoveryExportPage1Widget):
            self.button_validate.setEnabled(False)
            selected_device = self.current_page.get_selected_device()
            save_path = self.current_page.get_save_path()
            device = None

            if isinstance(selected_device, LocalDevice):
                selected_device = get_available_device(self.config.config_dir,
                                                       selected_device)

            if selected_device.type == DeviceFileType.PASSWORD:
                password = get_text_input(
                    self,
                    translate("TEXT_DEVICE_UNLOCK_TITLE"),
                    translate("TEXT_DEVICE_UNLOCK_FOR_RECOVERY_LABEL"),
                    placeholder="",
                    default_text="",
                    completion=None,
                    button_text=None,
                    validator=None,
                    hidden=True,
                )
                if password is None:
                    self.button_validate.setEnabled(True)
                    return
                try:
                    device = load_device_with_password(
                        selected_device.key_file_path, password)
                except LocalDeviceError:
                    show_error(
                        self,
                        translate("TEXT_LOGIN_ERROR_AUTHENTICATION_FAILED"))
                    self.button_validate.setEnabled(True)
                    return
            elif selected_device.type == DeviceFileType.SMARTCARD:
                try:
                    device = await load_device_with_smartcard(
                        selected_device.key_file_path)
                except LocalDeviceError as exc:
                    show_error(
                        self,
                        translate("TEXT_LOGIN_ERROR_AUTHENTICATION_FAILED"),
                        exception=exc)
                    self.button_validate.setEnabled(True)
                    return
                except ModuleNotFoundError as exc:
                    show_error(
                        self,
                        translate("TEXT_UNLOCK_ERROR_SMARTCARD_NOT_AVAILABLE"),
                        exception=exc)
                    self.button_validate.setEnabled(True)
                    return
            self.jobs_ctx.submit_job(
                self.export_success,
                self.export_failure,
                self._export_recovery_device,
                config_dir=self.config.config_dir,
                device=device,
                export_path=save_path,
            )
        else:
            self.dialog.accept()
Esempio n. 12
0
def test_password_load_not_found(config_dir, alice):
    with pytest.raises(LocalDeviceNotFoundError):
        key_file = get_default_key_file(config_dir, alice)
        load_device_with_password(key_file, "S3Cr37")
Esempio n. 13
0
def test_load_bad_password(config_dir, alice):
    save_device_with_password_in_config(config_dir, alice, "S3Cr37")

    with pytest.raises(LocalDeviceCryptoError):
        key_file = get_key_file(config_dir, alice)
        load_device_with_password(key_file, "dummy")