Merge remote-tracking branch 'origin/master' into sgc/tsm1

pull/19446/head
Stuart Carnie 2020-08-26 10:14:42 -07:00
commit 9163edb187
No known key found for this signature in database
GPG Key ID: 848D9C9718D78B4F
8 changed files with 46 additions and 196 deletions

View File

@ -158,7 +158,6 @@ var taskCmpOptions = cmp.Options{
// skip comparing permissions // skip comparing permissions
cmpopts.IgnoreFields( cmpopts.IgnoreFields(
influxdb.Task{}, influxdb.Task{},
"Authorization",
"LatestCompleted", "LatestCompleted",
"LatestScheduled", "LatestScheduled",
"CreatedAt", "CreatedAt",

View File

@ -92,7 +92,6 @@ func TestTaskHandler_handleGetTasks(t *testing.T) {
OrganizationID: 1, OrganizationID: 1,
OwnerID: 1, OwnerID: 1,
Organization: "test", Organization: "test",
AuthorizationID: 0x100,
}, },
{ {
ID: 2, ID: 2,
@ -100,7 +99,6 @@ func TestTaskHandler_handleGetTasks(t *testing.T) {
OrganizationID: 2, OrganizationID: 2,
OwnerID: 2, OwnerID: 2,
Organization: "test", Organization: "test",
AuthorizationID: 0x200,
}, },
} }
return tasks, len(tasks), nil return tasks, len(tasks), nil
@ -200,7 +198,6 @@ func TestTaskHandler_handleGetTasks(t *testing.T) {
OrganizationID: 2, OrganizationID: 2,
OwnerID: 2, OwnerID: 2,
Organization: "test", Organization: "test",
AuthorizationID: 0x200,
}, },
} }
return tasks, len(tasks), nil return tasks, len(tasks), nil
@ -274,7 +271,6 @@ func TestTaskHandler_handleGetTasks(t *testing.T) {
OrganizationID: 2, OrganizationID: 2,
OwnerID: 2, OwnerID: 2,
Organization: "test2", Organization: "test2",
AuthorizationID: 0x200,
}, },
} }
return tasks, len(tasks), nil return tasks, len(tasks), nil
@ -347,7 +343,6 @@ func TestTaskHandler_handleGetTasks(t *testing.T) {
OrganizationID: 1, OrganizationID: 1,
OwnerID: 1, OwnerID: 1,
Organization: "test2", Organization: "test2",
AuthorizationID: 0x100,
}, },
{ {
ID: 2, ID: 2,
@ -355,7 +350,6 @@ func TestTaskHandler_handleGetTasks(t *testing.T) {
OrganizationID: 2, OrganizationID: 2,
OwnerID: 2, OwnerID: 2,
Organization: "test2", Organization: "test2",
AuthorizationID: 0x200,
}, },
} }
return tasks, len(tasks), nil return tasks, len(tasks), nil
@ -1245,7 +1239,7 @@ func TestTaskHandler_CreateTaskWithOrgName(t *testing.T) {
t.Fatalf("expected task to be created with org ID %s, got %s", o.ID, tc.OrganizationID) t.Fatalf("expected task to be created with org ID %s, got %s", o.ID, tc.OrganizationID)
} }
return &influxdb.Task{ID: 9, OrganizationID: o.ID, OwnerID: o.ID, AuthorizationID: authz.ID, Name: "x", Flux: tc.Flux}, nil return &influxdb.Task{ID: 9, OrganizationID: o.ID, OwnerID: o.ID, Name: "x", Flux: tc.Flux}, nil
}, },
} }
@ -1390,7 +1384,6 @@ func TestTaskHandler_Sessions(t *testing.T) {
return &influxdb.Task{ return &influxdb.Task{
ID: taskID, ID: taskID,
OrganizationID: o.ID, OrganizationID: o.ID,
AuthorizationID: taskAuth.ID,
}, nil }, nil
}, },
} }
@ -1484,7 +1477,6 @@ func TestTaskHandler_Sessions(t *testing.T) {
return &influxdb.Task{ return &influxdb.Task{
ID: taskID, ID: taskID,
OrganizationID: o.ID, OrganizationID: o.ID,
AuthorizationID: taskAuth.ID,
}, nil }, nil
}, },
} }
@ -1580,7 +1572,6 @@ func TestTaskHandler_Sessions(t *testing.T) {
return &influxdb.Task{ return &influxdb.Task{
ID: taskID, ID: taskID,
OrganizationID: o.ID, OrganizationID: o.ID,
AuthorizationID: taskAuth.ID,
}, nil }, nil
}, },
} }
@ -1675,7 +1666,6 @@ func TestTaskHandler_Sessions(t *testing.T) {
return &influxdb.Task{ return &influxdb.Task{
ID: taskID, ID: taskID,
OrganizationID: o.ID, OrganizationID: o.ID,
AuthorizationID: taskAuth.ID,
}, nil }, nil
}, },
} }

View File

@ -1,7 +1,6 @@
package kv package kv
import ( import (
"context"
"time" "time"
"github.com/benbjohnson/clock" "github.com/benbjohnson/clock"
@ -50,8 +49,6 @@ type Service struct {
variableStore *IndexStore variableStore *IndexStore
urmByUserIndex *Index urmByUserIndex *Index
disableAuthorizationsForMaxPermissions func(context.Context) bool
} }
// NewService returns an instance of a Service. // NewService returns an instance of a Service.
@ -71,9 +68,6 @@ func NewService(log *zap.Logger, kv Store, configs ...ServiceConfig) *Service {
endpointStore: newEndpointStore(), endpointStore: newEndpointStore(),
variableStore: newVariableStore(), variableStore: newVariableStore(),
urmByUserIndex: NewIndex(URMByUserIndexMapping, WithIndexReadPathEnabled), urmByUserIndex: NewIndex(URMByUserIndexMapping, WithIndexReadPathEnabled),
disableAuthorizationsForMaxPermissions: func(context.Context) bool {
return false
},
} }
if len(configs) > 0 { if len(configs) > 0 {
@ -110,10 +104,3 @@ func (s *Service) WithResourceLogger(audit resource.Logger) {
func (s *Service) WithStore(store Store) { func (s *Service) WithStore(store Store) {
s.kv = store s.kv = store
} }
// WithMaxPermissionFunc sets the useAuthorizationsForMaxPermissions function
// which can trigger whether or not max permissions uses the users authorizations
// to derive maximum permissions.
func (s *Service) WithMaxPermissionFunc(fn func(context.Context) bool) {
s.disableAuthorizationsForMaxPermissions = fn
}

View File

@ -88,19 +88,11 @@ func kvToInfluxTask(k *kvTask) *influxdb.Task {
func (s *Service) FindTaskByID(ctx context.Context, id influxdb.ID) (*influxdb.Task, error) { func (s *Service) FindTaskByID(ctx context.Context, id influxdb.ID) (*influxdb.Task, error) {
var t *influxdb.Task var t *influxdb.Task
err := s.kv.View(ctx, func(tx Tx) error { err := s.kv.View(ctx, func(tx Tx) error {
if influxdb.FindTaskAuthRequired(ctx) {
task, err := s.findTaskByIDWithAuth(ctx, tx, id)
if err != nil {
return err
}
t = task
} else {
task, err := s.findTaskByID(ctx, tx, id) task, err := s.findTaskByID(ctx, tx, id)
if err != nil { if err != nil {
return err return err
} }
t = task t = task
}
return nil return nil
}) })
if err != nil { if err != nil {
@ -110,35 +102,6 @@ func (s *Service) FindTaskByID(ctx context.Context, id influxdb.ID) (*influxdb.T
return t, nil return t, nil
} }
// findTaskByIDWithAuth is a task lookup that populates the auth
// This is to be used when we want to satisfy the FindTaskByID method
// But is more taxing on the system then if we want to find the task alone.
func (s *Service) findTaskByIDWithAuth(ctx context.Context, tx Tx, id influxdb.ID) (*influxdb.Task, error) {
t, err := s.findTaskByID(ctx, tx, id)
if err != nil {
return nil, err
}
t.Authorization = &influxdb.Authorization{
Status: influxdb.Active,
ID: influxdb.ID(1),
OrgID: t.OrganizationID,
UserID: t.OwnerID,
}
if t.OwnerID.Valid() {
ctx = icontext.SetAuthorizer(ctx, t.Authorization)
// populate task Auth
ps, err := s.maxPermissions(ctx, tx, t.OwnerID)
if err != nil {
return nil, err
}
t.Authorization.Permissions = ps
}
return t, nil
}
// findTaskByID is an internal method used to do any action with tasks internally // findTaskByID is an internal method used to do any action with tasks internally
// that do not require authorization. // that do not require authorization.
func (s *Service) findTaskByID(ctx context.Context, tx Tx, id influxdb.ID) (*influxdb.Task, error) { func (s *Service) findTaskByID(ctx context.Context, tx Tx, id influxdb.ID) (*influxdb.Task, error) {
@ -297,11 +260,6 @@ func (s *Service) findTasksByUser(ctx context.Context, tx Tx, filter influxdb.Ta
return nil, 0, influxdb.ErrUnexpectedTaskBucketErr(err) return nil, 0, influxdb.ErrUnexpectedTaskBucketErr(err)
} }
ps, err := s.maxPermissions(ctx, tx, *filter.User)
if err != nil {
return nil, 0, err
}
matchFn := newTaskMatchFn(filter, nil) matchFn := newTaskMatchFn(filter, nil)
for k, v := c.Next(); k != nil; k, v = c.Next() { for k, v := c.Next(); k != nil; k, v = c.Next() {
@ -312,14 +270,6 @@ func (s *Service) findTasksByUser(ctx context.Context, tx Tx, filter influxdb.Ta
t := kvToInfluxTask(kvTask) t := kvToInfluxTask(kvTask)
if matchFn == nil || matchFn(t) { if matchFn == nil || matchFn(t) {
t.Authorization = &influxdb.Authorization{
Status: influxdb.Active,
UserID: t.OwnerID,
ID: influxdb.ID(1),
OrgID: t.OrganizationID,
Permissions: ps,
}
ts = append(ts, t) ts = append(ts, t)
if len(ts) >= filter.Limit { if len(ts) >= filter.Limit {
@ -399,7 +349,7 @@ func (s *Service) findTasksByOrg(ctx context.Context, tx Tx, filter influxdb.Tas
return nil, 0, influxdb.ErrInvalidTaskID return nil, 0, influxdb.ErrInvalidTaskID
} }
t, err := s.findTaskByIDWithAuth(ctx, tx, *id) t, err := s.findTaskByID(ctx, tx, *id)
if err != nil { if err != nil {
if err == influxdb.ErrTaskNotFound { if err == influxdb.ErrTaskNotFound {
// we might have some crufty index's // we might have some crufty index's
@ -656,16 +606,6 @@ func (s *Service) createTask(ctx context.Context, tx Tx, tc influxdb.TaskCreate)
return nil, influxdb.ErrUnexpectedTaskBucketErr(err) return nil, influxdb.ErrUnexpectedTaskBucketErr(err)
} }
// populate permissions so the task can be used immediately
// if we cant populate here we shouldn't error.
ps, _ := s.maxPermissions(ctx, tx, task.OwnerID)
task.Authorization = &influxdb.Authorization{
Status: influxdb.Active,
ID: influxdb.ID(1),
OrgID: task.OrganizationID,
Permissions: ps,
}
uid, _ := icontext.GetUserID(ctx) uid, _ := icontext.GetUserID(ctx)
if err := s.audit.Log(resource.Change{ if err := s.audit.Log(resource.Change{
Type: resource.Create, Type: resource.Create,
@ -1711,42 +1651,3 @@ func ExtractTaskOptions(ctx context.Context, lang influxdb.FluxLanguageService,
} }
return options.FromScript(lang, flux) return options.FromScript(lang, flux)
} }
func (s *Service) maxPermissions(ctx context.Context, tx Tx, userID influxdb.ID) ([]influxdb.Permission, error) {
// TODO(desa): these values should be cached so it's not so expensive to lookup each time.
f := influxdb.UserResourceMappingFilter{UserID: userID}
mappings, err := s.findUserResourceMappings(ctx, tx, f)
if err != nil {
return nil, &influxdb.Error{
Err: err,
}
}
ps := make([]influxdb.Permission, 0, len(mappings))
for _, m := range mappings {
p, err := m.ToPermissions()
if err != nil {
return nil, &influxdb.Error{
Err: err,
}
}
ps = append(ps, p...)
}
ps = append(ps, influxdb.MePermissions(userID)...)
if !s.disableAuthorizationsForMaxPermissions(ctx) {
// TODO(desa): this is super expensive, we should keep a list of a users maximal privileges somewhere
// we did this so that the oper token would be used in a users permissions.
af := influxdb.AuthorizationFilter{UserID: &userID}
as, err := s.findAuthorizations(ctx, tx, af)
if err != nil {
return nil, err
}
for _, a := range as {
ps = append(ps, a.Permissions...)
}
}
return ps, nil
}

View File

@ -165,7 +165,6 @@ func TestRetrieveTaskWithBadAuth(t *testing.T) {
return err return err
} }
task.OwnerID = influxdb.ID(1) task.OwnerID = influxdb.ID(1)
task.AuthorizationID = influxdb.ID(132) // bad id or an id that doesnt match any auth
tbyte, err := json.Marshal(task) tbyte, err := json.Marshal(task)
if err != nil { if err != nil {
return err return err

20
task.go
View File

@ -29,32 +29,12 @@ var (
TaskSystemType = "system" TaskSystemType = "system"
) )
type contextKey string
const (
taskAuthKey contextKey = "taskAuth"
)
// TODO: these are temporary functions until we can work through optimizing auth
// FindTaskWithAuth adds a auth hint for lookup of tasks
func FindTaskWithoutAuth(ctx context.Context) context.Context {
return context.WithValue(ctx, taskAuthKey, "omit")
}
// FindTaskAuthRequired retrieves the taskAuth hint
func FindTaskAuthRequired(ctx context.Context) bool {
val, ok := ctx.Value(taskAuthKey).(string)
return !(ok && val == "omit")
}
// Task is a task. 🎊 // Task is a task. 🎊
type Task struct { type Task struct {
ID ID `json:"id"` ID ID `json:"id"`
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
OrganizationID ID `json:"orgID"` OrganizationID ID `json:"orgID"`
Organization string `json:"org"` Organization string `json:"org"`
AuthorizationID ID `json:"-"`
Authorization *Authorization `json:"-"`
OwnerID ID `json:"ownerID"` OwnerID ID `json:"ownerID"`
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`

View File

@ -70,7 +70,7 @@ type AnalyticalStorage struct {
func (as *AnalyticalStorage) FinishRun(ctx context.Context, taskID, runID influxdb.ID) (*influxdb.Run, error) { func (as *AnalyticalStorage) FinishRun(ctx context.Context, taskID, runID influxdb.ID) (*influxdb.Run, error) {
run, err := as.TaskControlService.FinishRun(ctx, taskID, runID) run, err := as.TaskControlService.FinishRun(ctx, taskID, runID)
if run != nil && run.ID.String() != "" { if run != nil && run.ID.String() != "" {
task, err := as.TaskService.FindTaskByID(influxdb.FindTaskWithoutAuth(ctx), run.TaskID) task, err := as.TaskService.FindTaskByID(ctx, run.TaskID)
if err != nil { if err != nil {
return run, err return run, err
} }

View File

@ -280,8 +280,6 @@ func testTaskCRUD(t *testing.T, sys *System) {
LatestScheduled: tsk.LatestScheduled, LatestScheduled: tsk.LatestScheduled,
OrganizationID: cr.OrgID, OrganizationID: cr.OrgID,
Organization: cr.Org, Organization: cr.Org,
AuthorizationID: tsk.AuthorizationID,
Authorization: tsk.Authorization,
OwnerID: tsk.OwnerID, OwnerID: tsk.OwnerID,
Name: "task #0", Name: "task #0",
Cron: "* * * * *", Cron: "* * * * *",
@ -291,10 +289,6 @@ func testTaskCRUD(t *testing.T, sys *System) {
Type: influxdb.TaskSystemType, Type: influxdb.TaskSystemType,
} }
// tasks sets user id on authorization to that
// of the tasks owner
want.Authorization.UserID = tsk.OwnerID
for fn, f := range found { for fn, f := range found {
if diff := cmp.Diff(f, want); diff != "" { if diff := cmp.Diff(f, want); diff != "" {
t.Logf("got: %+#v", f) t.Logf("got: %+#v", f)