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)
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)
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)
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
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
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)
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}"))
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)
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)