async def test_organization_spontaneous_bootstrap(backend,
                                                  organization_factory,
                                                  local_device_factory,
                                                  apiv1_backend_sock_factory,
                                                  flavour):
    neworg = organization_factory("NewOrg")
    # Spontaneous bootstrap must have empty token
    empty_token = ""

    # Step 1: organization creation (if needed)

    if flavour == "create_same_token":
        # Basically pretent we already tried the spontaneous
        # bootstrap but got interrupted
        step1_token = empty_token
        step1_expiration_date = None
    else:
        # Administration explicitly created an organization,
        # we shouldn't be able to overwrite it
        step1_token = "123"
        step1_expiration_date = pendulum.now().add(days=1)
    if flavour != "no_create":
        await backend.organization.create(
            id=neworg.organization_id,
            bootstrap_token=step1_token,
            expiration_date=step1_expiration_date,
        )

    # Step 2: organization bootstrap

    newalice = local_device_factory(org=neworg, profile=UserProfile.ADMIN)
    backend_newalice, backend_newalice_first_device = local_device_to_backend_user(
        newalice, neworg)

    async with apiv1_backend_sock_factory(backend,
                                          neworg.organization_id) as sock:
        rep = await organization_bootstrap(
            sock,
            empty_token,
            backend_newalice.user_certificate,
            backend_newalice_first_device.device_certificate,
            neworg.root_verify_key,
        )
        if flavour == "create_different_token":
            assert rep == {"status": "not_found"}
        else:
            assert rep == {"status": "ok"}

    # Check organization informations

    org = await backend.organization.get(id=neworg.organization_id)
    if flavour == "create_different_token":
        assert org.root_verify_key is None
        assert org.bootstrap_token == step1_token
        assert org.expiration_date == step1_expiration_date
    else:
        assert org.root_verify_key == neworg.root_verify_key
        assert org.bootstrap_token == empty_token
        assert org.expiration_date is None
示例#2
0
async def test_organization_create_and_bootstrap(
    webhook_spy,
    backend,
    organization_factory,
    local_device_factory,
    alice,
    administration_backend_sock,
    apiv1_backend_sock_factory,
):
    neworg = organization_factory("NewOrg")

    # 1) Create organization, note this means `neworg.bootstrap_token`
    # will contain an invalid token

    rep = await organization_create(administration_backend_sock,
                                    neworg.organization_id)
    assert rep == {"status": "ok", "bootstrap_token": ANY}
    bootstrap_token = rep["bootstrap_token"]

    # 2) Bootstrap organization

    # Use an existing user name to make sure they didn't mix together
    newalice = local_device_factory("alice@dev1",
                                    neworg,
                                    profile=UserProfile.ADMIN)
    backend_newalice, backend_newalice_first_device = local_device_to_backend_user(
        newalice, neworg)

    async with apiv1_backend_sock_factory(backend,
                                          neworg.organization_id) as sock:
        rep = await organization_bootstrap(
            sock,
            bootstrap_token=bootstrap_token,
            user_certificate=backend_newalice.user_certificate,
            device_certificate=backend_newalice_first_device.
            device_certificate,
            root_verify_key=neworg.root_verify_key,
            redacted_user_certificate=backend_newalice.
            redacted_user_certificate,
            redacted_device_certificate=backend_newalice_first_device.
            redacted_device_certificate,
        )
    assert rep == {"status": "ok"}

    # Ensure webhook has been triggered
    assert webhook_spy == [(
        "http://example.com:888888/webhook",
        {
            "device_id": "alice@dev1",
            "device_label": "My dev1 machine",
            "human_email": "*****@*****.**",
            "human_label": "Alicey McAliceFace",
            "organization_id": "NewOrg",
        },
    )]
async def test_organization_create_and_bootstrap(
    backend,
    organization_factory,
    local_device_factory,
    alice,
    administration_backend_sock,
    apiv1_backend_sock_factory,
):
    neworg = organization_factory("NewOrg")

    # 1) Create organization, note this means `neworg.bootstrap_token`
    # will contain an invalid token

    rep = await organization_create(administration_backend_sock,
                                    neworg.organization_id)
    assert rep == {"status": "ok", "bootstrap_token": ANY}
    bootstrap_token = rep["bootstrap_token"]

    # 2) Bootstrap organization

    # Use an existing user name to make sure they didn't mix together
    newalice = local_device_factory("alice@dev1",
                                    neworg,
                                    profile=UserProfile.ADMIN)
    backend_newalice, backend_newalice_first_device = local_device_to_backend_user(
        newalice, neworg)

    async with apiv1_backend_sock_factory(backend,
                                          neworg.organization_id) as sock:
        rep = await organization_bootstrap(
            sock,
            bootstrap_token=bootstrap_token,
            user_certificate=backend_newalice.user_certificate,
            device_certificate=backend_newalice_first_device.
            device_certificate,
            root_verify_key=neworg.root_verify_key,
            redacted_user_certificate=backend_newalice.
            redacted_user_certificate,
            redacted_device_certificate=backend_newalice_first_device.
            redacted_device_certificate,
        )
    assert rep == {"status": "ok"}

    # 3) Now our new device can connect the backend
    async with apiv1_backend_sock_factory(backend, newalice) as sock:
        await ping(sock)

    # 4) Make sure alice from the other organization is still working

    async with apiv1_backend_sock_factory(backend, alice) as sock:
        await ping(sock)
async def test_organization_recreate_and_bootstrap(
    backend,
    organization_factory,
    local_device_factory,
    administration_backend_sock,
    apiv1_backend_sock_factory,
):
    neworg = organization_factory("NewOrg")
    rep = await organization_create(administration_backend_sock,
                                    neworg.organization_id)
    assert rep == {"status": "ok", "bootstrap_token": ANY}
    bootstrap_token1 = rep["bootstrap_token"]

    # Can recreate the organization as long as it hasn't been bootstrapped yet
    rep = await organization_create(administration_backend_sock,
                                    neworg.organization_id)
    assert rep == {"status": "ok", "bootstrap_token": ANY}
    bootstrap_token2 = rep["bootstrap_token"]

    assert bootstrap_token1 != bootstrap_token2

    newalice = local_device_factory(org=neworg, profile=UserProfile.ADMIN)
    backend_newalice, backend_newalice_first_device = local_device_to_backend_user(
        newalice, neworg)

    async with apiv1_backend_sock_factory(backend,
                                          neworg.organization_id) as sock:
        # Old token is now invalid
        rep = await organization_bootstrap(
            sock,
            bootstrap_token1,
            backend_newalice.user_certificate,
            backend_newalice_first_device.device_certificate,
            neworg.root_verify_key,
        )
        assert rep == {"status": "not_found"}

        rep = await organization_bootstrap(
            sock,
            bootstrap_token2,
            backend_newalice.user_certificate,
            backend_newalice_first_device.device_certificate,
            neworg.root_verify_key,
        )
        assert rep == {"status": "ok"}

    # Now we are no longer allowed to re-create the organization
    rep = await organization_create(administration_backend_sock,
                                    neworg.organization_id)
    assert rep == {"status": "already_exists"}
示例#5
0
async def test_organization_with_expiration_date_create_and_bootstrap(
    backend,
    organization_factory,
    local_device_factory,
    alice,
    administration_backend_sock,
    apiv1_backend_sock_factory,
):
    neworg = organization_factory("NewOrg")

    # 1) Create organization, note this means `neworg.bootstrap_token`
    # will contain an invalid token

    with freeze_time("2000-01-01"):

        expiration_date = pendulum.datetime(2000, 1, 2)
        rep = await organization_create(administration_backend_sock,
                                        neworg.organization_id,
                                        expiration_date=expiration_date)
        assert rep == {
            "status": "ok",
            "bootstrap_token": ANY,
            "expiration_date": expiration_date
        }
        bootstrap_token = rep["bootstrap_token"]

        # 2) Bootstrap organization

        # Use an existing user name to make sure they didn't mix together
        newalice = local_device_factory("alice@dev1",
                                        neworg,
                                        profile=UserProfile.ADMIN)
        backend_newalice, backend_newalice_first_device = local_device_to_backend_user(
            newalice, neworg)

        async with apiv1_backend_sock_factory(backend,
                                              neworg.organization_id) as sock:
            rep = await organization_bootstrap(
                sock,
                bootstrap_token,
                backend_newalice.user_certificate,
                backend_newalice_first_device.device_certificate,
                neworg.root_verify_key,
            )
        assert rep == {"status": "ok"}
async def test_organization_with_expiration_date_create_and_bootstrap(
    backend,
    organization_factory,
    local_device_factory,
    alice,
    administration_backend_sock,
    apiv1_backend_sock_factory,
):
    neworg = organization_factory("NewOrg")

    # 1) Create organization, note this means `neworg.bootstrap_token`
    # will contain an invalid token

    with freeze_time("2000-01-01"):

        expiration_date = pendulum.Pendulum(2000, 1, 2)
        rep = await organization_create(administration_backend_sock,
                                        neworg.organization_id,
                                        expiration_date=expiration_date)
        assert rep == {
            "status": "ok",
            "bootstrap_token": ANY,
            "expiration_date": expiration_date
        }
        bootstrap_token = rep["bootstrap_token"]

        # 2) Bootstrap organization

        # Use an existing user name to make sure they didn't mix together
        newalice = local_device_factory("alice@dev1",
                                        neworg,
                                        profile=UserProfile.ADMIN)
        backend_newalice, backend_newalice_first_device = local_device_to_backend_user(
            newalice, neworg)

        async with apiv1_backend_sock_factory(backend,
                                              neworg.organization_id) as sock:
            rep = await organization_bootstrap(
                sock,
                bootstrap_token,
                backend_newalice.user_certificate,
                backend_newalice_first_device.device_certificate,
                neworg.root_verify_key,
            )
        assert rep == {"status": "ok"}

        # 3) Now our new device can connect the backend
        async with apiv1_backend_sock_factory(backend, newalice) as sock:
            await ping(sock)

        # 4) Make sure alice from the other organization is still working

        async with apiv1_backend_sock_factory(backend, alice) as sock:
            await ping(sock)

    # 5) Now advance after the expiration
    with freeze_time("2000-01-02"):
        # Both anonymous and authenticated connections are refused
        with pytest.raises(HandshakeOrganizationExpired):
            async with apiv1_backend_sock_factory(backend, newalice):
                pass
        with pytest.raises(HandshakeOrganizationExpired):
            async with apiv1_backend_sock_factory(backend,
                                                  neworg.organization_id):
                pass
async def test_create_organization_already_bootstrapped(
    aqtbot,
    running_backend,
    catch_create_org_widget,
    autoclose_dialog,
    gui,
    monkeypatch,
    organization_factory,
    local_device_factory,
    alice,
):
    org = organization_factory()
    backend_user, backend_first_device = local_device_to_backend_user(
        alice, org)
    bootstrap_token = "123456"
    await running_backend.backend.organization.create(org.organization_id,
                                                      bootstrap_token, None)
    await running_backend.backend.organization.bootstrap(
        org.organization_id,
        backend_user,
        backend_first_device,
        bootstrap_token,
        org.root_verify_key,
    )

    org_bs_addr = BackendOrganizationBootstrapAddr.build(
        running_backend.addr, org.organization_id, bootstrap_token)

    monkeypatch.setattr("parsec.core.gui.main_window.get_text_input",
                        lambda *args, **kwargs: (str(org_bs_addr)))

    # The org bootstrap window is usually opened using a sub-menu.
    # Sub-menus can be a bit challenging to open in tests so we cheat
    # using the keyboard shortcut Ctrl+O that has the same effect.
    await aqtbot.key_click(gui, "o", QtCore.Qt.ControlModifier, 200)

    co_w = await catch_create_org_widget()
    await aqtbot.wait_until(co_w.user_widget.isVisible)

    await aqtbot.key_clicks(co_w.user_widget.line_edit_user_full_name,
                            "Gordon Freeman")
    await aqtbot.key_clicks(co_w.user_widget.line_edit_user_email,
                            "*****@*****.**")

    def _user_widget_ready():
        assert co_w.user_widget.line_edit_org_name.text(
        ) == org.organization_id
        assert co_w.user_widget.line_edit_org_name.isReadOnly() is True

    await aqtbot.wait_until(_user_widget_ready)

    await aqtbot.mouse_click(co_w.user_widget.check_accept_contract,
                             QtCore.Qt.LeftButton)
    await aqtbot.mouse_click(co_w.button_validate, QtCore.Qt.LeftButton)

    await aqtbot.wait_until(co_w.device_widget.isVisible)

    await aqtbot.key_clicks(co_w.device_widget.line_edit_device, "HEV")
    await aqtbot.key_clicks(
        co_w.device_widget.widget_password.line_edit_password, "nihilanth")
    await aqtbot.key_clicks(
        co_w.device_widget.widget_password.line_edit_password_check,
        "nihilanth")
    await aqtbot.mouse_click(co_w.button_validate, QtCore.Qt.LeftButton)

    def _modal_shown():
        assert autoclose_dialog.dialogs == [
            ("Error", "This bootstrap link was already used.")
        ]

    await aqtbot.wait_until(_modal_shown)