def validate(self, string, pos): try: if len(string) == 0: return QValidator.Intermediate, string, pos BackendOrganizationAddr.from_url(string) return QValidator.Acceptable, string, pos except ValueError: return QValidator.Intermediate, string, pos
def test_backend_organization_addr_good(base_url, expected, verify_key): org = OrganizationID("org") backend_addr = BackendAddr.from_url(base_url) addr = BackendOrganizationAddr.build(backend_addr, organization_id=org, root_verify_key=verify_key) assert addr.hostname == "foo" assert addr.port == expected["port"] assert addr.use_ssl == expected["ssl"] assert addr.organization_id == org assert addr.root_verify_key == verify_key addr2 = BackendOrganizationAddr.from_url(addr.to_url()) assert addr == addr2
async def bootstrap_organization( cmds: APIV1_BackendAnonymousCmds, human_handle: Optional[HumanHandle], device_label: Optional[str], ) -> LocalDevice: root_signing_key = SigningKey.generate() root_verify_key = root_signing_key.verify_key organization_addr = BackendOrganizationAddr.build( backend_addr=cmds.addr, organization_id=cmds.addr.organization_id, root_verify_key=root_verify_key, ) device = generate_new_device( organization_addr=organization_addr, profile=UserProfile.ADMIN, human_handle=human_handle, device_label=device_label, ) now = pendulum_now() user_certificate = UserCertificateContent( author=None, timestamp=now, user_id=device.user_id, human_handle=device.human_handle, public_key=device.public_key, profile=device.profile, ) redacted_user_certificate = user_certificate.evolve(human_handle=None) device_certificate = DeviceCertificateContent( author=None, timestamp=now, device_id=device.device_id, device_label=device.device_label, verify_key=device.verify_key, ) redacted_device_certificate = device_certificate.evolve(device_label=None) user_certificate = user_certificate.dump_and_sign(root_signing_key) redacted_user_certificate = redacted_user_certificate.dump_and_sign( root_signing_key) device_certificate = device_certificate.dump_and_sign(root_signing_key) redacted_device_certificate = redacted_device_certificate.dump_and_sign( root_signing_key) rep = await cmds.organization_bootstrap( organization_id=cmds.addr.organization_id, bootstrap_token=cmds.addr.token, root_verify_key=root_verify_key, user_certificate=user_certificate, device_certificate=device_certificate, redacted_user_certificate=redacted_user_certificate, redacted_device_certificate=redacted_device_certificate, ) _check_rep(rep, step_name="organization bootstrap") return device
async def test_handshake_unknown_organization(running_backend, coolorg): unknown_org_addr = BackendOrganizationAddr.build( backend_addr=coolorg.addr, organization_id="dummy", root_verify_key=coolorg.root_verify_key) with pytest.raises(BackendConnectionRefused) as exc: async with apiv1_backend_anonymous_cmds_factory( unknown_org_addr) as cmds: await cmds.ping() assert str(exc.value) == "Invalid handshake information"
async def test_handshake_rvk_mismatch(running_backend, alice, otherorg): bad_rvk_org_addr = BackendOrganizationAddr.build( backend_addr=alice.organization_addr, organization_id=alice.organization_id, root_verify_key=otherorg.root_verify_key, ) with pytest.raises(BackendConnectionRefused) as exc: async with backend_authenticated_cmds_factory( bad_rvk_org_addr, alice.device_id, alice.signing_key ) as cmds: await cmds.ping() assert str(exc.value) == "Root verify key for organization differs between client and server"
async def test_handshake_unknown_organization(running_backend, alice): unknown_org_addr = BackendOrganizationAddr.build( backend_addr=alice.organization_addr, organization_id="dummy", root_verify_key=alice.organization_addr.root_verify_key, ) with pytest.raises(BackendConnectionRefused) as exc: async with backend_authenticated_cmds_factory( unknown_org_addr, alice.device_id, alice.signing_key ) as cmds: await cmds.ping() assert str(exc.value) == "Invalid handshake information"
async def test_handshake_rvk_mismatch(running_backend, coolorg, otherorg): bad_rvk_org_addr = BackendOrganizationAddr.build( backend_addr=coolorg.addr, organization_id=coolorg.organization_id, root_verify_key=otherorg.root_verify_key, ) with pytest.raises(BackendConnectionRefused) as exc: async with apiv1_backend_anonymous_cmds_factory( bad_rvk_org_addr) as cmds: await cmds.ping() assert str( exc.value ) == "Root verify key for organization differs between client and server"
async def do_claim_user( self, requested_device_label: Optional[str], requested_human_handle: Optional[HumanHandle]) -> LocalDevice: private_key = PrivateKey.generate() signing_key = SigningKey.generate() try: payload = InviteUserData( requested_device_label=requested_device_label, requested_human_handle=requested_human_handle, public_key=private_key.public_key, verify_key=signing_key.verify_key, ).dump_and_encrypt(key=self._shared_secret_key) except DataError as exc: raise InviteError( "Cannot generate InviteUserData payload") from exc rep = await self._cmds.invite_4_claimer_communicate(payload=payload) _check_rep(rep, step_name="step 4 (data exchange)") rep = await self._cmds.invite_4_claimer_communicate(payload=b"") _check_rep(rep, step_name="step 4 (confirmation exchange)") try: confirmation = InviteUserConfirmation.decrypt_and_load( rep["payload"], key=self._shared_secret_key) except DataError as exc: raise InviteError( "Invalid InviteUserConfirmation payload provided by peer" ) from exc organization_addr = BackendOrganizationAddr.build( backend_addr=self._cmds.addr, organization_id=self._cmds.addr.organization_id, root_verify_key=confirmation.root_verify_key, ) new_device = generate_new_device( organization_addr=organization_addr, device_id=confirmation.device_id, device_label=confirmation.device_label, human_handle=confirmation.human_handle, profile=confirmation.profile, private_key=private_key, signing_key=signing_key, ) return new_device
def organization_addr(exported_verify_key): url = "parsec://foo/org?rvk=<rvk>".replace("<rvk>", exported_verify_key) return BackendOrganizationAddr.from_url(url)
def test_backend_organization_addr_bad_value(url, exc_msg, exported_verify_key): url = url.replace("<rvk>", exported_verify_key) with pytest.raises(ValueError) as exc: BackendOrganizationAddr.from_url(url) assert str(exc.value) == exc_msg