Пример #1
0
async def get_project_states_for_user(user_id: int, project_uuid: str,
                                      app: web.Application) -> ProjectState:
    # for templates: the project is never locked and never opened. also the running state is always unknown
    lock_state = ProjectLocked(value=False, status=ProjectStatus.CLOSED)
    running_state = RunningState.UNKNOWN
    lock_state, computation_task = await logged_gather(
        _get_project_lock_state(user_id, project_uuid, app),
        director_v2_api.get_computation_task(app, user_id, UUID(project_uuid)),
    )
    if computation_task:
        # get the running state
        running_state = computation_task.state

    return ProjectState(locked=lock_state,
                        state=ProjectRunningState(value=running_state))
def mocks_on_projects_api(mocker) -> Dict:
    """
    All projects in this module are UNLOCKED
    """
    state = ProjectState(
        locked=ProjectLocked(
            value=False,
            owner=Owner(user_id=2, first_name="Speedy", last_name="Gonzalez"),
        ),
        state=ProjectRunningState(value=RunningState.NOT_STARTED),
    ).dict(by_alias=True, exclude_unset=True)
    mocker.patch(
        "simcore_service_webserver.projects.projects_api.get_project_state_for_user",
        return_value=future_with_result(state),
    )
Пример #3
0
async def add_project_states_for_user(
    user_id: int,
    project: Dict[str, Any],
    is_template: bool,
    app: web.Application,
) -> Dict[str, Any]:

    # for templates: the project is never locked and never opened. also the running state is always unknown
    lock_state = ProjectLocked(value=False, status=ProjectStatus.CLOSED)
    running_state = RunningState.UNKNOWN
    if not is_template:
        lock_state, computation_task = await logged_gather(
            _get_project_lock_state(user_id, project["uuid"], app),
            director_v2_api.get_computation_task(app, user_id, project["uuid"]),
        )

        if computation_task:
            # get the running state
            running_state = computation_task.state
            # get the nodes individual states
            for (
                node_id,
                node_state,
            ) in computation_task.pipeline_details.node_states.items():
                prj_node = project["workbench"].get(str(node_id))
                if prj_node is None:
                    continue
                node_state_dict = json.loads(
                    node_state.json(by_alias=True, exclude_unset=True)
                )
                prj_node.setdefault("state", {}).update(node_state_dict)

    project["state"] = ProjectState(
        locked=lock_state, state=ProjectRunningState(value=running_state)
    ).dict(by_alias=True, exclude_unset=True)
    return project
Пример #4
0
def mocks_on_projects_api(mocker, logged_user) -> None:
    """
    All projects in this module are UNLOCKED

    Emulates that it found logged_user as the SOLE user of this project
    and returns the  ProjectState indicating his as owner
    """
    nameparts = logged_user["name"].split(".") + [""]
    state = ProjectState(
        locked=ProjectLocked(
            value=False,
            owner=Owner(
                user_id=logged_user["id"],
                first_name=nameparts[0],
                last_name=nameparts[1],
            ),
            status=ProjectStatus.CLOSED,
        ),
        state=ProjectRunningState(value=RunningState.NOT_STARTED),
    )
    mocker.patch(
        "simcore_service_webserver.projects.projects_api._get_project_lock_state",
        return_value=state,
    )
async def test_open_shared_project_2_users_locked(
    client: TestClient,
    client_on_running_server_factory: Callable,
    logged_user: Dict,
    shared_project: Dict,
    socketio_client_factory: Callable,
    client_session_id_factory: Callable,
    user_role: UserRole,
    expected: ExpectedResponse,
    mocker,
    disable_gc_manual_guest_users,
):
    # Use-case: user 1 opens a shared project, user 2 tries to open it as well
    mock_project_state_updated_handler = mocker.Mock()

    client_1 = client
    client_id1 = client_session_id_factory()
    client_2 = client_on_running_server_factory()
    client_id2 = client_session_id_factory()

    # 1. user 1 opens project
    sio_1 = await _connect_websocket(
        socketio_client_factory,
        user_role != UserRole.ANONYMOUS,
        client_1,
        client_id1,
        {SOCKET_IO_PROJECT_UPDATED_EVENT: mock_project_state_updated_handler},
    )
    # expected is that the project is closed and unlocked
    expected_project_state_client_1 = ProjectState(
        locked=ProjectLocked(value=False, status=ProjectStatus.CLOSED),
        state=ProjectRunningState(value=RunningState.NOT_STARTED),
    )
    for client_id in [client_id1, None]:
        await _state_project(
            client_1,
            shared_project,
            expected.ok if user_role != UserRole.GUEST else web.HTTPOk,
            expected_project_state_client_1,
        )
    await _open_project(
        client_1,
        client_id1,
        shared_project,
        expected.ok if user_role != UserRole.GUEST else web.HTTPOk,
    )
    # now the expected result is that the project is locked and opened by client 1
    owner1 = Owner(
        user_id=logged_user["id"],
        first_name=(logged_user["name"].split(".") + [""])[0],
        last_name=(logged_user["name"].split(".") + [""])[1],
    )
    expected_project_state_client_1.locked.value = True
    expected_project_state_client_1.locked.status = ProjectStatus.OPENED
    expected_project_state_client_1.locked.owner = owner1
    # NOTE: there are 2 calls since we are part of the primary group and the all group
    await _assert_project_state_updated(
        mock_project_state_updated_handler,
        shared_project,
        [expected_project_state_client_1]
        * (0 if user_role == UserRole.ANONYMOUS else 2),
    )
    await _state_project(
        client_1,
        shared_project,
        expected.ok if user_role != UserRole.GUEST else web.HTTPOk,
        expected_project_state_client_1,
    )

    # 2. create a separate client now and log in user2, try to open the same shared project
    user_2 = await log_client_in(
        client_2, {"role": user_role.name}, enable_check=user_role != UserRole.ANONYMOUS
    )
    sio_2 = await _connect_websocket(
        socketio_client_factory,
        user_role != UserRole.ANONYMOUS,
        client_2,
        client_id2,
        {SOCKET_IO_PROJECT_UPDATED_EVENT: mock_project_state_updated_handler},
    )
    await _open_project(
        client_2,
        client_id2,
        shared_project,
        expected.locked if user_role != UserRole.GUEST else HTTPLocked,
    )
    expected_project_state_client_2 = deepcopy(expected_project_state_client_1)
    expected_project_state_client_2.locked.status = ProjectStatus.OPENED

    await _state_project(
        client_2,
        shared_project,
        expected.ok if user_role != UserRole.GUEST else web.HTTPOk,
        expected_project_state_client_2,
    )

    # 3. user 1 closes the project
    await _close_project(client_1, client_id1, shared_project, expected.no_content)
    if not any(user_role == role for role in [UserRole.ANONYMOUS, UserRole.GUEST]):
        # Guests cannot close projects
        expected_project_state_client_1 = ProjectState(
            locked=ProjectLocked(value=False, status=ProjectStatus.CLOSED),
            state=ProjectRunningState(value=RunningState.NOT_STARTED),
        )

    # we should receive an event that the project lock state changed
    # NOTE: there are 2x3 calls since we are part of the primary group and the all group and user 2 is part of the all group
    # first CLOSING, then CLOSED
    await _assert_project_state_updated(
        mock_project_state_updated_handler,
        shared_project,
        [
            expected_project_state_client_1.copy(
                update={
                    "locked": ProjectLocked(
                        value=True, status=ProjectStatus.CLOSING, owner=owner1
                    )
                }
            )
        ]
        * (
            0
            if any(user_role == role for role in [UserRole.ANONYMOUS, UserRole.GUEST])
            else 3
        )
        + [expected_project_state_client_1]
        * (
            0
            if any(user_role == role for role in [UserRole.ANONYMOUS, UserRole.GUEST])
            else 3
        ),
    )
    await _state_project(
        client_1,
        shared_project,
        expected.ok if user_role != UserRole.GUEST else web.HTTPOk,
        expected_project_state_client_1,
    )

    # 4. user 2 now should be able to open the project
    await _open_project(
        client_2,
        client_id2,
        shared_project,
        expected.ok if user_role != UserRole.GUEST else HTTPLocked,
    )
    if not any(user_role == role for role in [UserRole.ANONYMOUS, UserRole.GUEST]):
        expected_project_state_client_2.locked.value = True
        expected_project_state_client_2.locked.status = ProjectStatus.OPENED
        owner2 = Owner(
            user_id=user_2["id"],
            first_name=(user_2["name"].split(".") + [""])[0],
            last_name=(user_2["name"].split(".") + [""])[1],
        )
        expected_project_state_client_2.locked.owner = owner2
        expected_project_state_client_1.locked.value = True
        expected_project_state_client_1.locked.status = ProjectStatus.OPENED
        expected_project_state_client_1.locked.owner = owner2
    # NOTE: there are 3 calls since we are part of the primary group and the all group
    await _assert_project_state_updated(
        mock_project_state_updated_handler,
        shared_project,
        [expected_project_state_client_1]
        * (
            0
            if any(user_role == role for role in [UserRole.ANONYMOUS, UserRole.GUEST])
            else 3
        ),
    )
    await _state_project(
        client_1,
        shared_project,
        expected.ok if user_role != UserRole.GUEST else web.HTTPOk,
        expected_project_state_client_1,
    )
Пример #6
0
    )
    # for templates: the project is never locked and never opened. also the running state is always unknown
    lock_state = ProjectLocked(value=False, status=ProjectStatus.CLOSED)
    running_state = RunningState.UNKNOWN

    if not is_template:
        lock_state = await _get_project_lock_state(user_id, project["uuid"],
                                                   app)

        if computation_task := await director_v2_api.get_computation_task(
                app, user_id, project["uuid"]):
            # get the running state
            running_state = computation_task.state
            # get the nodes individual states
            for (
                    node_id,
                    node_state,
            ) in computation_task.pipeline_details.node_states.items():
                prj_node = project["workbench"].get(str(node_id))
                if prj_node is None:
                    continue
                node_state_dict = json.loads(
                    node_state.json(by_alias=True, exclude_unset=True))
                prj_node.setdefault("state", {}).update(node_state_dict)

    project["state"] = ProjectState(
        locked=lock_state,
        state=ProjectRunningState(value=running_state)).dict(
            by_alias=True, exclude_unset=True)
    return project
Пример #7
0
async def _get_project_running_state(
        user_id: PositiveInt, project_uuid: str,
        app: web.Application) -> ProjectRunningState:
    pipeline_state: RunningState = await get_pipeline_state(
        app, user_id, project_uuid)
    return ProjectRunningState(value=pipeline_state)