Ejemplo n.º 1
0
def test_create(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.add_user_to_group("*****@*****.**", "other-group")

    run_ctl(
        setup,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        "*****@*****.**",
        "some-group",
        "foo +bar -(org)",
        "this is a service account.\n\n it is for testing",
    )
    service_account = ServiceAccount.get(setup.session,
                                         name="*****@*****.**")
    assert service_account is not None
    assert service_account.user.name == "*****@*****.**"
    assert service_account.machine_set == "foo +bar -(org)"
    assert service_account.description == "this is a service account.\n\n it is for testing"
    group = Group.get(setup.session, name="some-group")
    assert group
    assert get_service_accounts(setup.session, group) == [service_account]

    # If the account already exists, creating it again returns an error and does nothing.
    with pytest.raises(SystemExit):
        run_ctl(
            setup,
            "service_account",
            "--actor",
            "*****@*****.**",
            "create",
            "*****@*****.**",
            "other-group",
            "foo",
            "another test",
        )
    service_account = ServiceAccount.get(setup.session,
                                         name="*****@*****.**")
    assert service_account is not None
    assert service_account.machine_set == "foo +bar -(org)"
    assert service_account.description == "this is a service account.\n\n it is for testing"
    group = Group.get(setup.session, name="some-group")
    assert group
    assert get_service_accounts(setup.session, group) == [service_account]
Ejemplo n.º 2
0
def test_create_as_service_account(setup):
    """Test that a service account can create another service account."""
    with setup.transaction():
        setup.create_group("some-group")
        setup.create_service_account("*****@*****.**", "another-group")
        setup.grant_permission_to_service_account(USER_ADMIN, "", "*****@*****.**")

    run_ctl(
        setup,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        "*****@*****.**",
        "some-group",
        "foo +bar -(org)",
        "this is a service account.\n\n it is for testing",
    )
    service_account = ServiceAccount.get(setup.session, name="*****@*****.**")
    assert service_account is not None
    assert service_account.user.name == "*****@*****.**"
    assert service_account.machine_set == "foo +bar -(org)"
    assert service_account.description == "this is a service account.\n\n it is for testing"
    group = Group.get(setup.session, name="some-group")
    assert get_service_accounts(setup.session, group) == [service_account]
Ejemplo n.º 3
0
def get_group_view_template_vars(session, actor, group, graph):
    # type: (Session, User, Group, GroupGraph) -> Dict[str, Any]
    ret = {}
    ret["grantable"] = user_grantable_permissions(session, actor)

    try:
        group_md = graph.get_group_details(group.name)
    except NoSuchGroup:
        # Very new group with no metadata yet, or it has been disabled and
        # excluded from in-memory cache.
        group_md = {}

    ret["members"] = group.my_members()
    ret["groups"] = group.my_groups()
    ret["service_accounts"] = get_service_accounts(session, group)
    ret["permissions"] = group_md.get("permissions", [])
    for permission in ret["permissions"]:
        permission["granted_on"] = datetime.fromtimestamp(permission["granted_on"])

    ret["permission_requests_pending"] = []
    for req in get_pending_request_by_group(session, group):
        granters = []
        for owner, argument in get_owner_arg_list(session, req.permission, req.argument):
            granters.append(owner.name)
        ret["permission_requests_pending"].append((req, granters))

    ret["audited"] = group_md.get("audited", False)
    ret["log_entries"] = group.my_log_entries()
    ret["num_pending"] = count_requests_by_group(session, group, status="pending")
    ret["current_user_role"] = {
        "is_owner": user_role_index(actor, ret["members"]) in OWNER_ROLE_INDICES,
        "is_approver": user_role_index(actor, ret["members"]) in APPROVER_ROLE_INDICES,
        "is_manager": user_role(actor, ret["members"]) == "manager",
        "is_member": user_role(actor, ret["members"]) is not None,
        "role": user_role(actor, ret["members"]),
    }
    ret["can_leave"] = (
        ret["current_user_role"]["is_member"] and not ret["current_user_role"]["is_owner"]
    )
    ret["statuses"] = AUDIT_STATUS_CHOICES

    # Add mapping_id to permissions structure
    ret["my_permissions"] = group.my_permissions()
    for perm_up in ret["permissions"]:
        for perm_direct in ret["my_permissions"]:
            if (
                perm_up["permission"] == perm_direct.name
                and perm_up["argument"] == perm_direct.argument
            ):
                perm_up["mapping_id"] = perm_direct.mapping_id
                break

    ret["alerts"] = []
    ret["self_pending"] = count_requests_by_group(session, group, status="pending", user=actor)
    if ret["self_pending"]:
        ret["alerts"].append(Alert("info", "You have a pending request to join this group.", None))

    return ret
Ejemplo n.º 4
0
def get_group_view_template_vars(session, actor, group, graph):
    ret = {}
    ret["grantable"] = user_grantable_permissions(session, actor)

    try:
        group_md = graph.get_group_details(group.name)
    except NoSuchGroup:
        # Very new group with no metadata yet, or it has been disabled and
        # excluded from in-memory cache.
        group_md = {}

    ret["members"] = group.my_members()
    ret["groups"] = group.my_groups()
    ret["service_accounts"] = get_service_accounts(session, group)
    ret["permissions"] = group_md.get('permissions', [])

    ret["permission_requests_pending"] = []
    for req in get_pending_request_by_group(session, group):
        granters = []
        for owner, argument in get_owner_arg_list(session, req.permission,
                                                  req.argument):
            granters.append(owner.name)
        ret["permission_requests_pending"].append((req, granters))

    ret["audited"] = group_md.get('audited', False)
    ret["log_entries"] = group.my_log_entries()
    ret["num_pending"] = group.my_requests("pending").count()
    ret["current_user_role"] = {
        'is_owner': user_role_index(actor,
                                    ret["members"]) in OWNER_ROLE_INDICES,
        'is_approver': user_role_index(actor, ret["members"])
        in APPROVER_ROLE_INDICES,
        'is_manager': user_role(actor, ret["members"]) == "manager",
        'is_member': user_role(actor, ret["members"]) is not None,
        'role': user_role(actor, ret["members"]),
    }
    ret["can_leave"] = (ret["current_user_role"]['is_member']
                        and not ret["current_user_role"]['is_owner'])
    ret["statuses"] = AUDIT_STATUS_CHOICES

    # Add mapping_id to permissions structure
    ret["my_permissions"] = group.my_permissions()
    for perm_up in ret["permissions"]:
        for perm_direct in ret["my_permissions"]:
            if (perm_up['permission'] == perm_direct.name
                    and perm_up['argument'] == perm_direct.argument):
                perm_up['mapping_id'] = perm_direct.mapping_id
                break

    ret["alerts"] = []
    ret["self_pending"] = group.my_requests("pending", user=actor).count()
    if ret["self_pending"]:
        ret["alerts"].append(
            Alert('info', 'You have a pending request to join this group.',
                  None))

    return ret
Ejemplo n.º 5
0
def test_create_invalid_actor(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.create_group("some-group")

    with pytest.raises(SystemExit):
        run_ctl(
            setup,
            "service_account",
            "--actor",
            "*****@*****.**",
            "create",
            "*****@*****.**",
            "some-group",
            "foo",
            "another test",
        )

    assert ServiceAccount.get(setup.session, name="*****@*****.**") is None
    group = Group.get(setup.session, name="some-group")
    assert get_service_accounts(setup.session, group) == []
Ejemplo n.º 6
0
def test_service_account_create(groups, service_accounts, session, tmpdir, users):  # noqa: F811
    machine_set = "foo +bar -(org)"
    description = "this is a service account.\n\n it is for testing"
    security_team_group = Group.get(session, name="security-team")
    good_actor_username = "******"
    good_service_account_name = "*****@*****.**"

    assert ServiceAccount.get(session, name=good_service_account_name) is None
    assert get_service_accounts(session, security_team_group) == []
    # no-op if non-existing actor
    call_main(
        session,
        tmpdir,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        good_service_account_name,
        security_team_group.groupname,
        machine_set,
        description,
    )
    # ... or if bad account name
    call_main(
        session,
        tmpdir,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        "bad-service-account-name",
        security_team_group.groupname,
        machine_set,
        description,
    )
    # ... or non-existing owner group
    call_main(
        session,
        tmpdir,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        good_service_account_name,
        "non-such-owner-group",
        machine_set,
        description,
    )
    # make sure no change was made
    assert ServiceAccount.get(session, name=good_service_account_name) is None
    assert get_service_accounts(session, security_team_group) == []

    # now it works
    call_main(
        session,
        tmpdir,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        good_service_account_name,
        security_team_group.groupname,
        machine_set,
        description,
    )
    service_account = ServiceAccount.get(session, name=good_service_account_name)
    assert service_account, "non-existing account should be created"
    assert service_account.user.name == good_service_account_name
    assert service_account.machine_set == machine_set
    assert service_account.description == description
    assert get_service_accounts(session, security_team_group) == [service_account]

    # no-op if account name already exists
    call_main(
        session,
        tmpdir,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        good_service_account_name,
        security_team_group.groupname,
        machine_set,
        description,
    )
    service_account = ServiceAccount.get(session, name=good_service_account_name)
    assert service_account, "non-account should be created"
    assert service_account.user.name == good_service_account_name
    assert service_account.machine_set == machine_set
    assert service_account.description == description
    assert get_service_accounts(session, security_team_group) == [service_account]

    # actor can be a service account as well
    call_main(
        session,
        tmpdir,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        "*****@*****.**",
        security_team_group.groupname,
        machine_set + "2",
        description + "2",
    )
    service_account_2 = ServiceAccount.get(session, name="*****@*****.**")
    assert service_account_2, "non-existing account should be created"
    assert service_account_2.user.name == "*****@*****.**"
    assert service_account_2.machine_set == (machine_set + "2")
    assert service_account_2.description == (description + "2")
    assert set(get_service_accounts(session, security_team_group)) == set(
        [service_account, service_account_2]
    )
Ejemplo n.º 7
0
def test_service_accounts(
        session,
        standard_graph,
        graph,
        users,
        groups,
        permissions  # noqa: F811
):
    # Create a service account.
    service_account = ServiceAccount.get(session, name="*****@*****.**")
    assert service_account.description == "some service account"
    assert service_account.machine_set == "some machines"
    assert service_account.user.name == "*****@*****.**"
    assert service_account.user.enabled == True
    assert service_account.user.is_service_account == True
    accounts = get_service_accounts(session, groups["team-sre"])
    assert len(accounts) == 1
    assert accounts[0].user.name == "*****@*****.**"
    assert is_service_account(session, service_account.user)

    # Duplicates should raise an exception.
    with pytest.raises(DuplicateServiceAccount):
        create_service_account(session, users["*****@*****.**"], "*****@*****.**",
                               "dup", "dup", groups["team-sre"])

    # zorkian should be able to manage the account, as should gary, but oliver (not a member of the
    # group) should not.
    assert can_manage_service_account(session, service_account,
                                      users["*****@*****.**"])
    assert can_manage_service_account(session, service_account,
                                      users["*****@*****.**"])
    assert not can_manage_service_account(session, service_account,
                                          users["*****@*****.**"])

    # Check that the user appears in the graph.
    graph.update_from_db(session)
    metadata = graph.user_metadata["*****@*****.**"]
    assert metadata["enabled"]
    assert metadata["service_account"]["description"] == "some service account"
    assert metadata["service_account"]["machine_set"] == "some machines"
    assert metadata["service_account"]["owner"] == "team-sre"
    group_details = graph.get_group_details("team-sre")
    assert group_details["service_accounts"] == ["*****@*****.**"]

    # Grant a permission to the service account and check it in the graph.
    grant_permission_to_service_account(session, service_account,
                                        permissions["team-sre"], "*")
    graph.update_from_db(session)
    user_details = graph.get_user_details("*****@*****.**")
    assert user_details["permissions"][0]["permission"] == "team-sre"
    assert user_details["permissions"][0]["argument"] == "*"

    # Diabling the service account should remove the link to the group.
    disable_service_account(session, users["*****@*****.**"], service_account)
    assert service_account.user.enabled == False
    assert get_service_accounts(session, groups["team-sre"]) == []

    # The user should also be gone from the graph and have its permissions removed.
    graph.update_from_db(session)
    group_details = graph.get_group_details("team-sre")
    assert "service_accounts" not in group_details
    metadata = graph.user_metadata["*****@*****.**"]
    assert not metadata["enabled"]
    assert "owner" not in metadata["service_account"]
    user_details = graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []

    # We can re-enable and attach to a different group.
    new_group = groups["security-team"]
    enable_service_account(session, users["*****@*****.**"], service_account,
                           new_group)
    assert service_account.user.enabled == True
    assert get_service_accounts(session, groups["team-sre"]) == []
    accounts = get_service_accounts(session, new_group)
    assert len(accounts) == 1
    assert accounts[0].user.name == "*****@*****.**"

    # Check that this is reflected in the graph and the user has no permissions.
    graph.update_from_db(session)
    group_details = graph.get_group_details("security-team")
    assert group_details["service_accounts"] == ["*****@*****.**"]
    metadata = graph.user_metadata["*****@*****.**"]
    assert metadata["service_account"]["owner"] == "security-team"
    user_details = graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []
Ejemplo n.º 8
0
def get_group_view_template_vars(session, actor, group, graph):
    # type: (Session, User, Group, GroupGraph) -> Dict[str, Any]
    ret = {}
    ret["grantable"] = user_grantable_permissions(session, actor)

    try:
        group_md = graph.get_group_details(group.name)
    except NoSuchGroup:
        # Very new group with no metadata yet, or it has been disabled and
        # excluded from in-memory cache.
        group_md = {}

    ret["members"] = group.my_members()
    ret["groups"] = group.my_groups()
    ret["service_accounts"] = get_service_accounts(session, group)
    ret["permissions"] = group_md.get("permissions", [])
    for permission in ret["permissions"]:
        permission["granted_on"] = datetime.fromtimestamp(
            permission["granted_on"])

    ret["permission_requests_pending"] = []
    for req in get_pending_request_by_group(session, group):
        granters = []
        for owner, argument in get_owner_arg_list(session, req.permission,
                                                  req.argument):
            granters.append(owner.name)
        ret["permission_requests_pending"].append((req, granters))

    ret["audited"] = group_md.get("audited", False)
    ret["log_entries"] = group.my_log_entries()
    ret["num_pending"] = count_requests_by_group(session,
                                                 group,
                                                 status="pending")
    ret["current_user_role"] = {
        "is_owner": user_role_index(actor,
                                    ret["members"]) in OWNER_ROLE_INDICES,
        "is_approver": user_role_index(actor, ret["members"])
        in APPROVER_ROLE_INDICES,
        "is_manager": user_role(actor, ret["members"]) == "manager",
        "is_member": user_role(actor, ret["members"]) is not None,
        "role": user_role(actor, ret["members"]),
    }
    ret["can_leave"] = (ret["current_user_role"]["is_member"]
                        and not ret["current_user_role"]["is_owner"])
    ret["statuses"] = AUDIT_STATUS_CHOICES

    # Add mapping_id to permissions structure
    ret["my_permissions"] = group.my_permissions()
    for perm_up in ret["permissions"]:
        for perm_direct in ret["my_permissions"]:
            if (perm_up["permission"] == perm_direct.name
                    and perm_up["argument"] == perm_direct.argument):
                perm_up["mapping_id"] = perm_direct.mapping_id
                break

    ret["alerts"] = []
    ret["self_pending"] = count_requests_by_group(session,
                                                  group,
                                                  status="pending",
                                                  user=actor)
    if ret["self_pending"]:
        ret["alerts"].append(
            Alert("info", "You have a pending request to join this group.",
                  None))

    return ret
Ejemplo n.º 9
0
def test_service_accounts(setup):
    # type: (SetupTest) -> None
    """Tests remaining non-usecase service account functions."""
    with setup.transaction():
        setup.create_service_account("*****@*****.**", "team-sre",
                                     "some machines", "some service account")
        setup.add_user_to_group("*****@*****.**", "team-sre", "owner")
        setup.add_user_to_group("*****@*****.**", "admins")
        setup.grant_permission_to_group(USER_ADMIN, "", "admins")
        setup.add_user_to_group("*****@*****.**", "team-sre")
        setup.create_user("*****@*****.**")
        setup.grant_permission_to_service_account("team-sre", "*",
                                                  "*****@*****.**")
        setup.create_group("security-team")

    group = Group.get(setup.session, name="team-sre")
    assert group
    accounts = get_service_accounts(setup.session, group)
    assert len(accounts) == 1
    service_account = accounts[0]
    assert service_account.user.name == "*****@*****.**"
    assert service_account.user.is_service_account

    # zorkian should be able to manage the account, as should gary, but oliver (not a member of the
    # group) should not.
    zorkian_user = User.get(setup.session, name="*****@*****.**")
    assert zorkian_user
    gary_user = User.get(setup.session, name="*****@*****.**")
    assert gary_user
    oliver_user = User.get(setup.session, name="*****@*****.**")
    assert oliver_user
    assert can_manage_service_account(setup.session, service_account,
                                      zorkian_user)
    assert can_manage_service_account(setup.session, service_account,
                                      gary_user)
    assert not can_manage_service_account(setup.session, service_account,
                                          oliver_user)

    # Diabling the service account should remove the link to the group.
    disable_service_account(setup.session, zorkian_user, service_account)
    assert service_account.user.enabled == False
    assert get_service_accounts(setup.session, group) == []

    # The user should also be gone from the graph and have its permissions removed.
    setup.graph.update_from_db(setup.session)
    group_details = setup.graph.get_group_details("team-sre")
    assert "service_accounts" not in group_details
    metadata = setup.graph.user_metadata["*****@*****.**"]
    assert not metadata["enabled"]
    assert "owner" not in metadata["service_account"]
    user_details = setup.graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []

    # We can re-enable and attach to a different group.
    new_group = Group.get(setup.session, name="security-team")
    assert new_group
    enable_service_account(setup.session, zorkian_user, service_account,
                           new_group)
    assert service_account.user.enabled == True
    assert get_service_accounts(setup.session, group) == []
    accounts = get_service_accounts(setup.session, new_group)
    assert len(accounts) == 1
    assert accounts[0].user.name == "*****@*****.**"

    # Check that this is reflected in the graph and the user has no permissions.
    setup.graph.update_from_db(setup.session)
    group_details = setup.graph.get_group_details("security-team")
    assert group_details["service_accounts"] == ["*****@*****.**"]
    metadata = setup.graph.user_metadata["*****@*****.**"]
    assert metadata["service_account"]["owner"] == "security-team"
    user_details = setup.graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []
Ejemplo n.º 10
0
def test_service_account_create(
    make_session, groups, service_accounts, session, users  # noqa: F811
):
    make_session.return_value = session

    machine_set = "foo +bar -(org)"
    description = "this is a service account.\n\n it is for testing"
    security_team_group = Group.get(session, name="security-team")
    good_actor_username = "******"
    good_service_account_name = "*****@*****.**"

    assert ServiceAccount.get(session, name=good_service_account_name) is None
    assert get_service_accounts(session, security_team_group) == []
    # no-op if non-existing actor
    call_main(
        session,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        good_service_account_name,
        security_team_group.groupname,
        machine_set,
        description,
    )
    # ... or if bad account name
    call_main(
        session,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        "bad-service-account-name",
        security_team_group.groupname,
        machine_set,
        description,
    )
    # ... or non-existing owner group
    call_main(
        session,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        good_service_account_name,
        "non-such-owner-group",
        machine_set,
        description,
    )
    # make sure no change was made
    assert ServiceAccount.get(session, name=good_service_account_name) is None
    assert get_service_accounts(session, security_team_group) == []

    # now it works
    call_main(
        session,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        good_service_account_name,
        security_team_group.groupname,
        machine_set,
        description,
    )
    service_account = ServiceAccount.get(session, name=good_service_account_name)
    assert service_account, "non-existing account should be created"
    assert service_account.user.name == good_service_account_name
    assert service_account.machine_set == machine_set
    assert service_account.description == description
    assert get_service_accounts(session, security_team_group) == [service_account]

    # no-op if account name already exists
    call_main(
        session,
        "service_account",
        "--actor",
        good_actor_username,
        "create",
        good_service_account_name,
        security_team_group.groupname,
        machine_set,
        description,
    )
    service_account = ServiceAccount.get(session, name=good_service_account_name)
    assert service_account, "non-account should be created"
    assert service_account.user.name == good_service_account_name
    assert service_account.machine_set == machine_set
    assert service_account.description == description
    assert get_service_accounts(session, security_team_group) == [service_account]

    # actor can be a service account as well
    call_main(
        session,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        "*****@*****.**",
        security_team_group.groupname,
        machine_set + "2",
        description + "2",
    )
    service_account_2 = ServiceAccount.get(session, name="*****@*****.**")
    assert service_account_2, "non-existing account should be created"
    assert service_account_2.user.name == "*****@*****.**"
    assert service_account_2.machine_set == (machine_set + "2")
    assert service_account_2.description == (description + "2")
    assert set(get_service_accounts(session, security_team_group)) == set(
        [service_account, service_account_2]
    )