Don't leak Observer permissions between teams for queries. (#12979)

If user is an observer in a team, only show the queries for which observer_can_run is set.
This commit is contained in:
Juan Fernandez 2023-07-26 15:33:21 -04:00 committed by GitHub
parent 2afbd24021
commit a7f6686c27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 24 deletions

View file

@ -97,7 +97,7 @@ func (svc *Service) ListQueries(ctx context.Context, opt fleet.ListOptions, team
}
user := authz.UserFromContext(ctx)
onlyShowObserverCanRun := onlyShowObserverCanRunQueries(user)
onlyShowObserverCanRun := onlyShowObserverCanRunQueries(user, teamID)
queries, err := svc.ds.ListQueries(ctx, fleet.ListQueryOptions{
ListOptions: opt,
@ -112,20 +112,14 @@ func (svc *Service) ListQueries(ctx context.Context, opt fleet.ListOptions, team
return queries, nil
}
func onlyShowObserverCanRunQueries(user *fleet.User) bool {
func onlyShowObserverCanRunQueries(user *fleet.User, teamID *uint) bool {
if user.GlobalRole != nil && *user.GlobalRole == fleet.RoleObserver {
return true
} else if len(user.Teams) > 0 {
allObserver := true
for _, team := range user.Teams {
if team.Role != fleet.RoleObserver {
allObserver = false
break
}
}
return allObserver
}
return false
return teamID != nil && user.TeamMembership(func(ut fleet.UserTeam) bool {
return ut.Role == fleet.RoleObserver
})[*teamID]
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -13,19 +13,63 @@ import (
)
func TestFilterQueriesForObserver(t *testing.T) {
require.True(t, onlyShowObserverCanRunQueries(&fleet.User{GlobalRole: ptr.String(fleet.RoleObserver)}))
require.False(t, onlyShowObserverCanRunQueries(&fleet.User{GlobalRole: ptr.String(fleet.RoleMaintainer)}))
require.False(t, onlyShowObserverCanRunQueries(&fleet.User{GlobalRole: ptr.String(fleet.RoleAdmin)}))
t.Run("global role", func(t *testing.T) {
require.True(t, onlyShowObserverCanRunQueries(&fleet.User{
GlobalRole: ptr.String(fleet.RoleObserver),
}, nil))
require.True(t, onlyShowObserverCanRunQueries(&fleet.User{Teams: []fleet.UserTeam{{Role: fleet.RoleObserver}}}))
require.True(t, onlyShowObserverCanRunQueries(&fleet.User{Teams: []fleet.UserTeam{
{Role: fleet.RoleObserver},
{Role: fleet.RoleObserver},
}}))
require.False(t, onlyShowObserverCanRunQueries(&fleet.User{Teams: []fleet.UserTeam{
{Role: fleet.RoleObserver},
{Role: fleet.RoleMaintainer},
}}))
require.False(t, onlyShowObserverCanRunQueries(&fleet.User{
GlobalRole: ptr.String(fleet.RoleObserverPlus),
}, nil))
require.False(t, onlyShowObserverCanRunQueries(&fleet.User{
GlobalRole: ptr.String(fleet.RoleMaintainer),
}, nil))
require.False(t, onlyShowObserverCanRunQueries(&fleet.User{
GlobalRole: ptr.String(fleet.RoleAdmin),
}, nil))
})
t.Run("user belongs to one or more teams", func(t *testing.T) {
require.True(t, onlyShowObserverCanRunQueries(&fleet.User{Teams: []fleet.UserTeam{{
Role: fleet.RoleObserver,
Team: fleet.Team{ID: 1},
}}}, ptr.Uint(1)))
require.True(t, onlyShowObserverCanRunQueries(&fleet.User{Teams: []fleet.UserTeam{
{
Role: fleet.RoleObserver,
Team: fleet.Team{ID: 1},
},
{
Role: fleet.RoleObserver,
Team: fleet.Team{ID: 2},
},
}}, ptr.Uint(2)))
require.True(t, onlyShowObserverCanRunQueries(&fleet.User{Teams: []fleet.UserTeam{
{
Role: fleet.RoleObserver,
Team: fleet.Team{ID: 1},
},
{
Role: fleet.RoleMaintainer,
Team: fleet.Team{ID: 2},
},
}}, ptr.Uint(1)))
require.False(t, onlyShowObserverCanRunQueries(&fleet.User{Teams: []fleet.UserTeam{
{
Role: fleet.RoleObserver,
Team: fleet.Team{ID: 1},
},
{
Role: fleet.RoleMaintainer,
Team: fleet.Team{ID: 2},
},
}}, ptr.Uint(2)))
})
}
func TestListQueries(t *testing.T) {