Example #1
0
    def test_pro_tier(self, db, project, pro_profile, profile):
        """
        Test able to add more than three collaborators with a private
        and public app.
        """
        project.is_public = False
        replace_owner(project, pro_profile)

        collabs = list(gen_collabs(4))

        for collab in collabs:
            project.assign_role("read", collab.user)
            assert (get_perms(collab.user, project) == ["read_project"]
                    and project.role(collab.user) == "read")

        # OK making app private.
        project.make_private_test()

        project.is_public = True
        project.save()

        for collab in collabs:
            project.assign_role(None, collab.user)
            assert project.role(collab.user) == None

        for collab in collabs:
            project.assign_role("read", collab.user)
            assert (get_perms(collab.user, project) == ["read_project"]
                    and project.role(collab.user) == "read")

        # OK making app private.
        project.make_private_test()
    def test_pro_tier(self, db, tier, get_inputs, meta_param_dict, pro_profile,
                      free_profile):
        """
        Test able to add more than one collaborator with a private
        and public sim.
        """
        if tier == "free":
            profile = free_profile
        else:
            profile = pro_profile

        inputs = _submit_inputs("Used-for-testing", get_inputs,
                                meta_param_dict, profile)

        _, submit_sim = _submit_sim(inputs)
        sim = submit_sim.submit()
        sim.status = "SUCCESS"
        sim.save()

        collabs = list(gen_collabs(3))

        for collab in collabs:
            sim.assign_role("read", collab.user)
            assert (get_perms(collab.user, sim) == ["read_simulation"]
                    and sim.role(collab.user) == "read")

        # OK making sim private.
        sim.make_private_test()

        sim.is_public = True
        sim.save()

        for collab in collabs:
            sim.assign_role(None, collab.user)
            assert sim.role(collab.user) == None

        for collab in collabs:
            sim.assign_role("read", collab.user)
            assert (get_perms(collab.user, sim) == ["read_simulation"]
                    and sim.role(collab.user) == "read")

        # OK making sim private.
        sim.make_private_test()
Example #3
0
    def test_get_private_projects(self, api_client, pro_profile):
        project = Project.objects.get(title="Used-for-testing")
        project.is_public = False
        project.owner = pro_profile
        replace_owner(project, pro_profile)
        project.save()

        # Test private app not included in unauthenticated get
        resp = api_client.get("/apps/api/v1/")
        assert resp.status_code == 200
        exp = set(proj.title
                  for proj in Project.objects.filter(is_public=True).all())
        act = set(proj["title"] for proj in resp.data["results"])
        assert exp == act

        # Test private app not included if user doesn't have write access
        collab = next(gen_collabs(1))
        api_client.force_login(collab.user)
        resp = api_client.get("/apps/api/v1/")
        assert resp.status_code == 200
        exp = set(proj.title
                  for proj in Project.objects.filter(is_public=True).all())
        act = set(proj["title"] for proj in resp.data["results"])
        assert exp == act

        # Test private app included if user has read access
        api_client.force_login(project.owner.user)
        resp = api_client.get("/apps/api/v1/")
        assert resp.status_code == 200
        exp = set(proj.title for proj in Project.objects.all())
        act = set(proj["title"] for proj in resp.data["results"])
        assert exp == act

        api_client.force_login(collab.user)
        project.assign_role("read", collab.user)
        resp = api_client.get("/apps/api/v1/")
        assert resp.status_code == 200
        exp = set(proj.title for proj in Project.objects.all())
        act = set(proj["title"] for proj in resp.data["results"])
        assert exp == act
Example #4
0
    def test_list_deployments(self, db, client, api_client, viz_project,
                              mock_deployments_requests_to_cluster):
        viz_project.sponsor = viz_project.owner
        viz_project.save()

        resp = client.get(f"/{viz_project}/viz/")
        assert resp.status_code == 200

        resp = api_client.get(f"/apps/api/v1/deployments/")
        assert resp.status_code == 403

        (collab, ) = gen_collabs(1)
        api_client.force_login(collab.user)
        resp = api_client.get(f"/apps/api/v1/deployments/")
        assert resp.status_code == 200
        assert resp.json()["results"] == []

        api_client.force_login(viz_project.cluster.service_account.user)
        resp = api_client.get(f"/apps/api/v1/deployments/")
        assert resp.status_code == 200
        assert (resp.json()["results"] == DeploymentSerializer(
            Deployment.objects.filter(project=viz_project), many=True).data)
Example #5
0
    def test_free_tier(self, db, project, free_profile):
        """
        Test private app can not have any collaborators but
        public is unlimited.
        """
        project.is_public = False
        project.save()
        replace_owner(project, free_profile)

        collabs = list(gen_collabs(3))

        # Test cannot add collaborator when app is private.
        with pytest.raises(PrivateAppException) as excinfo:
            project.assign_role("read", collabs[0].user)

        assert excinfo.value.todict() == {
            "upgrade_to": "pro",
            "resource": PrivateAppException.resource,
            "test_name": "make_app_private",
            "msg": PrivateAppException.msg,
        }
        assert (get_perms(collabs[0].user, project) == []
                and project.role(collabs[1].user) == None)

        # Unable for free users to make apps private.
        with pytest.raises(PrivateAppException):
            project.make_private_test()

        # Test no limit on collaborators when app is public.
        project.is_public = True
        project.save()

        for collab in collabs:
            project.assign_role("read", collab.user)
            assert (get_perms(collab.user, project) == ["read_project"]
                    and project.role(collab.user) == "read")

        with pytest.raises(PrivateAppException):
            project.make_private_test()
Example #6
0
    def test_private_app_restrictions(self, api_client):
        post_data = {
            "title": "New-Model",
            "oneliner": "oneliner",
            "description": "**Super** new!",
            "repo_url": "https://github.com/compute-tooling/compute-studio",
            "repo_tag": "dev",
            "cpu": 3,
            "memory": 9,
            "listed": True,
            "is_public": False,
        }

        (free_user, ) = gen_collabs(1)
        api_client.force_login(free_user.user)
        with mock_sync_projects():
            resp = api_client.post("/apps/api/v1/", post_data)
        assert resp.status_code == 400
        data = resp.json()
        assert "make_app_private" == data["app"]["test_name"]

        with pytest.raises(Project.DoesNotExist):
            Project.objects.get(title="New-Model")

        post_data["is_public"] = True
        with mock_sync_projects():
            resp = api_client.post("/apps/api/v1/", post_data)
        assert resp.status_code == 200

        with mock_sync_projects():
            resp = api_client.put(
                f"/apps/api/v1/{free_user}/New-Model/",
                {"is_public": False},
            )
        assert resp.status_code == 400
        data = resp.json()
        assert "make_app_private" == data["app"]["test_name"]
def test_add_authors(db, get_inputs, meta_param_dict, pro_profile):
    inputs = _submit_inputs("Used-for-testing", get_inputs, meta_param_dict,
                            pro_profile)

    _, submit_sim = _submit_sim(inputs)
    sim = submit_sim.submit()
    sim.status = "SUCCESS"
    sim.is_public = False
    sim.save()

    collab = next(gen_collabs(1))

    assert not sim.has_read_access(collab.user)

    # Create new pending permission object and make sure that read access was
    # granted appropriately.
    pp, created = PendingPermission.objects.get_or_create(
        sim=sim, profile=collab, permission_name="add_author")
    assert created
    assert not pp.is_expired()
    assert sim.has_read_access(collab.user)
    assert get_perms(collab.user, sim) == ["read_simulation"]

    sim = Simulation.objects.get(pk=sim.pk)
    assert sim.pending_permissions.filter(id=pp.id).count() == 1

    assert sim.authors.all().count() == 1 and sim.authors.get(
        pk=pro_profile.pk)

    pp.add_author()

    sim = Simulation.objects.get(pk=sim.pk)
    assert sim.authors.all().count() == 2 and sim.authors.get(
        pk=collab.pk) == collab

    assert PendingPermission.objects.filter(id=pp.id).count() == 0
def test_sim_permissions(db, get_inputs, meta_param_dict, pro_profile):
    collab = next(gen_collabs(1))
    inputs = _submit_inputs("Used-for-testing", get_inputs, meta_param_dict,
                            pro_profile)

    _, submit_sim = _submit_sim(inputs)
    sim = submit_sim.submit()
    sim.status = "SUCCESS"
    sim.is_public = False
    sim.save()

    # check permissions for owner and random profile
    assert get_perms(sim.owner.user, sim) == ["admin_simulation"]
    assert sim.role(sim.owner.user) == "admin"
    assert get_perms(collab.user, sim) == []
    assert sim.role(collab.user) is None

    # sim owner has all levels of access
    assert (sim.is_owner(sim.owner.user)
            and sim.has_admin_access(sim.owner.user)
            and sim.has_write_access(sim.owner.user)
            and sim.has_read_access(sim.owner.user))
    # random user has no access
    assert (not sim.is_owner(collab.user)
            and not sim.has_admin_access(collab.user)
            and not sim.has_write_access(collab.user)
            and not sim.has_read_access(collab.user))
    # None has no access and does not cause errors
    assert (not sim.is_owner(None) and not sim.has_admin_access(None)
            and not sim.has_write_access(None)
            and not sim.has_read_access(None))

    # test grant/removal of read access.
    sim.grant_read_permissions(collab.user)
    assert (get_perms(collab.user, sim) == ["read_simulation"]
            and sim.role(collab.user) == "read")
    assert (not sim.is_owner(collab.user)
            and not sim.has_admin_access(collab.user)
            and not sim.has_write_access(collab.user)
            and sim.has_read_access(collab.user))
    sim.remove_permissions(collab.user)
    assert get_perms(collab.user, sim) == [] and sim.role(collab.user) is None
    assert (not sim.is_owner(collab.user)
            and not sim.has_admin_access(collab.user)
            and not sim.has_write_access(collab.user)
            and not sim.has_read_access(collab.user))

    # test grant/remove are idempotent:
    for _ in range(3):
        sim.grant_read_permissions(collab.user)
        assert sim.has_read_access(collab.user)
    for _ in range(3):
        sim.remove_permissions(collab.user)
        assert not sim.has_read_access(collab.user)

    # test that only one permission is applied at a time.
    sim.grant_read_permissions(collab.user)
    assert get_perms(collab.user, sim) == ["read_simulation"]
    sim.grant_write_permissions(collab.user)
    assert get_perms(collab.user, sim) == ["write_simulation"]
    sim.grant_admin_permissions(collab.user)
    assert get_perms(collab.user, sim) == ["admin_simulation"]

    sim.is_public = True
    sim.save()
    assert sim.has_read_access(pro_profile.user)
    assert sim.has_read_access(collab.user)
    assert sim.has_read_access(None) is True

    # test role
    sim.is_public = False
    sim.save()
    sim.assign_role("admin", collab.user)
    assert sim.has_admin_access(collab.user) and sim.role(
        collab.user) == "admin"
    sim.assign_role("write", collab.user)
    assert sim.has_write_access(collab.user) and sim.role(
        collab.user) == "write"
    sim.assign_role("read", collab.user)
    assert sim.has_read_access(collab.user) and sim.role(collab.user) == "read"
    sim.assign_role(None, collab.user)
    assert not sim.has_read_access(collab.user) and sim.role(
        collab.user) == None

    with pytest.raises(ValueError):
        sim.assign_role("dne", collab.user)
def test_sim_fork(db, get_inputs, meta_param_dict, is_public):
    (profile, ) = gen_collabs(1, plan="pro")
    modeler = User.objects.get(username="******").profile
    inputs = _submit_inputs("Used-for-testing", get_inputs, meta_param_dict,
                            modeler)

    _, submit_sim = _submit_sim(inputs)
    sim = submit_sim.submit()

    sim.inputs.status = "SUCCESS"
    sim.inputs.save()

    sim.outputs = "hello world"
    sim.status = "SUCCESS"
    sim.is_public = is_public
    sim.save()

    next_model_pk = Simulation.objects.next_model_pk(sim.project)
    newsim = Simulation.objects.fork(sim, profile.user)
    assert newsim.owner != sim.owner
    assert newsim.inputs.owner == newsim.owner and newsim.inputs.owner != sim.owner
    assert newsim.model_pk == next_model_pk
    assert float(newsim.run_cost) == 0.0
    assert newsim.parent_sim == newsim.inputs.parent_sim == sim

    if not sim.is_public:
        # make sure each sim's owner has read access and that the
        # read access for the new sim only applies to the owner
        # of the new sim and not the owner of the old sim.
        assert newsim.has_admin_access(newsim.owner.user)
        assert sim.has_admin_access(sim.owner.user)
        assert newsim.is_public == False
        # newsim.save()
        assert not newsim.has_read_access(sim.owner.user)

    def objects_eq(obj1, obj2, fields_to_exclude):
        data1 = model_to_dict(obj1)
        data2 = model_to_dict(obj2)
        for field in data1:
            if field in fields_to_exclude:
                continue
            assert (data1[field] == data2[field]
                    ), f"At {field}: {data1[field]} != {data2[field]}"

    fields_to_exclude = ["id", "owner", "job_id", "parent_sim"]
    objects_eq(sim.inputs, newsim.inputs, fields_to_exclude)

    fields_to_exclude += [
        "inputs", "run_cost", "model_pk", "creation_date", "authors"
    ]
    objects_eq(sim, newsim, fields_to_exclude)

    sim.status = "PENDING"
    sim.save()
    with pytest.raises(ForkObjectException):
        Simulation.objects.fork(sim, profile.user)

    sim.inputs.status = "PENDING"
    sim.inputs.save()
    with pytest.raises(ForkObjectException):
        Simulation.objects.fork(sim, profile.user)
Example #10
0
    def test_put_detail_api(
        self,
        client,
        api_client,
        test_models,
        password,
        visibility_params,
    ):
        owner, is_public = visibility_params
        put_data = {
            "title": "Used-for-testing",
            "oneliner": "oneliner",
            "description": "hello world!",
            "repo_url": "https://github.com/compute-tooling/compute-studio",
            "repo_tag": "dev",
            "cpu": 2,
            "memory": 6,
            "lastet_tag": "v2",
            "is_public": is_public,
        }
        project = Project.objects.get(owner=owner, title="Used-for-testing")
        project.is_public = is_public
        project.save()

        # not logged in --> not authorized
        resp = api_client.put(
            f"/apps/api/v1/{owner}/Used-for-testing/",
            data=put_data,
            content_type="application/json",
        )
        assert resp.status_code == 401

        # not the owner --> not authorized
        client.login(username="******", password="******")
        resp = client.put(
            f"/apps/api/v1/{owner}/Used-FOR-testing/",
            data=put_data,
            content_type="application/json",
        )
        exp_notauthed_code = 403 if is_public else 404
        assert resp.status_code == exp_notauthed_code

        # logged in and owner --> do update
        client.force_login(owner.user)
        with mock_sync_projects():
            resp = client.put(
                f"/apps/api/v1/{owner}/Used-for-testing/",
                data=put_data,
                content_type="application/json",
            )
        assert resp.status_code == 200
        project = Project.objects.get(title="Used-for-testing", owner=owner)
        assert project.description == put_data["description"]
        assert project.status == "running"

        # test add write_project permission allows update
        put_data["description"] = "hello world!!"
        (collab, ) = gen_collabs(1)
        client.force_login(collab.user)
        with mock_sync_projects():
            resp = client.put(
                f"/apps/api/v1/{owner}/Used-for-testing/",
                data=put_data,
                content_type="application/json",
            )
        # make sure "tester" doesn't have access already.
        assert resp.status_code == exp_notauthed_code

        project = Project.objects.get(title="Used-for-testing", owner=owner)
        project.assign_role("write", collab.user)
        with mock_sync_projects():
            resp = client.put(
                f"/apps/api/v1/{owner}/Used-for-testing/",
                data=put_data,
                content_type="application/json",
            )
        assert resp.status_code == 200
        project = Project.objects.get(title="Used-for-testing", owner=owner)
        assert project.description == put_data["description"]
Example #11
0
    def test_project_permissions(self, db, project, pro_profile):
        collab = next(gen_collabs(1))
        project.is_public = False
        replace_owner(project, pro_profile)

        # check permissions for owner and random profile
        assert get_perms(project.owner.user, project) == ["admin_project"]
        assert project.role(project.owner.user) == "admin"
        assert get_perms(collab.user, project) == []
        assert project.role(collab.user) is None

        # project owner has all levels of access
        assert (project.is_owner(project.owner.user)
                and project.has_admin_access(project.owner.user)
                and project.has_write_access(project.owner.user)
                and project.has_read_access(project.owner.user))
        # random user has no access
        assert (not project.is_owner(collab.user)
                and not project.has_admin_access(collab.user)
                and not project.has_write_access(collab.user)
                and not project.has_read_access(collab.user))
        # None has no access and does not cause errors
        assert (not project.is_owner(None)
                and not project.has_admin_access(None)
                and not project.has_write_access(None)
                and not project.has_read_access(None))

        # test grant/removal of read access.
        project.grant_read_permissions(collab.user)
        assert (get_perms(collab.user, project) == ["read_project"]
                and project.role(collab.user) == "read")
        assert (not project.is_owner(collab.user)
                and not project.has_admin_access(collab.user)
                and not project.has_write_access(collab.user)
                and project.has_read_access(collab.user))
        project.remove_permissions(collab.user)
        assert (get_perms(collab.user, project) == []
                and project.role(collab.user) is None)
        assert (not project.is_owner(collab.user)
                and not project.has_admin_access(collab.user)
                and not project.has_write_access(collab.user)
                and not project.has_read_access(collab.user))

        # test grant/remove are idempotent:
        for _ in range(3):
            project.grant_read_permissions(collab.user)
            assert project.has_read_access(collab.user)
        for _ in range(3):
            project.remove_permissions(collab.user)
            assert not project.has_read_access(collab.user)

        # test that only one permission is applied at a time.
        project.grant_read_permissions(collab.user)
        assert get_perms(collab.user, project) == ["read_project"]
        project.grant_write_permissions(collab.user)
        assert get_perms(collab.user, project) == ["write_project"]
        project.grant_admin_permissions(collab.user)
        assert get_perms(collab.user, project) == ["admin_project"]

        project.is_public = True
        project.save()
        assert project.has_read_access(pro_profile.user)
        assert project.has_read_access(collab.user)
        assert project.has_read_access(None) is True

        # test role
        project.is_public = False
        project.save()
        project.assign_role("admin", collab.user)
        assert (project.has_admin_access(collab.user)
                and project.role(collab.user) == "admin")
        project.assign_role("write", collab.user)
        assert (project.has_write_access(collab.user)
                and project.role(collab.user) == "write")
        project.assign_role("read", collab.user)
        assert (project.has_read_access(collab.user)
                and project.role(collab.user) == "read")
        project.assign_role(None, collab.user)
        assert (not project.has_read_access(collab.user)
                and project.role(collab.user) == None)

        with pytest.raises(ValueError):
            project.assign_role("dne", collab.user)