예제 #1
0
def test_organization_id_user_id_and_device_name(raw):
    organization_id = OrganizationID(raw)
    assert str(organization_id) == raw
    assert organization_id == OrganizationID(raw)

    user_id = UserID(raw)
    assert str(user_id) == raw
    assert user_id == UserID(raw)

    device_name = DeviceName(raw)
    assert str(device_name) == raw
    assert device_name == DeviceName(raw)
예제 #2
0
def test_bad_organization_id_user_id_and_device_name(raw):
    with pytest.raises(ValueError):
        OrganizationID(raw)
    with pytest.raises(ValueError):
        UserID(raw)
    with pytest.raises(ValueError):
        DeviceName(raw)
예제 #3
0
    def _on_validate_clicked(self):
        backend_addr = None
        org_id = None
        device_name = None
        human_handle = None

        if self.start_addr:
            backend_addr = self.start_addr
        else:
            try:
                org_id = OrganizationID(
                    self.user_widget.line_edit_org_name.text())
            except ValueError as exc:
                show_error(self,
                           _("TEXT_ORG_WIZARD_INVALID_ORGANIZATION_ID"),
                           exception=exc)
                return
            try:
                backend_addr = BackendOrganizationBootstrapAddr.build(
                    backend_addr=self.user_widget.backend_addr
                    if self.user_widget.radio_use_custom.isChecked() else
                    self.config.preferred_org_creation_backend_addr,
                    organization_id=org_id,
                )
            except ValueError as exc:
                show_error(self,
                           _("TEXT_ORG_WIZARD_INVALID_BACKEND_ADDR"),
                           exception=exc)
                return
        try:
            device_name = DeviceName(
                self.device_widget.line_edit_device.text())
        except ValueError as exc:
            show_error(self,
                       _("TEXT_ORG_WIZARD_INVALID_DEVICE_NAME"),
                       exception=exc)
            return
        try:
            user_name = validators.trim_user_name(
                self.user_widget.line_edit_user_full_name.text())

            human_handle = HumanHandle(
                self.user_widget.line_edit_user_email.text(), user_name)
        except ValueError as exc:
            show_error(self,
                       _("TEXT_ORG_WIZARD_INVALID_HUMAN_HANDLE"),
                       exception=exc)
            return

        self.create_job = self.jobs_ctx.submit_job(
            ThreadSafeQtSignal(self, "req_success"),
            ThreadSafeQtSignal(self, "req_error"),
            _do_create_org,
            config=self.config,
            human_handle=human_handle,
            device_name=device_name,
            password=self.device_widget.password,
            backend_addr=backend_addr,
        )
        self.button_validate.setEnabled(False)
예제 #4
0
 def validate(self, string, pos):
     try:
         if len(string) == 0:
             return QValidator.Intermediate, string, pos
         DeviceName(string)
         return QValidator.Acceptable, string, pos
     except ValueError:
         return QValidator.Invalid, string, pos
예제 #5
0
def test_organization_id_user_id_and_device_name(raw):
    organization_id = OrganizationID(raw)
    assert organization_id == raw

    user_id = UserID(raw)
    assert user_id == raw

    device_name = DeviceName(raw)
    assert device_name == raw
예제 #6
0
    async def do_create_new_device(self, author: LocalDevice,
                                   device_label: Optional[str]) -> None:
        device_id = author.user_id.to_device_id(DeviceName.new())
        try:
            now = pendulum_now()

            device_certificate = DeviceCertificateContent(
                author=author.device_id,
                timestamp=now,
                device_id=device_id,
                device_label=device_label,
                verify_key=self._verify_key,
            )
            redacted_device_certificate = device_certificate.evolve(
                device_label=None)

            device_certificate = device_certificate.dump_and_sign(
                author.signing_key)
            redacted_device_certificate = redacted_device_certificate.dump_and_sign(
                author.signing_key)

        except DataError as exc:
            raise InviteError(
                f"Cannot generate device certificate: {exc}") from exc

        rep = await self._cmds.device_create(
            device_certificate=device_certificate,
            redacted_device_certificate=redacted_device_certificate,
        )
        _check_rep(rep, step_name="device creation")

        try:
            payload = InviteDeviceConfirmation(
                device_id=device_id,
                device_label=device_label,
                human_handle=author.human_handle,
                profile=author.profile,
                private_key=author.private_key,
                user_manifest_id=author.user_manifest_id,
                user_manifest_key=author.user_manifest_key,
                root_verify_key=author.root_verify_key,
            ).dump_and_encrypt(key=self._shared_secret_key)
        except DataError as exc:
            raise InviteError(
                "Cannot generate InviteUserConfirmation payload") from exc

        rep = await self._cmds.invite_4_greeter_communicate(token=self.token,
                                                            payload=payload)
        _check_rep(rep, step_name="step 4 (confirmation exchange)")

        await self._cmds.invite_delete(token=self.token,
                                       reason=InvitationDeletedReason.FINISHED)
예제 #7
0
async def _do_registration(core, device, new_device_name, token):
    try:
        new_device_name = DeviceName(new_device_name)
    except ValueError as exc:
        raise JobResultError("registration-invite-bad-value") from exc

    try:
        await core_invite_and_create_device(
            device=device,
            new_device_name=new_device_name,
            token=token,
            keepalive=core.config.backend_connection_keepalive,
        )
    except InviteClaimTimeoutError:
        raise JobResultError("registration-invite-timeout")
    except InviteClaimBackendOfflineError as exc:
        raise JobResultError("registration-invite-offline") from exc
    except InviteClaimError as exc:
        if "already_exists" in str(exc):
            raise JobResultError("already_exists")
        raise JobResultError("registration-invite-error", info=str(exc))
    return new_device_name, token
 def next_device_id(self, user_id=None):
     nonlocal name_count
     user_id = user_id or self.next_user_id()
     name_count += 1
     return user_id.to_device_id(DeviceName(f"dev{name_count}"))
예제 #9
0
    async def do_create_new_device(
            self, author: LocalDevice,
            device_label: Optional[DeviceLabel]) -> None:
        device_id = author.user_id.to_device_id(DeviceName.new())
        try:
            timestamp = author.timestamp()

            device_certificate = DeviceCertificateContent(
                author=author.device_id,
                timestamp=timestamp,
                device_id=device_id,
                device_label=device_label,
                verify_key=self._verify_key,
            )
            redacted_device_certificate = device_certificate.evolve(
                device_label=None)

            device_certificate = device_certificate.dump_and_sign(
                author.signing_key)
            redacted_device_certificate = redacted_device_certificate.dump_and_sign(
                author.signing_key)

        except DataError as exc:
            raise InviteError(
                f"Cannot generate device certificate: {exc}") from exc

        rep = await self._cmds.device_create(
            device_certificate=device_certificate,
            redacted_device_certificate=redacted_device_certificate,
        )
        _check_rep(rep, step_name="step 4 (device certificates upload)")

        # From now on the device has been created on the server, but greeter
        # is not aware of it yet. If something goes wrong, we can end up with
        # the greeter losing it private keys.
        # This is considered acceptable given 1) the error window is small and
        # 2) if this occurs the inviter can revoke the device and retry the
        # enrollment process to fix this

        try:
            payload = InviteDeviceConfirmation(
                device_id=device_id,
                device_label=device_label,
                human_handle=author.human_handle,
                profile=author.profile,
                private_key=author.private_key,
                user_manifest_id=author.user_manifest_id,
                user_manifest_key=author.user_manifest_key,
                root_verify_key=author.root_verify_key,
            ).dump_and_encrypt(key=self._shared_secret_key)
        except DataError as exc:
            raise InviteError(
                "Cannot generate InviteUserConfirmation payload") from exc

        rep = await self._cmds.invite_4_greeter_communicate(token=self.token,
                                                            payload=payload)
        _check_rep(rep, step_name="step 4 (confirmation exchange)")

        # Invitation deletion is not strictly necessary (enrollment has succeeded
        # anyway) so it's no big deal if something goes wrong before it can be
        # done (and it can be manually deleted from invitation list).
        await self._cmds.invite_delete(token=self.token,
                                       reason=InvitationDeletedReason.FINISHED)
예제 #10
0
def test_device_id(raw):
    user_id, device_name = raw.split("@")
    device_id = DeviceID(raw)
    assert device_id == DeviceID(raw)
    assert device_id.user_id == UserID(user_id)
    assert device_id.device_name == DeviceName(device_name)