mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Allow team maintainers to run new queries in the team hosts (#2076)
* Allow team maintainers to run new queries in the team hosts * Add policies for other roles
This commit is contained in:
parent
baa42d367e
commit
e286ee387e
5 changed files with 88 additions and 1 deletions
1
changes/issue-2062-team-maintainer-run-new
Normal file
1
changes/issue-2062-team-maintainer-run-new
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Allow team maintainers to run new queries in the team hosts.
|
||||
|
|
@ -15,6 +15,7 @@ list := "list"
|
|||
write := "write"
|
||||
write_role := "write_role"
|
||||
run := "run"
|
||||
run_new := "run_new"
|
||||
|
||||
# Roles
|
||||
admin := "admin"
|
||||
|
|
@ -265,6 +266,16 @@ allow {
|
|||
subject.global_role == maintainer
|
||||
action = run
|
||||
}
|
||||
allow {
|
||||
object.type == "query"
|
||||
subject.global_role == admin
|
||||
action = run_new
|
||||
}
|
||||
allow {
|
||||
object.type == "query"
|
||||
subject.global_role == maintainer
|
||||
action = run_new
|
||||
}
|
||||
# Team maintainer running a non-observers_can_run query must have the targets
|
||||
# filtered to only teams that they maintain
|
||||
allow {
|
||||
|
|
@ -274,6 +285,22 @@ allow {
|
|||
action == run
|
||||
}
|
||||
|
||||
# Team maintainer can run a new query
|
||||
allow {
|
||||
object.type == "query"
|
||||
# If role is maintainer on any team
|
||||
team_role(subject, subject.teams[_].id) == maintainer
|
||||
action == run_new
|
||||
}
|
||||
|
||||
# Team admin can run a new query
|
||||
allow {
|
||||
object.type == "query"
|
||||
# If role is maintainer on any team
|
||||
team_role(subject, subject.teams[_].id) == admin
|
||||
action == run_new
|
||||
}
|
||||
|
||||
# (Team) observers can run only if observers_can_run
|
||||
allow {
|
||||
object.type == "query"
|
||||
|
|
|
|||
|
|
@ -11,4 +11,6 @@ const (
|
|||
ActionWriteRole = "write_role"
|
||||
// ActionRun is the action for running a live query.
|
||||
ActionRun = "run"
|
||||
// ActionRunNew is the action for running a new live query.
|
||||
ActionRunNew = "run_new"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ func (svc Service) NewDistributedQueryCampaign(ctx context.Context, queryString
|
|||
}
|
||||
queryString = query.Query
|
||||
} else {
|
||||
if err := svc.authz.Authorize(ctx, &fleet.Query{}, fleet.ActionWrite); err != nil {
|
||||
if err := svc.authz.Authorize(ctx, &fleet.Query{}, fleet.ActionRunNew); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query = &fleet.Query{
|
||||
|
|
|
|||
|
|
@ -1746,6 +1746,63 @@ func TestObserversCanOnlyRunDistributedCampaigns(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestTeamMaintainerCanRunNewDistributedCampaigns(t *testing.T) {
|
||||
ds := new(mock.Store)
|
||||
rs := &mock.QueryResultStore{
|
||||
HealthCheckFunc: func() error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
lq := &live_query.MockLiveQuery{}
|
||||
mockClock := clock.NewMockClock()
|
||||
svc := newTestServiceWithClock(ds, rs, lq, mockClock)
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{}, nil
|
||||
}
|
||||
|
||||
ds.NewDistributedQueryCampaignFunc = func(ctx context.Context, camp *fleet.DistributedQueryCampaign) (*fleet.DistributedQueryCampaign, error) {
|
||||
return camp, nil
|
||||
}
|
||||
ds.QueryFunc = func(ctx context.Context, id uint) (*fleet.Query, error) {
|
||||
return &fleet.Query{
|
||||
ID: 42,
|
||||
Name: "query",
|
||||
Query: "select 1;",
|
||||
ObserverCanRun: false,
|
||||
}, nil
|
||||
}
|
||||
viewerCtx := viewer.NewContext(context.Background(), viewer.Viewer{
|
||||
User: &fleet.User{ID: 0, Teams: []fleet.UserTeam{{Role: fleet.RoleMaintainer}}},
|
||||
})
|
||||
|
||||
q := "select year, month, day, hour, minutes, seconds from time"
|
||||
ds.NewActivityFunc = func(ctx context.Context, user *fleet.User, activityType string, details *map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
//var gotQuery *fleet.Query
|
||||
ds.NewQueryFunc = func(ctx context.Context, query *fleet.Query, opts ...fleet.OptionalArg) (*fleet.Query, error) {
|
||||
//gotQuery = query
|
||||
query.ID = 42
|
||||
return query, nil
|
||||
}
|
||||
ds.NewDistributedQueryCampaignTargetFunc = func(ctx context.Context, target *fleet.DistributedQueryCampaignTarget) (*fleet.DistributedQueryCampaignTarget, error) {
|
||||
return target, nil
|
||||
}
|
||||
ds.CountHostsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets, now time.Time) (fleet.TargetMetrics, error) {
|
||||
return fleet.TargetMetrics{}, nil
|
||||
}
|
||||
ds.HostIDsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets) ([]uint, error) {
|
||||
return []uint{1, 3, 5}, nil
|
||||
}
|
||||
ds.NewActivityFunc = func(ctx context.Context, user *fleet.User, activityType string, details *map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
lq.On("RunQuery", "0", "select year, month, day, hour, minutes, seconds from time", []uint{1, 3, 5}).Return(nil)
|
||||
_, err := svc.NewDistributedQueryCampaign(viewerCtx, q, nil, fleet.HostTargets{HostIDs: []uint{2}, LabelIDs: []uint{1}})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestPolicyQueries(t *testing.T) {
|
||||
mockClock := clock.NewMockClock()
|
||||
ds := new(mock.Store)
|
||||
|
|
|
|||
Loading…
Reference in a new issue