예제 #1
0
def create_providers(data, db_session):
    s = db_session
    providers = data["providers"]
    for provider in providers:
        prov = CloudProvider()
        prov.name = provider["name"]
        prov.backend = provider["backend"]
        prov.service = provider["service"]
        s.add(prov)
        s.flush

    for name, user in list(data["users"].items()):
        new_user = User()
        new_user.username = name
        new_user.email = user["email"]
        new_user.is_admin = user["is_admin"]
        s.add(new_user)
        user["id"] = new_user.id

    for project in data["projects"]:
        new_project = Project()
        new_project.name = project["name"]
        s.add(new_project)
        for storage in project["storage_access"]:
            provider = s.query(CloudProvider).filter_by(name=storage).first()
            if provider:
                new_storage_access = StorageAccess(provider_id=provider.id,
                                                   project_id=new_project.id)
                s.add(new_storage_access)

        for bucket in project["buckets"]:
            new_bucket = Bucket()
            new_bucket.name = bucket["name"]
            provider = s.query(CloudProvider).filter_by(
                name=bucket["provider"]).first()
            new_bucket.provider_id = provider.id
            s.add(new_bucket)
            s.flush()
            project_to_bucket = ProjectToBucket()
            project_to_bucket.bucket_id = new_bucket.id
            project_to_bucket.project_id = new_project.id
            s.add(project_to_bucket)
            s.flush()
        for user in project["users"]:
            access = AccessPrivilege()
            access.user_id = data["users"][user["name"]]["id"]
            access.project_id = new_project.id
            s.add(access)
예제 #2
0
def test_invalid_service_account_has_external_access(
    client,
    app,
    encoded_jwt_service_accounts_access,
    valid_service_account_patcher,
    valid_google_project_patcher,
    db_session,
    cloud_manager,
):
    """
    Test that an invalid service account gives us the expected error structure
    """
    sa_patcher = valid_service_account_patcher
    proj_patcher = valid_google_project_patcher
    sa_patcher["service_account_has_external_access"].return_value = True
    proj_patcher[
        "get_service_account_ids_from_google_members"].return_value = [
            "*****@*****.**"
        ]
    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]

    (cloud_manager.return_value.__enter__.return_value.get_service_account.
     return_value) = {
         "uniqueId": "0",
         "email": "*****@*****.**"
     }

    db_session.add(Project(auth_id="project_a"))
    db_session.add(Project(auth_id="project_b"))
    db_session.commit()
    project_access = ["project_a", "project_b"]

    invalid_service_account = {
        "service_account_email": "*****@*****.**",
        "google_project_id": "some-google-project-872340ajsdkj",
        "project_access": project_access,
    }

    response = client.post(
        "/google/service_accounts",
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(invalid_service_account),
        content_type="application/json",
    )

    assert response.status_code == 400
    _assert_expected_error_response_structure(response, project_access)
    assert response.json["errors"]["service_account_email"]["status"] == 403
예제 #3
0
def create_awg_user(users, db_session):
    s = db_session
    for username in list(users.keys()):
        user = query_for_user(session=s, username=username)
        if not user:
            user = User(username=username)
            s.add(user)

        projects = {}
        for project_data in users[username]["projects"]:
            auth_id = project_data["auth_id"]
            p_name = project_data.get("name", auth_id)

            project = s.query(Project).filter(Project.auth_id == auth_id).first()
            if not project:
                project = Project(name=p_name, auth_id=auth_id)
                s.add(project)
            projects[p_name] = project

        groups = users[username].get("groups", [])
        for group in groups:
            group_name = group["name"]
            group_desc = group["description"]
            grp = s.query(Group).filter(Group.name == group_name).first()
            if not grp:
                grp = Group()
                grp.name = group_name
                grp.description = group_desc
                s.add(grp)
                s.flush()
            UserToGroup(group=grp, user=user)
            for projectname in group["projects"]:
                gap = (
                    s.query(AccessPrivilege)
                    .join(AccessPrivilege.project)
                    .join(AccessPrivilege.group)
                    .filter(Project.name == projectname, Group.name == group_name)
                    .first()
                )
                if not gap:
                    project = projects[projectname]
                    gap = AccessPrivilege(project_id=project.id, group_id=grp.id)
                    s.add(gap)
                    s.flush()
                ap = (
                    s.query(AccessPrivilege)
                    .join(AccessPrivilege.project)
                    .join(AccessPrivilege.user)
                    .filter(Project.name == projectname, User.username == user.username)
                    .first()
                )
                privilege = {"read"}
                if not ap:
                    project = projects[projectname]
                    ap = AccessPrivilege(
                        project=project, user=user, privilege=privilege
                    )
                    s.add(ap)
                    s.flush()
    return user.id, user.username
예제 #4
0
def test_project(db_session):

    project = Project(id=1, name="test_project", auth_id="test_project")
    db_session.add(project)
    db_session.commit()

    yield project
예제 #5
0
def create_awg_groups(data, db_session):
    s = db_session
    projects = {}
    for project_data in data["projects"]:
        auth_id = project_data["auth_id"]
        p_name = project_data.get("name", auth_id)

        project = s.query(Project).filter(Project.auth_id == auth_id).first()
        if not project:
            project = Project(name=p_name, auth_id=auth_id)
            s.add(project)
        projects[p_name] = project

    for group in data["groups"]:
        group_name = group["name"]
        group_desc = group["description"]
        grp = s.query(Group).filter(Group.name == group_name).first()
        if not grp:
            grp = Group()
            grp.name = group_name
            grp.description = group_desc
            s.add(grp)

        for projectname in group["projects"]:
            gap = (s.query(AccessPrivilege).join(
                AccessPrivilege.project).join(AccessPrivilege.group).filter(
                    Project.name == projectname,
                    Group.name == group_name).first())
            if not gap:
                project = projects[projectname]
                gap = AccessPrivilege(project_id=project.id, group_id=grp.id)
                s.add(gap)
                s.flush()
예제 #6
0
def create_user(users, db_session, is_admin=False):
    s = db_session
    for username in list(users.keys()):
        user = query_for_user(session=s, username=username)
        if not user:
            user = User(username=username, is_admin=is_admin)
            s.add(user)
        for project_data in users[username]["projects"]:
            privilege = project_data["privilege"]
            auth_id = project_data["auth_id"]
            p_name = project_data.get("name", auth_id)

            project = s.query(Project).filter(
                Project.auth_id == auth_id).first()
            if not project:
                project = Project(name=p_name, auth_id=auth_id)
                s.add(project)
            ap = (s.query(AccessPrivilege).join(
                AccessPrivilege.project).join(AccessPrivilege.user).filter(
                    Project.name == p_name,
                    User.username == user.username).first())
            if not ap:
                ap = AccessPrivilege(project=project,
                                     user=user,
                                     privilege=privilege)
                s.add(ap)
            else:
                ap.privilege = privilege

    return user.id, user.username
예제 #7
0
def test_valid_google_project_access(valid_google_project_patcher,
                                     valid_service_account_patcher,
                                     db_session):
    """
    Test that when everything is valid and there are access to data through
    projects (access is all valid), the GoogleProjectValidity is valid
    and has the expected information.
    """
    patcher = valid_google_project_patcher

    project1 = Project(auth_id="some-project-auth-id")
    project2 = Project(auth_id="some-other-project-auth-id")
    db_session.add(project1)
    db_session.add(project2)
    db_session.commit()

    patcher["get_project_access_from_service_accounts"].return_value = [
        project1,
        project2,
    ]

    google_project_validity = GoogleProjectValidity("some-project-id")

    # should evaluate to true by default before checking validity
    assert google_project_validity

    google_project_validity.check_validity(early_return=False)

    # should evaluate to true since it's valid
    assert google_project_validity

    # test that it contains the correct error information
    assert "valid_parent_org" in google_project_validity
    assert google_project_validity["valid_parent_org"]

    assert "valid_member_types" in google_project_validity
    assert google_project_validity["valid_member_types"]

    assert "members_exist_in_fence" in google_project_validity
    assert google_project_validity["members_exist_in_fence"]

    assert "new_service_account" in google_project_validity
    assert "service_accounts" in google_project_validity
    assert "access" in google_project_validity
    assert hasattr(google_project_validity["access"], "__iter__")
    assert "some-project-auth-id" in (google_project_validity["access"])
    assert "some-other-project-auth-id" in (google_project_validity["access"])
예제 #8
0
def test_valid_get_google_project_parent_org(
    cloud_manager,
    client,
    app,
    encoded_jwt_service_accounts_access,
    valid_service_account_patcher,
    valid_google_project_patcher,
    db_session,
    monkeypatch,
):
    """
    Test that a valid service account gives us the expected response when it has
    parent org BUT that org is whitelisted.
    """

    monkeypatch.setitem(config, "WHITE_LISTED_GOOGLE_PARENT_ORGS",
                        ["whitelisted-parent-org"])

    (valid_google_project_patcher["get_google_project_parent_org"].return_value
     ) = "whitelisted-parent-org"
    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]

    db_session.add(Project(auth_id="project_a"))
    db_session.add(Project(auth_id="project_b"))
    db_session.commit()
    project_access = ["project_a", "project_b"]

    (cloud_manager.return_value.__enter__.return_value.get_service_account.
     return_value) = {
         "uniqueId": "0",
         "email": "*****@*****.**"
     }

    valid_service_account = {
        "service_account_email": "*****@*****.**",
        "google_project_id": "some-google-project-872340ajsdkj",
        "project_access": project_access,
    }

    response = client.post(
        "/google/service_accounts",
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(valid_service_account),
        content_type="application/json",
    )

    assert response.status_code == 200
예제 #9
0
def test_create_projects(db_session):
    # setup
    project_1_id = "123"
    project_1_name = "my-project-1"
    project_2_id = "456"
    project_2_name = "my-project-2"
    provider_id = "789"
    bucket_name = "my-bucket-2"

    cp = CloudProvider(
        id=provider_id,
        name=provider_id,
        endpoint="https://test.com",
        backend="test_backend",
        description="description",
        service="service",
    )
    db_session.add(cp)

    # only pre-create project 1
    p = Project(id=project_1_id, name=project_1_name)
    db_session.add(p)

    # only pre-create a StorageAccess for project 1
    sa = StorageAccess(project_id=project_1_id, provider_id=provider_id)
    db_session.add(sa)

    # only pre-create a Bucket for project 2
    b = Bucket(name=bucket_name, provider_id=provider_id)
    db_session.add(b)

    # test "fence-create create" projects creation
    data = {
        "projects": [
            {
                "id": project_1_id,
                "auth_id": "phs-project-1",
                "name": project_1_name,
                "storage_accesses": [{"name": provider_id, "buckets": ["my-bucket-1"]}],
            },
            {
                "id": project_2_id,
                "auth_id": "phs-project-2",
                "name": project_2_name,
                "storage_accesses": [{"name": provider_id, "buckets": [bucket_name]}],
            },
        ]
    }
    create_projects(db_session, data)

    projects_in_db = db_session.query(Project).all()
    assert projects_in_db, "no projects were created"
    assert len(projects_in_db) == len(data["projects"])
    project_names = {p.name for p in projects_in_db}
    assert project_1_name in project_names
    assert project_2_name in project_names
예제 #10
0
def test_patch_service_account_valid_limit(
    client,
    app,
    db_session,
    encoded_jwt_service_accounts_access,
    register_user_service_account,
    user_can_manage_service_account_mock,
    valid_user_service_account_mock,
    revoke_user_service_account_from_google_mock,
    add_user_service_account_to_google_mock,
):
    """
    Test that patching with new project_access returns 204
    when SERVICE_ACCOUNT_LIMIT number of projects is registered. 
    """
    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]
    service_account = register_user_service_account["service_account"]
    project_access = []
    n_projects = config["SERVICE_ACCOUNT_LIMIT"]
    for i in range(n_projects):
        project = Project(id=i, auth_id="auth_id_{}".format(i))

        bucket = Bucket(id=i)

        db_session.add(project)
        db_session.add(bucket)
        db_session.commit()

        project_to_bucket = ProjectToBucket(project_id=i, bucket_id=i)

        db_session.add(project_to_bucket)
        db_session.commit()

        gbag = GoogleBucketAccessGroup(id=i,
                                       bucket_id=i,
                                       email="*****@*****.**")

        db_session.add(gbag)
        db_session.commit()

        project_access.append("auth_id_{}".format(i))

    response = client.patch(
        "/google/service_accounts/{}".format(quote(service_account.email)),
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        content_type="application/json",
        data=json.dumps({"project_access": project_access}),
    )
    assert response.status_code == 204

    service_account_accesses = (
        db_session.query(ServiceAccountToGoogleBucketAccessGroup).filter_by(
            service_account_id=service_account.id)).all()

    assert len(service_account_accesses) == config["SERVICE_ACCOUNT_LIMIT"]
예제 #11
0
def test_delete_user_with_access_privilege(app, db_session):
    user = User(username="******")
    project = Project(id=1, name="test-project")
    access_privilege = AccessPrivilege(user=user, privilege=["read"], project=project)
    db_session.add(user)
    db_session.add(project)
    db_session.add(access_privilege)
    db_session.commit()
    delete_users(config["DB"], [user.username])
    remaining_usernames = db_session.query(User.username).all()
    assert db_session.query(User).count() == 0, remaining_usernames
def test_invalid_service_account_dry_run_errors(
    cloud_manager,
    client,
    app,
    encoded_jwt_service_accounts_access,
    valid_service_account_patcher,
    db_session,
):
    """
    Test that an invalid service account gives us the expected error structure
    """

    valid_service_account_patcher[
        "service_account_has_external_access"
    ].return_value = True

    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]

    db_session.add(Project(auth_id="project_a"))
    db_session.add(Project(auth_id="project_b"))
    db_session.commit()
    project_access = ["project_a", "project_b"]

    invalid_service_account = {
        "service_account_email": "*****@*****.**",
        "google_project_id": "some-google-project-872340ajsdkj",
        "project_access": project_access,
    }

    response = client.post(
        "/google/service_accounts/_dry_run",
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(invalid_service_account),
        content_type="application/json",
    )

    assert response.status_code != 200
    _assert_expected_error_response_structure(response, project_access)
예제 #13
0
def test_invalid_google_project_access(valid_google_project_patcher,
                                       db_session):
    """
    Test that when the Google Project is invalid, the resulting
    GoogleProjectValidity is False-y and contains the expected information.

    Here we're testing when the Google Project's members have invalid access.
    """
    patcher = valid_google_project_patcher

    project = Project(auth_id="some-project-auth-id")
    db_session.add(project)
    db_session.commit()

    patcher["get_project_access_from_service_accounts"].return_value = [
        project
    ]
    patcher["get_users_from_google_members"].return_value = ["test-user"]
    patcher["do_all_users_have_access_to_project"].return_value = False

    google_project_validity = GoogleProjectValidity("some-project-id")

    # should evaluate to true by default before checking validity
    assert google_project_validity

    google_project_validity.check_validity(early_return=False)

    # should evaluate to false since invalid
    assert not google_project_validity

    # test that it contains the correct error information
    assert "valid_parent_org" in google_project_validity
    assert google_project_validity["valid_parent_org"]

    assert "valid_member_types" in google_project_validity
    assert google_project_validity["valid_member_types"]

    assert "members_exist_in_fence" in google_project_validity
    assert google_project_validity["members_exist_in_fence"]

    assert "new_service_account" in google_project_validity
    assert "service_accounts" in google_project_validity
    assert "access" in google_project_validity
    assert hasattr(google_project_validity["access"], "__iter__")
    assert "some-project-auth-id" in (google_project_validity["access"])
    assert not google_project_validity["access"]["some-project-auth-id"]
예제 #14
0
def create_project(current_session, name, auth_id, storage_accesses):
    """
    Creates a project with an associated auth_id and storage access
    """
    new_project = Project(name=name, auth_id=auth_id)
    current_session.add(new_project)
    current_session.flush()
    for storage in storage_accesses:
        provider = current_session.query(CloudProvider).filter(
            CloudProvider.name == storage).first()
        if provider:
            new_storage_access = StorageAccess(provider_id=provider.id,
                                               project_id=new_project.id)
            current_session.add(new_storage_access)
        else:
            raise NotFound()
    return new_project
예제 #15
0
def setup_data(db_session):
    cp = CloudProvider(name="test", endpoint="http://test.endpt")
    user = UserServiceAccount(
        google_unique_id="test_id", email="*****@*****.**", google_project_id="test"
    )
    user_1 = UserServiceAccount(
        google_unique_id="test_id", email="*****@*****.**", google_project_id="test"
    )
    user_2 = UserServiceAccount(
        google_unique_id="test_id", email="*****@*****.**", google_project_id="test"
    )
    user_3 = UserServiceAccount(
        google_unique_id="test_id", email="*****@*****.**", google_project_id="test"
    )

    db_session.add(user)
    db_session.add(user_1)
    db_session.add(user_2)
    db_session.add(user_3)

    db_session.add(cp)
    db_session.commit()

    bucket = Bucket(name="bucket1", provider_id=cp.id)
    bucket2 = Bucket(name="bucket2", provider_id=cp.id)
    bucket3 = Bucket(name="bucket3", provider_id=cp.id)

    db_session.add(bucket)
    db_session.add(bucket2)
    db_session.add(bucket3)
    db_session.commit()

    project1 = Project(name="test_1", auth_id="test_auth_1")
    project2 = Project(name="test_2", auth_id="test_auth_2")
    project3 = Project(name="test_3", auth_id="test_auth_3")
    db_session.add(project1)
    db_session.add(project2)
    db_session.add(project3)
    db_session.commit()

    db_session.add(ProjectToBucket(project_id=project1.id, bucket_id=bucket.id))
    db_session.add(ProjectToBucket(project_id=project2.id, bucket_id=bucket2.id))
    db_session.add(ProjectToBucket(project_id=project3.id, bucket_id=bucket3.id))

    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project1.id, service_account_id=user.id
        )
    )
    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project2.id, service_account_id=user.id
        )
    )

    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project1.id, service_account_id=user_1.id
        )
    )
    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project1.id, service_account_id=user_2.id
        )
    )
    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project1.id, service_account_id=user_3.id
        )
    )

    access_grp = GoogleBucketAccessGroup(
        bucket_id=bucket.id, email="*****@*****.**"
    )

    access_grp2 = GoogleBucketAccessGroup(
        bucket_id=bucket2.id, email="*****@*****.**"
    )

    access_grp3 = GoogleBucketAccessGroup(
        bucket_id=bucket3.id, email="*****@*****.**"
    )

    db_session.add(access_grp)
    db_session.add(access_grp2)
    db_session.add(access_grp3)
    db_session.commit()

    service_account_grp1 = ServiceAccountToGoogleBucketAccessGroup(
        service_account_id=user.id, access_group_id=access_grp.id
    )

    service_account_grp2 = ServiceAccountToGoogleBucketAccessGroup(
        service_account_id=user.id, access_group_id=access_grp2.id
    )
    db_session.add(service_account_grp1)
    db_session.add(service_account_grp2)
    db_session.commit()
예제 #16
0
def test_invalid_project_limit_service_account_registration(
    app,
    db_session,
    client,
    encoded_jwt_service_accounts_access,
    cloud_manager,
    valid_google_project_patcher,
):
    """
    Test that we get a 400 when there are SERVICE_ACCOUNT_LIMIT + 1 number of projects and the databse isn't updated. 
    """
    proj_patcher = valid_google_project_patcher
    project_access = []
    n_projects = config["SERVICE_ACCOUNT_LIMIT"] + 1
    for i in range(n_projects):
        project = Project(id=i, auth_id="auth_id_{}".format(i))

        bucket = Bucket(id=i)

        db_session.add(project)
        db_session.add(bucket)
        db_session.commit()

        project_to_bucket = ProjectToBucket(project_id=i, bucket_id=i)

        db_session.add(project_to_bucket)
        db_session.commit()

        gbag = GoogleBucketAccessGroup(id=i,
                                       bucket_id=i,
                                       email="*****@*****.**")

        db_session.add(gbag)
        db_session.commit()

        project_access.append("auth_id_{}".format(i))

    google_project_id = "project-id"
    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]
    proj_patcher["get_service_account_ids_from_google_members"].return_value = [
        "test-{}@test.com".format(google_project_id),
        "{}@compute-system.iam.gserviceaccount.com".format(google_project_id),
    ]
    valid_service_account = {
        "service_account_email": "*****@*****.**",
        "google_project_id": google_project_id,
        "project_access": project_access,
    }

    (cloud_manager.return_value.__enter__.return_value.get_service_account.
     return_value) = {
         "uniqueId": "sa_unique_id",
         "email": "*****@*****.**"
     }

    (cloud_manager.return_value.__enter__.return_value.add_member_to_group.
     return_value) = {
         "email": "*****@*****.**"
     }

    assert len(db_session.query(UserServiceAccount).all()) == 0
    assert len(db_session.query(ServiceAccountAccessPrivilege).all()) == 0
    assert len(
        db_session.query(ServiceAccountToGoogleBucketAccessGroup).all()) == 0

    response = client.post(
        "/google/service_accounts",
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(valid_service_account),
        content_type="application/json",
    )

    assert response.status_code == 400

    assert len(db_session.query(UserServiceAccount).all()) == 0
    assert len(db_session.query(ServiceAccountAccessPrivilege).all()) == 0
    assert len(
        db_session.query(ServiceAccountToGoogleBucketAccessGroup).all()) == 0
예제 #17
0
def register_user_service_account(db_session):
    cp = db_session.query(CloudProvider).filter_by(name="test").first()
    if not cp:
        cp = CloudProvider(name="test", endpoint="http://test.endpt")
        db_session.add(cp)
        db_session.commit()

    bucket1 = db_session.query(Bucket).filter_by(name="bucket1").first()
    if not bucket1:
        bucket1 = Bucket(name="bucket1", provider_id=cp.id)
        db_session.add(bucket1)
        db_session.commit()

    bucket2 = db_session.query(Bucket).filter_by(name="bucket2").first()
    if not bucket2:
        bucket2 = Bucket(name="bucket2", provider_id=cp.id)
        db_session.add(bucket2)
        db_session.commit()

    project1 = db_session.query(Project).filter_by(name="test_1").first()
    if not project1:
        project1 = Project(name="test_1", auth_id="test_auth_1")
        db_session.add(project1)
        db_session.commit()

    project2 = db_session.query(Project).filter_by(name="test_2").first()
    if not project2:
        project2 = Project(name="test_2", auth_id="test_auth_2")
        db_session.add(project2)
        db_session.commit()

    access_grp1 = (
        db_session.query(GoogleBucketAccessGroup)
        .filter_by(email="*****@*****.**")
        .first()
    )
    if not access_grp1:
        access_grp1 = GoogleBucketAccessGroup(
            bucket_id=bucket1.id, email="*****@*****.**"
        )
        db_session.add(access_grp1)
        db_session.commit()

    access_grp2 = (
        db_session.query(GoogleBucketAccessGroup)
        .filter_by(email="*****@*****.**")
        .first()
    )
    if not access_grp2:
        access_grp2 = GoogleBucketAccessGroup(
            bucket_id=bucket2.id, email="*****@*****.**"
        )
        db_session.add(access_grp2)
        db_session.commit()

    project_to_bucket1 = (
        db_session.query(ProjectToBucket).filter_by(project_id=project1.id).first()
    )
    if not project_to_bucket1:
        project_to_bucket1 = ProjectToBucket(
            project_id=project1.id, bucket_id=bucket1.id
        )
        db_session.add(project_to_bucket1)
        db_session.commit()

    project_to_bucket2 = (
        db_session.query(ProjectToBucket).filter_by(project_id=project2.id).first()
    )
    if not project_to_bucket2:
        project_to_bucket2 = ProjectToBucket(
            project_id=project2.id, bucket_id=bucket2.id
        )
        db_session.add(project_to_bucket2)
        db_session.commit()

    # new service account each time this is called
    random_string = "".join(
        random.choice(string.ascii_uppercase + string.digits) for _ in range(6)
    )
    user = UserServiceAccount(
        google_unique_id="{}".format(random_string),
        email="{}@test.iam.gserviceaccount.com".format(random_string),
        google_project_id="test",
    )
    db_session.add(user)
    db_session.commit()

    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project1.id, service_account_id=user.id
        )
    )
    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project2.id, service_account_id=user.id
        )
    )

    # expiration set to 0 for testing that it gets set
    current_time = 0
    service_account_grp1 = ServiceAccountToGoogleBucketAccessGroup(
        service_account_id=user.id, access_group_id=access_grp1.id, expires=current_time
    )
    service_account_grp2 = ServiceAccountToGoogleBucketAccessGroup(
        service_account_id=user.id, access_group_id=access_grp2.id, expires=current_time
    )
    db_session.add(service_account_grp1)
    db_session.add(service_account_grp2)
    db_session.commit()

    return {
        "service_account": user,
        "projects": [project1, project2],
        "buckets": [bucket1, bucket2],
        "bucket_access_groups": [access_grp1, access_grp2],
    }
예제 #18
0
def invalid_service_account_not_exist(db_session):
    invalid_service_account = "*****@*****.**"
    user = UserServiceAccount(
        google_unique_id="invalid_test_id",
        email=invalid_service_account,
        google_project_id="test",
    )
    db_session.add(user)
    db_session.commit()

    cp = db_session.query(CloudProvider).filter_by(name="test").first()
    if not cp:
        cp = CloudProvider(name="test", endpoint="http://test.endpt")
        db_session.add(cp)
        db_session.commit()

    bucket1 = db_session.query(Bucket).filter_by(name="bucket1").first()
    if not bucket1:
        bucket1 = Bucket(name="bucket1", provider_id=cp.id)
        db_session.add(bucket1)
        db_session.commit()

    project1 = db_session.query(Project).filter_by(name="test_1").first()
    if not project1:
        project1 = Project(name="test_1", auth_id="test_auth_1")
        db_session.add(project1)
        db_session.commit()

    access_grp1 = (
        db_session.query(GoogleBucketAccessGroup)
        .filter_by(email="*****@*****.**")
        .first()
    )
    if not access_grp1:
        access_grp1 = GoogleBucketAccessGroup(
            bucket_id=bucket1.id, email="*****@*****.**"
        )
        db_session.add(access_grp1)
        db_session.commit()

    db_session.add(
        ServiceAccountAccessPrivilege(
            project_id=project1.id, service_account_id=user.id
        )
    )
    db_session.commit()

    # expiration set to 0 for testing that it gets set
    current_time = 0
    service_account_grp1 = ServiceAccountToGoogleBucketAccessGroup(
        service_account_id=user.id, access_group_id=access_grp1.id, expires=current_time
    )
    db_session.add(service_account_grp1)
    db_session.commit()

    def mock_is_valid(sa_email, *args, **kwargs):
        if sa_email == invalid_service_account:
            validity = GoogleServiceAccountValidity("account_id", "project_id")
            # set overall validity to False
            # set policy_accessible to False so the SA is removed from the DB
            validity["policy_accessible"] = False
            validity._valid = False
            return validity
        return True

    patcher = patch(
        "fence.scripting.google_monitor._is_valid_service_account", mock_is_valid
    )

    patcher.start()
    yield {
        "service_account": user,
        "projects": [project1],
        "bucket_access_groups": [access_grp1],
    }
    patcher.stop()
예제 #19
0
def test_register_service_account_already_exists(
    app,
    db_session,
    client,
    encoded_jwt_service_accounts_access,
    cloud_manager,
    valid_google_project_patcher,
    valid_service_account_patcher,
):

    project = Project(id=1, auth_id="some_auth_id")

    bucket = Bucket(id=1)

    db_session.add(project)
    db_session.add(bucket)
    db_session.commit()

    project_to_bucket = ProjectToBucket(project_id=1, bucket_id=1)

    db_session.add(project_to_bucket)
    db_session.commit()

    gbag = GoogleBucketAccessGroup(id=1, bucket_id=1, email="*****@*****.**")

    db_session.add(gbag)
    db_session.commit()

    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]
    project_access = ["some_auth_id"]
    valid_service_account = {
        "service_account_email": "*****@*****.**",
        "google_project_id": "project-id",
        "project_access": project_access,
    }

    (cloud_manager.return_value.__enter__.return_value.get_service_account.
     return_value) = {
         "uniqueId": "sa_unique_id",
         "email": "*****@*****.**"
     }

    (cloud_manager.return_value.__enter__.return_value.add_member_to_group.
     return_value) = {
         "email": "*****@*****.**"
     }

    response = client.post(
        "/google/service_accounts",
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(valid_service_account),
        content_type="application/json",
    )

    assert response.status_code == 200

    response = client.post(
        "/google/service_accounts",
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(valid_service_account),
        content_type="application/json",
    )

    assert response.status_code == 400
    assert response.json["errors"]["service_account_email"]["status"] == 409

    assert len(db_session.query(UserServiceAccount).all()) == 1
    assert len(db_session.query(ServiceAccountAccessPrivilege).all()) == 1
    assert len(
        db_session.query(ServiceAccountToGoogleBucketAccessGroup).all()) == 1
예제 #20
0
def test_valid_service_account_registration_multiple_service_accounts(
    app,
    db_session,
    client,
    encoded_jwt_service_accounts_access,
    cloud_manager,
    valid_google_project_patcher,
    valid_service_account_patcher,
):
    """
    Test that a valid service account registration request returns
    200 and succesfully creates entries in database when the Google project
    has both another valid service account in the project and a Google-managed
    system service account.
    """
    proj_patcher = valid_google_project_patcher
    project = Project(id=1, auth_id="some_auth_id")

    bucket = Bucket(id=1)

    db_session.add(project)
    db_session.add(bucket)
    db_session.commit()

    project_to_bucket = ProjectToBucket(project_id=1, bucket_id=1)

    db_session.add(project_to_bucket)
    db_session.commit()

    gbag = GoogleBucketAccessGroup(id=1, bucket_id=1, email="*****@*****.**")

    db_session.add(gbag)
    db_session.commit()

    google_project_id = "project-id"
    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]
    project_access = ["some_auth_id"]
    proj_patcher["get_service_account_ids_from_google_members"].return_value = [
        "test-{}@test.com".format(google_project_id),
        "{}@compute-system.iam.gserviceaccount.com".format(google_project_id),
    ]
    valid_service_account = {
        "service_account_email": "*****@*****.**",
        "google_project_id": google_project_id,
        "project_access": project_access,
    }

    (cloud_manager.return_value.__enter__.return_value.get_service_account.
     return_value) = {
         "uniqueId": "sa_unique_id",
         "email": "*****@*****.**"
     }

    (cloud_manager.return_value.__enter__.return_value.add_member_to_group.
     return_value) = {
         "email": "*****@*****.**"
     }

    assert len(db_session.query(UserServiceAccount).all()) == 0
    assert len(db_session.query(ServiceAccountAccessPrivilege).all()) == 0
    assert len(
        db_session.query(ServiceAccountToGoogleBucketAccessGroup).all()) == 0

    response = client.post(
        "/google/service_accounts",
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(valid_service_account),
        content_type="application/json",
    )

    assert response.status_code == 200

    assert len(db_session.query(UserServiceAccount).all()) == 1
    assert len(db_session.query(ServiceAccountAccessPrivilege).all()) == 1
    assert len(
        db_session.query(ServiceAccountToGoogleBucketAccessGroup).all()) == 1
예제 #21
0
def test_service_account_registration_expires_in(
    app,
    db_session,
    client,
    encoded_jwt_service_accounts_access,
    cloud_manager,
    valid_google_project_patcher,
    valid_service_account_patcher,
):
    """
    Test that a service account registration with a valid expires_in is
    successful, and that a registration with an invalid expires_in is not.
    """
    project = Project(id=1, auth_id="some_auth_id")

    bucket = Bucket(id=1)

    db_session.add(project)
    db_session.add(bucket)
    db_session.commit()

    project_to_bucket = ProjectToBucket(project_id=1, bucket_id=1)

    db_session.add(project_to_bucket)
    db_session.commit()

    gbag = GoogleBucketAccessGroup(id=1, bucket_id=1, email="*****@*****.**")

    db_session.add(gbag)
    db_session.commit()

    encoded_creds_jwt = encoded_jwt_service_accounts_access["jwt"]
    project_access = ["some_auth_id"]
    valid_service_account = {
        "service_account_email": "*****@*****.**",
        "google_project_id": "project-id",
        "project_access": project_access,
    }

    (cloud_manager.return_value.__enter__.return_value.get_service_account.
     return_value) = {
         "uniqueId": "sa_unique_id",
         "email": "*****@*****.**"
     }

    (cloud_manager.return_value.__enter__.return_value.add_member_to_group.
     return_value) = {
         "email": "*****@*****.**"
     }

    assert len(db_session.query(UserServiceAccount).all()) == 0
    assert len(db_session.query(ServiceAccountAccessPrivilege).all()) == 0
    assert len(
        db_session.query(ServiceAccountToGoogleBucketAccessGroup).all()) == 0

    # valid expires_in: should succeed
    requested_exp = 60

    response = client.post(
        "/google/service_accounts?expires_in={}".format(requested_exp),
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(valid_service_account),
        content_type="application/json",
    )
    assert response.status_code == 200  # check if success

    assert len(db_session.query(UserServiceAccount).all()) == 1
    assert len(db_session.query(ServiceAccountAccessPrivilege).all()) == 1
    sa_to_bucket_entries = db_session.query(
        ServiceAccountToGoogleBucketAccessGroup).all()
    assert len(sa_to_bucket_entries) == 1

    # make sure the access was granted for the requested time
    # (allow up to 2 sec for runtime)
    diff = sa_to_bucket_entries[0].expires - int(time.time())
    assert requested_exp - 2 <= diff <= requested_exp

    # invalid expires_in: should fail
    requested_exp = "abc"  # expires_in must be int >0

    response = client.post(
        "/google/service_accounts?expires_in={}".format(requested_exp),
        headers={"Authorization": "Bearer " + encoded_creds_jwt},
        data=json.dumps(valid_service_account),
        content_type="application/json",
    )
    assert response.status_code == 400  # check if failure