Allow GitOps user to list software (#44721)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44696

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

## Testing

- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
- [X] reproduced issue on main branch (with software exceptions on and
policies with software automation, `fleetctl gitops` failed for a gitops
user with a 403)
- [X] verified issue fixed on this branch -- `fleetctl gitops` synced
successfully

For unreleased bug fixes in a release candidate, one of:

- [X] Confirmed that the fix is not expected to adversely impact load
test results


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Expanded GitOps permissions to read and list software inventory,
software titles, installable software, and maintained apps at both
global and team scopes; adjusted related read behaviors and
capitalization in messaging.
* **Tests**
* Updated and added authorization and integration tests to reflect the
new GitOps read/list behavior across software-related and maintained-app
endpoints, including team-scoped scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Scott Gress
2026-05-05 13:27:57 -05:00
committed by GitHub
parent 8e96771719
commit e72c38ad60
9 changed files with 200 additions and 39 deletions
@@ -0,0 +1 @@
- Added permissions for GitOps user to list software titles
+28
View File
@@ -86,6 +86,20 @@ func TestListMaintainedAppsAuth(t *testing.T) {
true,
true,
},
{
"global gitops",
&fleet.User{GlobalRole: ptr.String(fleet.RoleGitOps)},
false,
false,
false,
},
{
"team gitops",
&fleet.User{Teams: []fleet.UserTeam{{Team: fleet.Team{ID: 1}, Role: fleet.RoleGitOps}}},
false,
false,
true,
},
}
var forbiddenError *authz.Forbidden
@@ -224,6 +238,20 @@ func TestGetMaintainedAppAuth(t *testing.T) {
true,
true,
},
{
"global gitops",
&fleet.User{GlobalRole: ptr.String(fleet.RoleGitOps)},
false,
false,
false,
},
{
"team gitops",
&fleet.User{Teams: []fleet.UserTeam{{Team: fleet.Team{ID: 1}, Role: fleet.RoleGitOps}}},
false,
false,
true,
},
}
var forbiddenError *authz.Forbidden
+17 -17
View File
@@ -740,10 +740,10 @@ allow {
# Software
##
# Global admins, maintainers, technician, observers, and observer_plus can read all software.
# Global admins, maintainers, technician, observers, observer_plus and gitops can read all software.
allow {
object.type == "software_inventory"
subject.global_role == [admin, maintainer, technician, observer, observer_plus][_]
subject.global_role == [admin, maintainer, technician, observer, observer_plus, gitops][_]
action == read
}
@@ -754,32 +754,32 @@ allow {
action == write
}
# Team admins, maintainers, technician, observers and observer_plus can read all software in their teams.
# Team admins, maintainers, technician, observers, observer_plus and gitops can read all software in their teams.
allow {
not is_null(object.team_id)
object.type == "software_inventory"
team_role(subject, object.team_id) == [admin, maintainer, technician, observer, observer_plus][_]
team_role(subject, object.team_id) == [admin, maintainer, technician, observer, observer_plus, gitops][_]
action == read
}
# Global admins and maintainers can read all maintained apps.
# Global admins and maintainers and gitops can read all maintained apps.
allow {
object.type == "maintained_app"
subject.global_role == [admin, maintainer][_]
subject.global_role == [admin, maintainer, gitops][_]
action == read
}
# Team admins and maintainers can read all maintained apps (no team constraint, unlike installers)
# Team admins and maintainers and gitops can read all maintained apps (no team constraint, unlike installers)
allow {
object.type == "maintained_app"
team_role(subject, subject.teams[_].id) == [admin, maintainer][_]
team_role(subject, subject.teams[_].id) == [admin, maintainer, gitops][_]
action == read
}
# Global admins, maintainers, and technicians can read any installable entity (software installer or VPP app)
# Global admins, maintainers, technicians and gitops can read any installable entity (software installer or VPP app)
allow {
object.type == "installable_entity"
subject.global_role == [admin, maintainer, technician][_]
subject.global_role == [admin, maintainer, technician, gitops][_]
action == read
}
@@ -790,11 +790,11 @@ allow {
action == write
}
# Team admins, maintainers, and technicians can read any installable entity (software installer or VPP app) in their teams.
# Team admins, maintainers, technicians and gitops can read any installable entity (software installer or VPP app) in their teams.
allow {
not is_null(object.team_id)
object.type == "installable_entity"
team_role(subject, object.team_id) == [admin, maintainer, technician][_]
team_role(subject, object.team_id) == [admin, maintainer, technician, gitops][_]
action == read
}
@@ -865,9 +865,9 @@ allow {
# Global admins, maintainers, technicians, and gitops can resend MDM config profiles.
#
# GitOps doesn't really need permissions to resend to specific hosts,
# gitops doesn't really need permissions to resend to specific hosts,
# but we will keep this as-is to not break any workflows that might be using a
# GitOps token to do a resend.
# gitops token to do a resend.
allow {
object.type == "mdm_config_profile"
subject.global_role == [admin, maintainer, technician, gitops][_]
@@ -894,9 +894,9 @@ allow {
# Team admins, maintainers, technicians, and gitops can resend MDM config profiles on their teams.
#
# GitOps doesn't really need permissions to resend to specific hosts,
# gitops doesn't really need permissions to resend to specific hosts,
# but we will keep this as-is to not break any workflows that might be using a
# GitOps token to do a resend.
# gitops token to do a resend.
allow {
not is_null(object.team_id)
object.team_id != 0
@@ -1250,7 +1250,7 @@ allow {
##
# Certificate Authorities
##
# Global admins and GitOps can configure, read, list, and read secrets of certificate authorities.
# Global admins and gitops can configure, read, list, and read secrets of certificate authorities.
allow {
object.type == "certificate_authority"
subject.global_role == [admin, gitops][_]
+34 -7
View File
@@ -643,6 +643,8 @@ func TestAuthorizeSoftwareInventory(t *testing.T) {
t.Parallel()
softwareInventory := &fleet.AuthzSoftwareInventory{}
team1SoftwareInventory := &fleet.AuthzSoftwareInventory{TeamID: ptr.Uint(1)}
team2SoftwareInventory := &fleet.AuthzSoftwareInventory{TeamID: ptr.Uint(2)}
runTestCases(t, []authTestCase{
{user: nil, object: softwareInventory, action: read, allow: false},
{user: test.UserNoRoles, object: softwareInventory, action: read, allow: false},
@@ -651,8 +653,11 @@ func TestAuthorizeSoftwareInventory(t *testing.T) {
{user: test.UserObserver, object: softwareInventory, action: read, allow: true},
{user: test.UserObserverPlus, object: softwareInventory, action: read, allow: true},
{user: test.UserTechnician, object: softwareInventory, action: read, allow: true},
{user: test.UserGitOps, object: softwareInventory, action: read, allow: false},
{user: test.UserGitOps, object: softwareInventory, action: read, allow: true},
{user: test.UserGitOps, object: team1SoftwareInventory, action: read, allow: true},
{user: test.UserTeamGitOpsTeam1, object: softwareInventory, action: read, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team1SoftwareInventory, action: read, allow: true},
{user: test.UserTeamGitOpsTeam1, object: team2SoftwareInventory, action: read, allow: false},
{user: test.UserTeamTechnicianTeam1, object: softwareInventory, action: read, allow: false},
})
}
@@ -713,18 +718,16 @@ func TestAuthorizeSoftwareInstaller(t *testing.T) {
{user: test.UserTechnician, object: team2Installer, action: read, allow: true},
{user: test.UserTechnician, object: team2Installer, action: write, allow: false},
// TODO: confirm gitops permissions
{user: test.UserGitOps, object: noTeamInstaller, action: read, allow: false},
{user: test.UserGitOps, object: noTeamInstaller, action: read, allow: true},
{user: test.UserGitOps, object: noTeamInstaller, action: write, allow: true},
{user: test.UserGitOps, object: team1Installer, action: read, allow: false},
{user: test.UserGitOps, object: team1Installer, action: read, allow: true},
{user: test.UserGitOps, object: team1Installer, action: write, allow: true},
{user: test.UserGitOps, object: team2Installer, action: read, allow: false},
{user: test.UserGitOps, object: team2Installer, action: read, allow: true},
{user: test.UserGitOps, object: team2Installer, action: write, allow: true},
// TODO: confirm gitops permissions
{user: test.UserTeamGitOpsTeam1, object: noTeamInstaller, action: read, allow: false},
{user: test.UserTeamGitOpsTeam1, object: noTeamInstaller, action: write, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team1Installer, action: read, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team1Installer, action: read, allow: true},
{user: test.UserTeamGitOpsTeam1, object: team1Installer, action: write, allow: true},
{user: test.UserTeamGitOpsTeam1, object: team2Installer, action: read, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team2Installer, action: write, allow: false},
@@ -766,6 +769,30 @@ func TestAuthorizeSoftwareInstaller(t *testing.T) {
})
}
func TestAuthorizeMaintainedApp(t *testing.T) {
t.Parallel()
maintainedApp := &fleet.MaintainedApp{}
runTestCases(t, []authTestCase{
{user: nil, object: maintainedApp, action: read, allow: false},
{user: test.UserNoRoles, object: maintainedApp, action: read, allow: false},
{user: test.UserAdmin, object: maintainedApp, action: read, allow: true},
{user: test.UserMaintainer, object: maintainedApp, action: read, allow: true},
{user: test.UserObserver, object: maintainedApp, action: read, allow: false},
{user: test.UserObserverPlus, object: maintainedApp, action: read, allow: false},
{user: test.UserTechnician, object: maintainedApp, action: read, allow: false},
{user: test.UserGitOps, object: maintainedApp, action: read, allow: true},
{user: test.UserTeamAdminTeam1, object: maintainedApp, action: read, allow: true},
{user: test.UserTeamMaintainerTeam1, object: maintainedApp, action: read, allow: true},
{user: test.UserTeamObserverTeam1, object: maintainedApp, action: read, allow: false},
{user: test.UserTeamObserverPlusTeam1, object: maintainedApp, action: read, allow: false},
{user: test.UserTeamTechnicianTeam1, object: maintainedApp, action: read, allow: false},
{user: test.UserTeamGitOpsTeam1, object: maintainedApp, action: read, allow: true},
})
}
func TestAuthorizeHostSoftwareInstallerResult(t *testing.T) {
t.Parallel()
+13 -7
View File
@@ -7019,14 +7019,13 @@ func (s *integrationEnterpriseTestSuite) TestGitOpsUserActions() {
// Attempt to delete a label, should allow.
s.DoJSON("DELETE", "/api/latest/fleet/labels/foo2", fleet.DeleteLabelRequest{}, http.StatusOK, &fleet.DeleteLabelResponse{})
// Attempt to list all software, should fail.
s.DoJSON("GET", "/api/latest/fleet/software/versions", listSoftwareRequest{}, http.StatusForbidden, &listSoftwareVersionsResponse{})
s.DoJSON("GET", "/api/latest/fleet/software", listSoftwareRequest{}, http.StatusForbidden, &listSoftwareResponse{})
s.DoJSON("GET", "/api/latest/fleet/software/count", countSoftwareRequest{}, http.StatusForbidden, &countSoftwareResponse{})
s.DoJSON("GET", "/api/latest/fleet/software/titles", listSoftwareTitlesRequest{}, http.StatusForbidden, &listSoftwareTitlesResponse{})
// Listing software is allowed for gitops so they can reconcile software state.
s.DoJSON("GET", "/api/latest/fleet/software/versions", listSoftwareRequest{}, http.StatusOK, &listSoftwareVersionsResponse{})
s.DoJSON("GET", "/api/latest/fleet/software", listSoftwareRequest{}, http.StatusOK, &listSoftwareResponse{})
s.DoJSON("GET", "/api/latest/fleet/software/count", countSoftwareRequest{}, http.StatusOK, &countSoftwareResponse{})
s.DoJSON("GET", "/api/latest/fleet/software/titles", listSoftwareTitlesRequest{}, http.StatusOK, &listSoftwareTitlesResponse{})
// Getting a single software title or version still requires Host:list, which gitops doesn't have.
s.DoJSON("GET", "/api/latest/fleet/software/titles/1", getSoftwareTitleRequest{}, http.StatusForbidden, &getSoftwareTitleResponse{})
// Attempt to list a software, should fail.
s.DoJSON("GET", "/api/latest/fleet/software/1", getSoftwareRequest{}, http.StatusForbidden, &getSoftwareResponse{})
s.DoJSON("GET", "/api/latest/fleet/software/versions/1", getSoftwareRequest{}, http.StatusForbidden, &getSoftwareResponse{})
@@ -7575,6 +7574,13 @@ func (s *integrationEnterpriseTestSuite) TestGitOpsUserActions() {
},
QueryID: &q1.ID,
}, http.StatusForbidden, &countTargetsResponse{})
// Listing software titles for the team it owns is allowed.
s.DoJSON("GET", "/api/latest/fleet/software/titles", listSoftwareTitlesRequest{}, http.StatusOK, &listSoftwareTitlesResponse{}, "team_id", fmt.Sprint(t1.ID))
// Listing software titles globally (no team) is forbidden for team gitops.
s.DoJSON("GET", "/api/latest/fleet/software/titles", listSoftwareTitlesRequest{}, http.StatusForbidden, &listSoftwareTitlesResponse{})
// Listing software titles for a team it does not own is forbidden.
s.DoJSON("GET", "/api/latest/fleet/software/titles", listSoftwareTitlesRequest{}, http.StatusForbidden, &listSoftwareTitlesResponse{}, "team_id", fmt.Sprint(t2.ID))
}
func (s *integrationEnterpriseTestSuite) TestDesktopEndpointWithInvalidPolicy() {
+3 -3
View File
@@ -57,8 +57,8 @@ func TestSoftwareInstallersAuth(t *testing.T) {
{"global observer+ team 0", test.UserObserverPlus, ptr.Uint(0), true, true},
{"global observer+ team", test.UserObserverPlus, ptr.Uint(1), true, true},
{"global gitops no team", test.UserGitOps, nil, true, false},
{"global gitops team 0", test.UserGitOps, ptr.Uint(0), true, false},
{"global gitops team", test.UserGitOps, ptr.Uint(1), true, false},
{"global gitops team 0", test.UserGitOps, ptr.Uint(0), false, false},
{"global gitops team", test.UserGitOps, ptr.Uint(1), false, false},
{"team admin no team", test.UserTeamAdminTeam1, nil, true, true},
{"team admin team 0", test.UserTeamAdminTeam1, ptr.Uint(0), true, true},
{"team admin team", test.UserTeamAdminTeam1, ptr.Uint(1), false, false},
@@ -77,7 +77,7 @@ func TestSoftwareInstallersAuth(t *testing.T) {
{"team observer+ other team", test.UserTeamObserverPlusTeam2, ptr.Uint(1), true, true},
{"team gitops no team", test.UserTeamGitOpsTeam1, nil, true, true},
{"team gitops team 0", test.UserTeamGitOpsTeam1, ptr.Uint(0), true, true},
{"team gitops team", test.UserTeamGitOpsTeam1, ptr.Uint(1), true, false},
{"team gitops team", test.UserTeamGitOpsTeam1, ptr.Uint(1), false, false},
{"team gitops other team", test.UserTeamGitOpsTeam2, ptr.Uint(1), true, true},
}
+49 -1
View File
@@ -72,6 +72,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
user *fleet.User
shouldFailGlobalRead bool
shouldFailTeamRead bool
shouldFailGetByID bool
}{
{
name: "global-admin",
@@ -81,6 +82,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: false,
},
{
name: "global-maintainer",
@@ -90,6 +92,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: false,
},
{
name: "global-observer",
@@ -99,6 +102,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: false,
},
{
name: "team-admin-belongs-to-team",
@@ -111,6 +115,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: false,
},
{
name: "team-maintainer-belongs-to-team",
@@ -123,6 +128,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: false,
},
{
name: "team-observer-belongs-to-team",
@@ -135,6 +141,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: false,
},
{
name: "team-admin-does-not-belong-to-team",
@@ -147,6 +154,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
},
{
name: "team-maintainer-does-not-belong-to-team",
@@ -159,6 +167,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
},
{
name: "team-observer-does-not-belong-to-team",
@@ -171,6 +180,45 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
},
{
// GitOps can list/count software but cannot fetch a single version
// because SoftwareByID also requires Host:list permission.
name: "global-gitops",
user: &fleet.User{
ID: 1,
GlobalRole: ptr.String(fleet.RoleGitOps),
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: true,
},
{
name: "team-gitops-belongs-to-team",
user: &fleet.User{
ID: 1,
Teams: []fleet.UserTeam{{
Team: fleet.Team{ID: 1},
Role: fleet.RoleGitOps,
}},
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: true,
},
{
name: "team-gitops-does-not-belong-to-team",
user: &fleet.User{
ID: 1,
Teams: []fleet.UserTeam{{
Team: fleet.Team{ID: 2},
Role: fleet.RoleGitOps,
}},
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
},
} {
t.Run(tc.name, func(t *testing.T) {
@@ -197,7 +245,7 @@ func TestServiceSoftwareInventoryAuth(t *testing.T) {
checkAuthErr(t, tc.shouldFailTeamRead, err)
_, err = svc.SoftwareByID(ctx, 1, ptr.Uint(1), false)
checkAuthErr(t, tc.shouldFailTeamRead, err)
checkAuthErr(t, tc.shouldFailGetByID, err)
})
}
}
+52 -1
View File
@@ -36,6 +36,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
user *fleet.User
shouldFailGlobalRead bool
shouldFailTeamRead bool
shouldFailGetByID bool
shouldFailWrite bool
}{
{
@@ -46,6 +47,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: false,
shouldFailWrite: false,
},
{
@@ -56,6 +58,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: false,
shouldFailWrite: true,
},
{
@@ -66,6 +69,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: false,
shouldFailWrite: true,
},
{
@@ -79,6 +83,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: false,
shouldFailWrite: true,
},
{
@@ -92,6 +97,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: false,
shouldFailWrite: true,
},
{
@@ -105,6 +111,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: false,
shouldFailWrite: true,
},
{
@@ -118,6 +125,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
shouldFailWrite: true,
},
{
@@ -131,6 +139,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
shouldFailWrite: true,
},
{
@@ -144,6 +153,48 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
shouldFailWrite: true,
},
{
// GitOps can list software titles but cannot fetch a single title
// because SoftwareTitleByID also requires Host:list permission.
name: "global-gitops",
user: &fleet.User{
ID: 1,
GlobalRole: ptr.String(fleet.RoleGitOps),
},
shouldFailGlobalRead: false,
shouldFailTeamRead: false,
shouldFailGetByID: true,
shouldFailWrite: true,
},
{
name: "team-gitops-belongs-to-team",
user: &fleet.User{
ID: 1,
Teams: []fleet.UserTeam{{
Team: fleet.Team{ID: 1},
Role: fleet.RoleGitOps,
}},
},
shouldFailGlobalRead: true,
shouldFailTeamRead: false,
shouldFailGetByID: true,
shouldFailWrite: true,
},
{
name: "team-gitops-does-not-belong-to-team",
user: &fleet.User{
ID: 1,
Teams: []fleet.UserTeam{{
Team: fleet.Team{ID: 2},
Role: fleet.RoleGitOps,
}},
},
shouldFailGlobalRead: true,
shouldFailTeamRead: true,
shouldFailGetByID: true,
shouldFailWrite: true,
},
} {
@@ -172,7 +223,7 @@ func TestServiceSoftwareTitlesAuth(t *testing.T) {
// Get a software title for a team
_, err = svc.SoftwareTitleByID(ctx, 1, ptr.Uint(1))
checkAuthErr(t, tc.shouldFailTeamRead, err)
checkAuthErr(t, tc.shouldFailGetByID, err)
// Update a software title's name
err = svc.UpdateSoftwareName(ctx, 1, "2 Chrome 2 Furious")
+3 -3
View File
@@ -77,8 +77,8 @@ func TestVPPAuth(t *testing.T) {
{"global observer team", test.UserObserver, ptr.Uint(1), true, true, true},
{"global observer+ no team", test.UserObserverPlus, nil, true, true, true},
{"global observer+ team", test.UserObserverPlus, ptr.Uint(1), true, true, true},
{"global gitops no team", test.UserGitOps, nil, true, false, false},
{"global gitops team", test.UserGitOps, ptr.Uint(1), true, false, false},
{"global gitops no team", test.UserGitOps, nil, false, false, false},
{"global gitops team", test.UserGitOps, ptr.Uint(1), false, false, false},
{"team admin no team", test.UserTeamAdminTeam1, nil, true, true, false},
{"team admin team", test.UserTeamAdminTeam1, ptr.Uint(1), false, false, false},
{"team admin other team", test.UserTeamAdminTeam2, ptr.Uint(1), true, true, false},
@@ -92,7 +92,7 @@ func TestVPPAuth(t *testing.T) {
{"team observer+ team", test.UserTeamObserverPlusTeam1, ptr.Uint(1), true, true, true},
{"team observer+ other team", test.UserTeamObserverPlusTeam2, ptr.Uint(1), true, true, true},
{"team gitops no team", test.UserTeamGitOpsTeam1, nil, true, true, false},
{"team gitops team", test.UserTeamGitOpsTeam1, ptr.Uint(1), true, false, false},
{"team gitops team", test.UserTeamGitOpsTeam1, ptr.Uint(1), false, false, false},
{"team gitops other team", test.UserTeamGitOpsTeam2, ptr.Uint(1), true, true, false},
}