def validate(self, string, pos): try: if len(string) == 0: return QValidator.Intermediate, string, pos BackendOrganizationBootstrapAddr.from_url(string) return QValidator.Acceptable, string, pos except ValueError: return QValidator.Intermediate, string, pos
async def test_good(running_backend, backend, alice, bob, alice_backend_cmds, user_fs_factory, with_labels): org_id = OrganizationID("NewOrg") org_token = "123456" await backend.organization.create(org_id, org_token) organization_addr = BackendOrganizationBootstrapAddr.build( running_backend.addr, org_id, org_token) if with_labels: human_handle = HumanHandle(email="*****@*****.**", label="Zack") device_label = "PC1" else: human_handle = None device_label = None async with apiv1_backend_anonymous_cmds_factory( addr=organization_addr) as cmds: new_device = await bootstrap_organization(cmds, human_handle=human_handle, device_label=device_label) assert new_device is not None assert new_device.organization_id == org_id assert new_device.device_label == device_label assert new_device.human_handle == human_handle assert new_device.profile == UserProfile.ADMIN # Test the behavior of this new device async with user_fs_factory(new_device, initialize_in_v0=True) as newfs: await newfs.workspace_create("wa") await newfs.sync() # Test the device in correct in the backend backend_user, backend_device = await backend.user.get_user_with_device( org_id, new_device.device_id) assert backend_user.user_id == new_device.user_id assert backend_user.human_handle == new_device.human_handle assert backend_user.profile == new_device.profile assert backend_user.user_certifier is None if with_labels: assert backend_user.user_certificate != backend_user.redacted_user_certificate else: assert backend_user.user_certificate == backend_user.redacted_user_certificate assert backend_device.device_id == new_device.device_id assert backend_device.device_label == new_device.device_label assert backend_device.device_certifier is None if with_labels: assert backend_device.device_certificate != backend_device.redacted_device_certificate else: assert backend_device.device_certificate == backend_device.redacted_device_certificate
def test_backend_organization_bootstrap_addr_good(base_url, expected, verify_key): org = OrganizationID("org") backend_addr = BackendAddr.from_url(base_url) addr = BackendOrganizationBootstrapAddr.build(backend_addr, org, "token-123") assert addr.hostname == "foo" assert addr.port == expected["port"] assert addr.use_ssl == expected["ssl"] assert addr.organization_id == org assert addr.token == "token-123" addr2 = BackendOrganizationBootstrapAddr.from_url(str(addr)) assert addr == addr2 org_addr = addr.generate_organization_addr(verify_key) assert isinstance(org_addr, BackendOrganizationAddr) assert org_addr.root_verify_key == verify_key assert org_addr.hostname == addr.hostname assert org_addr.port == addr.port assert org_addr.use_ssl == addr.use_ssl assert org_addr.organization_id == addr.organization_id
async def _create_organization(debug, name, backend_addr, administration_token, expiration_date): async with spinner("Creating group in backend"): async with apiv1_backend_administration_cmds_factory( backend_addr, administration_token) as cmds: rep = await cmds.organization_create(name, expiration_date) if rep["status"] != "ok": raise RuntimeError(f"Backend refused to create group: {rep}") bootstrap_token = rep["bootstrap_token"] organization_addr = BackendOrganizationBootstrapAddr.build( backend_addr, name, bootstrap_token) organization_addr_display = click.style(organization_addr.to_url(), fg="yellow") click.echo(f"Bootstrap group url: {organization_addr_display}")
async def test_invalid_token(running_backend, backend): org_id = OrganizationID("NewOrg") old_token = "123456" new_token = "abcdef" await backend.organization.create(org_id, old_token) await backend.organization.create(org_id, new_token) organization_addr = BackendOrganizationBootstrapAddr.build( running_backend.addr, org_id, old_token) async with apiv1_backend_anonymous_cmds_factory( addr=organization_addr) as cmds: with pytest.raises(InviteNotFoundError): await bootstrap_organization(cmds, human_handle=None, device_label=None)
async def test_already_bootstrapped(running_backend, backend, alice, bob, alice_backend_cmds, user_fs_factory): org_id = OrganizationID("NewOrg") org_token = "123456" await backend.organization.create(org_id, org_token) organization_addr = BackendOrganizationBootstrapAddr.build( running_backend.addr, org_id, org_token) async with apiv1_backend_anonymous_cmds_factory( addr=organization_addr) as cmds: await bootstrap_organization(cmds, human_handle=None, device_label=None) with pytest.raises(InviteAlreadyUsedError): await bootstrap_organization(cmds, human_handle=None, device_label=None)
async def _do_api_request(email, organization_id): data = json.dumps({"email": email, "organization_id": organization_id}).encode("utf-8") url = os.environ.get("BOOTSTRAP_API_URL", "quickjoin") req = Request(url, method="POST", data=data, headers={"Content-Type": "application/json"}) try: response = await trio.to_thread.run_sync(lambda: urlopen(req)) if response.status != 200: raise JobResultError("invalid_response") try: content = await trio.to_thread.run_sync(lambda: response.read()) content = json.loads(content) if content.get("error", None): raise JobResultError(content["error"]) return ( content["gid"], BackendOrganizationBootstrapAddr.from_url(content["bootstrap_link"]), ) except (TypeError, KeyError) as exc: raise JobResultError("invalid_response", exc=exc) except (HTTPException, URLError) as exc: raise JobResultError("offline", exc=exc)
def _organization_factory(orgname=None, expiration_date=None): nonlocal count if not orgname: count += 1 orgname = f"Org{count}" assert orgname not in organizations organization_id = OrganizationID(orgname) organizations.add(organization_id) bootstrap_token = f"<{orgname}-bootstrap-token>" bootstrap_addr = BackendOrganizationBootstrapAddr.build( backend_addr, organization_id=organization_id, token=bootstrap_token) root_signing_key = SigningKey.generate() addr = bootstrap_addr.generate_organization_addr( root_signing_key.verify_key) return OrganizationFullData(bootstrap_addr, addr, root_signing_key)
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 def _on_finished(ret): if ret: self.reload_login_devices() self.try_login(ret[0], ret[1]) BootstrapOrganizationWidget.show_modal( jobs_ctx=self.jobs_ctx, config=self.config, addr=action_addr, parent=self, on_finished=_on_finished, )
async def initialize_test_organization( config_dir: Path, backend_address: BackendAddr, password: str, administration_token: str, force: bool, additional_users_number: int, additional_devices_number: int, ) -> Tuple[LocalDevice, LocalDevice, LocalDevice]: configure_logging("WARNING") organization_id = OrganizationID("Org") # Create organization async with apiv1_backend_administration_cmds_factory( backend_address, administration_token) as administration_cmds: rep = await administration_cmds.organization_create(organization_id) assert rep["status"] == "ok" bootstrap_token = rep["bootstrap_token"] organization_bootstrap_addr = BackendOrganizationBootstrapAddr.build( backend_address, organization_id, bootstrap_token) # Bootstrap organization and Alice user and create device "laptop" for Alice async with apiv1_backend_anonymous_cmds_factory( organization_bootstrap_addr) as anonymous_cmds: alice_device = await bootstrap_organization( cmds=anonymous_cmds, human_handle=HumanHandle(label="Alice", email="*****@*****.**"), device_label="laptop", ) save_device_with_password(config_dir, alice_device, password, force=force) config = load_config(config_dir, debug="DEBUG" in os.environ) # Create context manager, alice_client will be needed for the rest of the script async with logged_client_factory(config, alice_device) as alice_client: async with backend_authenticated_cmds_factory( addr=alice_device.organization_addr, device_id=alice_device.device_id, signing_key=alice_device.signing_key, ) as alice_cmds: # Create new device "pc" for Alice other_alice_device = await _register_new_device( cmds=alice_cmds, author=alice_device, device_label="pc") save_device_with_password(config_dir, other_alice_device, password, force=force) # Add additional random device for alice if additional_devices_number > 0: print( f"Adding {additional_devices_number} devices in the test group" ) print(" ... please wait ...") await _add_random_device( cmds=alice_cmds, config_dir=config_dir, force=force, password=password, device=alice_device, additional_devices_number=additional_devices_number, ) print(" Done ") # Invite Bob in organization bob_device = await _register_new_user( cmds=alice_cmds, author=alice_device, device_label="laptop", human_handle=HumanHandle(email="*****@*****.**", label="Bob"), profile=UserProfile.STANDARD, ) save_device_with_password(config_dir, bob_device, password, force=force) # Create Alice workspace alice_ws_id = await alice_client.user_fs.workspace_create( "alice_workspace") # Create context manager async with logged_client_factory(config, bob_device) as bob_client: # Create Bob workspace bob_ws_id = await bob_client.user_fs.workspace_create( "bob_workspace") # Bob share workspace with Alice await bob_client.user_fs.workspace_share( bob_ws_id, alice_device.user_id, WorkspaceRole.MANAGER) # Alice share workspace with Bob await alice_client.user_fs.workspace_share( alice_ws_id, bob_device.user_id, WorkspaceRole.MANAGER) # Add additional random users if additional_users_number > 0: print( f"Adding {additional_users_number} users in the test group" ) print(" ... please wait ...") await _add_random_users( cmds=alice_cmds, author=alice_device, alice_client=alice_client, bob_client=bob_client, alice_ws_id=alice_ws_id, bob_ws_id=bob_ws_id, additional_users_number=additional_users_number, ) print(" Done ") # Synchronize every device for device in (alice_device, other_alice_device, bob_device): async with logged_client_factory(config, device) as client: await client.user_fs.process_last_messages() await client.user_fs.sync() return (alice_device, other_alice_device, bob_device)
async def organization_bootstrap_addr(running_backend): org_id = OrganizationID("NewOrg") org_token = "123456" await running_backend.backend.organization.create(org_id, org_token) return BackendOrganizationBootstrapAddr.build(running_backend.addr, org_id, org_token)
def test_backend_organization_bootstrap_addr_bad_value(url, exc_msg): with pytest.raises(ValueError) as exc: BackendOrganizationBootstrapAddr.from_url(url) assert str(exc.value) == exc_msg