influxdb/authorizer/task_test.go

583 lines
18 KiB
Go
Raw Normal View History

package authorizer_test
import (
"context"
"testing"
"time"
"github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/authorizer"
pctx "github.com/influxdata/influxdb/context"
"github.com/influxdata/influxdb/http"
"github.com/influxdata/influxdb/inmem"
"github.com/influxdata/influxdb/kv"
"github.com/influxdata/influxdb/mock"
_ "github.com/influxdata/influxdb/query/builtin"
"github.com/pkg/errors"
"go.uber.org/zap/zaptest"
)
func TestOnboardingValidation(t *testing.T) {
svc := newKVSVC(t)
ts := authorizer.NewTaskService(zaptest.NewLogger(t), mockTaskService(3, 2, 1))
r, err := svc.OnboardInitialUser(context.Background(), &influxdb.OnboardingRequest{
feat(kv): implemented key/value store with end-to-end integration tests * feat(kv:inmem:bolt): implement user service in a kv * refactor(kv): use consistent func receiver name * feat(kv): add initial basic auth service * refactor(passwords): move auth interface into own file * refactor(passwords): rename basic auth files to passwords * refactor(passwords): rename from BasicAuth to Passwords * refactor(kv): copy bolt user test into kv Co-authored-by: Michael Desa <mjdesa@gmail.com> * feat(kv): add inmem testing to kv store * fix(kv): remove extra user index initialization * feat(kv): attempt at making errors nice * fix(http): return not found error if filter is invalid * fix(http): s/platform/influxdb/ for user service * fix(http): s/platform/influxdb/ for user service * feat(kv): initial port of telegraf configs to kv * feat(kv): first pass at migrating bolt org service to kv * feat(kv): first pass at bucket service * feat(kv): first pass at migrating kvlog to kv package * feat(kv): add resource op logs * feat(kv): first pass at user resource mapping migration * feat(kv): add urm usage to bucket and org services * feat(kv): first pass at kv authz service * feat(kv): add cascading auth delete for users * feat(kv): first pass d authorizer.OrganizationService in kv * feat(cmd/influxd/launcher): user kv services where appropriate * fix(kv): initialize authorizations * fix(influxdb): use same buckets while slowly migrating stuff * fix(kv): make staticcheck pass * feat(kv): add dashboards to kv review: make suggestions from pr review fix: use common bucket names for bolt/kv stores * test(kv): add complete password test coverage * chore(kv): fixes for staticcheck * feat(kv): implement labels generically on kv * feat(kv): implement macro service * feat(kv): add source service * feat(kv): add session service * feat(kv): add kv secret service * refactor(kv): update telegraf and urm with error messages * feat(kv): add lookup service * feat(kv): add kv onboarding service * refactor(kv): update telegraf to avoid repetition * feat(cmd/influxd): use kv lookup service * feat(kv): add telegraf to lookup service * feat(cmd/influxd): use kv telegraf service * feat(kv): initial port of scrapers in bolt to kv * feat(kv): update scraper error messaging * feat(cmd/influxd): add kv scraper * feat(kv): add inmem backend tests * refactor(kv): copy paste errors * refactor(kv): add code to password errors * fix(testing): update error messages for incorrect passwords * feat(kv:inmem:bolt): implement user service in a kv * refactor(kv): use consistent func receiver name * refactor(kv): copy bolt user test into kv Co-authored-by: Michael Desa <mjdesa@gmail.com> * feat(kv): add inmem testing to kv store * fix(kv): remove extra user index initialization * feat(kv): attempt at making errors nice * fix(http): return not found error if filter is invalid * fix(http): s/platform/influxdb/ for user service * feat(kv): first pass at migrating bolt org service to kv * feat(kv): first pass at bucket service * feat(kv): first pass at migrating kvlog to kv package * feat(kv): add resource op logs * feat(kv): first pass at user resource mapping migration * feat(kv): add urm usage to bucket and org services * feat(kv): first pass at kv authz service * feat(kv): add cascading auth delete for users * feat(kv): first pass d authorizer.OrganizationService in kv * feat(cmd/influxd/launcher): user kv services where appropriate * feat(kv): add initial basic auth service * refactor(passwords): move auth interface into own file * refactor(passwords): rename basic auth files to passwords * fix(http): s/platform/influxdb/ for user service * fix(kv): initialize authorizations * fix(influxdb): use same buckets while slowly migrating stuff * fix(kv): make staticcheck pass * feat(kv): add dashboards to kv review: make suggestions from pr review fix: use common bucket names for bolt/kv stores * feat(kv): implement labels generically on kv * refactor(passwords): rename from BasicAuth to Passwords * test(kv): add complete password test coverage * chore(kv): fixes for staticcheck * feat(kv): implement macro service * feat(kv): add source service * feat(kv): add session service * feat(kv): initial port of telegraf configs to kv * feat(kv): initial port of scrapers in bolt to kv * feat(kv): add kv secret service * refactor(kv): update telegraf and urm with error messages * feat(kv): add lookup service * feat(kv): add kv onboarding service * refactor(kv): update telegraf to avoid repetition * feat(cmd/influxd): use kv lookup service * feat(kv): add telegraf to lookup service * feat(cmd/influxd): use kv telegraf service * feat(kv): update scraper error messaging * feat(cmd/influxd): add kv scraper * feat(kv): add inmem backend tests * refactor(kv): copy paste errors * refactor(kv): add code to password errors * fix(testing): update error messages for incorrect passwords * feat(http): initial support for flushing all key/values from kv store * feat(kv): rename macro to variable * feat(cmd/influxd/launcher): user kv services where appropriate * refactor(passwords): rename from BasicAuth to Passwords * feat(kv): implement macro service * test(ui): introduce cypress * test(ui): introduce first typescript test * test(ui/e2e): add ci job * chore: update gitignore to ignore test outputs * feat(inmem): in memory influxdb * test(e2e): adding pinger that checks if influxdb is alive * hackathon * hack * hack * hack * hack * Revert "feat(inmem): in memory influxdb" This reverts commit 30ddf032003e704643b07ce80df61c3299ea7295. * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * chore: lint ignore node_modules * hack * hack * hack * add user and flush * hack * remove unused vars * hack * hack * ci(circle): prefix e2e artifacts * change test to testid * update cypress * moar testid * fix npm warnings * remove absolte path * chore(ci): remove /home/circleci proto mkdir hack * wip: crud resources e2e * fix(inmem): use inmem kv store services * test(dashboard): add first dashboard crud tests * hack * undo hack * fix: use response from setup for orgID * chore: wip * add convenience getByTitle function * test(e2e): ui can create orgs * test(e2e): add test for org deletion and update * test(e2e): introduce task creation test * test(e2e): create and update of buckets on org view * chore: move types to declaration file * chore: use route fixture in dashboard tests * chore(ci): hack back * test(ui): update snapshots * chore: package-lock * chore: remove macros * fix: launcher rebase issues * fix: compile errors * fix: compile errors * feat(cmd/influxdb): add explicit testing, asset-path, and store flags Co-authored-by: Andrew Watkins <watts@influxdb.com> * fix(cmd/influxd): set default HTTP handler and flags Co-authored-by: Andrew Watkins <watts@influxdb.com> * build(Makefile): add run-e2e and PHONY * feat(kv:inmem:bolt): implement user service in a kv * refactor(kv): use consistent func receiver name * feat(kv): add initial basic auth service * refactor(passwords): move auth interface into own file * refactor(passwords): rename basic auth files to passwords * refactor(passwords): rename from BasicAuth to Passwords * refactor(kv): copy bolt user test into kv Co-authored-by: Michael Desa <mjdesa@gmail.com> * feat(kv): add inmem testing to kv store * fix(kv): remove extra user index initialization * feat(kv): attempt at making errors nice * fix(http): return not found error if filter is invalid * fix(http): s/platform/influxdb/ for user service * fix(http): s/platform/influxdb/ for user service * feat(kv): initial port of telegraf configs to kv * feat(kv): initial port of scrapers in bolt to kv * feat(kv): first pass at migrating bolt org service to kv * feat(kv): first pass at bucket service * feat(kv): first pass at migrating kvlog to kv package * feat(kv): add resource op logs * feat(kv): first pass at user resource mapping migration * feat(kv): add urm usage to bucket and org services * feat(kv): first pass at kv authz service * feat(kv): add cascading auth delete for users * feat(kv): first pass d authorizer.OrganizationService in kv * feat(cmd/influxd/launcher): user kv services where appropriate * fix(kv): initialize authorizations * fix(influxdb): use same buckets while slowly migrating stuff * fix(kv): make staticcheck pass * feat(kv): add dashboards to kv review: make suggestions from pr review fix: use common bucket names for bolt/kv stores * test(kv): add complete password test coverage * chore(kv): fixes for staticcheck * feat(kv): implement labels generically on kv * feat(kv): implement macro service * feat(kv): add source service * feat(kv): add session service * feat(kv): add kv secret service * refactor(kv): update telegraf and urm with error messages * feat(kv): add lookup service * feat(kv): add kv onboarding service * refactor(kv): update telegraf to avoid repetition * feat(cmd/influxd): use kv lookup service * feat(kv): add telegraf to lookup service * feat(cmd/influxd): use kv telegraf service * feat(kv): update scraper error messaging * feat(cmd/influxd): add kv scraper * feat(kv): add inmem backend tests * refactor(kv): copy paste errors * refactor(kv): add code to password errors * fix(testing): update error messages for incorrect passwords * feat(kv): rename macro to variable * refactor(kv): auth/bucket/org/user unique checks return errors now * feat(inmem): add way to get all bucket names from store * feat(inmem): Buckets to return slice of bytes rather than strings * feat(inmem): add locks around Buckets to avoid races * feat(cmd/influx): check for unauthorized error in wrapCheckSetup * chore(e2e): add video and screenshot artifcats to gitignore * docs(ci): add build instructions for e2e tests * feat(kv): add id lookup for authorized resources
2019-02-19 23:47:19 +00:00
User: "Setec Astronomy",
Password: "too many secrets",
Org: "thing",
Bucket: "holder",
RetentionPeriod: 1,
})
if err != nil {
t.Fatal(err)
}
ctx := pctx.SetAuthorizer(context.Background(), r.Auth)
_, err = ts.CreateTask(ctx, influxdb.TaskCreate{
OrganizationID: r.Org.ID,
OwnerID: r.Auth.GetUserID(),
Flux: `option task = {
name: "my_task",
every: 1s,
}
from(bucket:"holder") |> range(start:-5m) |> to(bucket:"holder", org:"thing")`,
})
if err != nil {
t.Fatal(err)
}
}
func mockTaskService(orgID, taskID, runID influxdb.ID) influxdb.TaskService {
task := influxdb.Task{
ID: taskID,
OrganizationID: orgID,
Name: "cows",
Status: string(influxdb.TaskActive),
Flux: `option task = {
name: "my_task",
every: 1s,
}
from(bucket:"holder") |> range(start:-5m) |> to(bucket:"holder", org:"thing")`,
Every: "1s",
}
log := influxdb.Log{Message: "howdy partner"}
run := influxdb.Run{
ID: runID,
TaskID: taskID,
Status: "completed",
ScheduledFor: time.Now().UTC(),
StartedAt: time.Now().UTC().Add(time.Second * 3),
FinishedAt: time.Now().UTC().Add(time.Second * 10),
Log: []influxdb.Log{log},
}
return &mock.TaskService{
FindTaskByIDFn: func(context.Context, influxdb.ID) (*influxdb.Task, error) {
return &task, nil
},
FindTasksFn: func(context.Context, influxdb.TaskFilter) ([]*influxdb.Task, int, error) {
return []*influxdb.Task{&task}, 1, nil
},
CreateTaskFn: func(_ context.Context, tc influxdb.TaskCreate) (*influxdb.Task, error) {
taskCopy := task
return &taskCopy, nil
},
UpdateTaskFn: func(context.Context, influxdb.ID, influxdb.TaskUpdate) (*influxdb.Task, error) {
return &task, nil
},
DeleteTaskFn: func(context.Context, influxdb.ID) error {
return nil
},
FindLogsFn: func(context.Context, influxdb.LogFilter) ([]*influxdb.Log, int, error) {
return []*influxdb.Log{&log}, 1, nil
},
FindRunsFn: func(context.Context, influxdb.RunFilter) ([]*influxdb.Run, int, error) {
return []*influxdb.Run{&run}, 1, nil
},
FindRunByIDFn: func(context.Context, influxdb.ID, influxdb.ID) (*influxdb.Run, error) {
return &run, nil
},
CancelRunFn: func(context.Context, influxdb.ID, influxdb.ID) error {
return nil
},
RetryRunFn: func(context.Context, influxdb.ID, influxdb.ID) (*influxdb.Run, error) {
return &run, nil
},
ForceRunFn: func(context.Context, influxdb.ID, int64) (*influxdb.Run, error) {
return &run, nil
},
}
}
func TestValidations(t *testing.T) {
var (
taskID = influxdb.ID(0x7456)
runID = influxdb.ID(0x402)
otherOrg = &influxdb.Organization{Name: "other_org"}
)
svc := newKVSVC(t)
r, err := svc.OnboardInitialUser(context.Background(), &influxdb.OnboardingRequest{
feat(kv): implemented key/value store with end-to-end integration tests * feat(kv:inmem:bolt): implement user service in a kv * refactor(kv): use consistent func receiver name * feat(kv): add initial basic auth service * refactor(passwords): move auth interface into own file * refactor(passwords): rename basic auth files to passwords * refactor(passwords): rename from BasicAuth to Passwords * refactor(kv): copy bolt user test into kv Co-authored-by: Michael Desa <mjdesa@gmail.com> * feat(kv): add inmem testing to kv store * fix(kv): remove extra user index initialization * feat(kv): attempt at making errors nice * fix(http): return not found error if filter is invalid * fix(http): s/platform/influxdb/ for user service * fix(http): s/platform/influxdb/ for user service * feat(kv): initial port of telegraf configs to kv * feat(kv): first pass at migrating bolt org service to kv * feat(kv): first pass at bucket service * feat(kv): first pass at migrating kvlog to kv package * feat(kv): add resource op logs * feat(kv): first pass at user resource mapping migration * feat(kv): add urm usage to bucket and org services * feat(kv): first pass at kv authz service * feat(kv): add cascading auth delete for users * feat(kv): first pass d authorizer.OrganizationService in kv * feat(cmd/influxd/launcher): user kv services where appropriate * fix(kv): initialize authorizations * fix(influxdb): use same buckets while slowly migrating stuff * fix(kv): make staticcheck pass * feat(kv): add dashboards to kv review: make suggestions from pr review fix: use common bucket names for bolt/kv stores * test(kv): add complete password test coverage * chore(kv): fixes for staticcheck * feat(kv): implement labels generically on kv * feat(kv): implement macro service * feat(kv): add source service * feat(kv): add session service * feat(kv): add kv secret service * refactor(kv): update telegraf and urm with error messages * feat(kv): add lookup service * feat(kv): add kv onboarding service * refactor(kv): update telegraf to avoid repetition * feat(cmd/influxd): use kv lookup service * feat(kv): add telegraf to lookup service * feat(cmd/influxd): use kv telegraf service * feat(kv): initial port of scrapers in bolt to kv * feat(kv): update scraper error messaging * feat(cmd/influxd): add kv scraper * feat(kv): add inmem backend tests * refactor(kv): copy paste errors * refactor(kv): add code to password errors * fix(testing): update error messages for incorrect passwords * feat(kv:inmem:bolt): implement user service in a kv * refactor(kv): use consistent func receiver name * refactor(kv): copy bolt user test into kv Co-authored-by: Michael Desa <mjdesa@gmail.com> * feat(kv): add inmem testing to kv store * fix(kv): remove extra user index initialization * feat(kv): attempt at making errors nice * fix(http): return not found error if filter is invalid * fix(http): s/platform/influxdb/ for user service * feat(kv): first pass at migrating bolt org service to kv * feat(kv): first pass at bucket service * feat(kv): first pass at migrating kvlog to kv package * feat(kv): add resource op logs * feat(kv): first pass at user resource mapping migration * feat(kv): add urm usage to bucket and org services * feat(kv): first pass at kv authz service * feat(kv): add cascading auth delete for users * feat(kv): first pass d authorizer.OrganizationService in kv * feat(cmd/influxd/launcher): user kv services where appropriate * feat(kv): add initial basic auth service * refactor(passwords): move auth interface into own file * refactor(passwords): rename basic auth files to passwords * fix(http): s/platform/influxdb/ for user service * fix(kv): initialize authorizations * fix(influxdb): use same buckets while slowly migrating stuff * fix(kv): make staticcheck pass * feat(kv): add dashboards to kv review: make suggestions from pr review fix: use common bucket names for bolt/kv stores * feat(kv): implement labels generically on kv * refactor(passwords): rename from BasicAuth to Passwords * test(kv): add complete password test coverage * chore(kv): fixes for staticcheck * feat(kv): implement macro service * feat(kv): add source service * feat(kv): add session service * feat(kv): initial port of telegraf configs to kv * feat(kv): initial port of scrapers in bolt to kv * feat(kv): add kv secret service * refactor(kv): update telegraf and urm with error messages * feat(kv): add lookup service * feat(kv): add kv onboarding service * refactor(kv): update telegraf to avoid repetition * feat(cmd/influxd): use kv lookup service * feat(kv): add telegraf to lookup service * feat(cmd/influxd): use kv telegraf service * feat(kv): update scraper error messaging * feat(cmd/influxd): add kv scraper * feat(kv): add inmem backend tests * refactor(kv): copy paste errors * refactor(kv): add code to password errors * fix(testing): update error messages for incorrect passwords * feat(http): initial support for flushing all key/values from kv store * feat(kv): rename macro to variable * feat(cmd/influxd/launcher): user kv services where appropriate * refactor(passwords): rename from BasicAuth to Passwords * feat(kv): implement macro service * test(ui): introduce cypress * test(ui): introduce first typescript test * test(ui/e2e): add ci job * chore: update gitignore to ignore test outputs * feat(inmem): in memory influxdb * test(e2e): adding pinger that checks if influxdb is alive * hackathon * hack * hack * hack * hack * Revert "feat(inmem): in memory influxdb" This reverts commit 30ddf032003e704643b07ce80df61c3299ea7295. * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * hack * chore: lint ignore node_modules * hack * hack * hack * add user and flush * hack * remove unused vars * hack * hack * ci(circle): prefix e2e artifacts * change test to testid * update cypress * moar testid * fix npm warnings * remove absolte path * chore(ci): remove /home/circleci proto mkdir hack * wip: crud resources e2e * fix(inmem): use inmem kv store services * test(dashboard): add first dashboard crud tests * hack * undo hack * fix: use response from setup for orgID * chore: wip * add convenience getByTitle function * test(e2e): ui can create orgs * test(e2e): add test for org deletion and update * test(e2e): introduce task creation test * test(e2e): create and update of buckets on org view * chore: move types to declaration file * chore: use route fixture in dashboard tests * chore(ci): hack back * test(ui): update snapshots * chore: package-lock * chore: remove macros * fix: launcher rebase issues * fix: compile errors * fix: compile errors * feat(cmd/influxdb): add explicit testing, asset-path, and store flags Co-authored-by: Andrew Watkins <watts@influxdb.com> * fix(cmd/influxd): set default HTTP handler and flags Co-authored-by: Andrew Watkins <watts@influxdb.com> * build(Makefile): add run-e2e and PHONY * feat(kv:inmem:bolt): implement user service in a kv * refactor(kv): use consistent func receiver name * feat(kv): add initial basic auth service * refactor(passwords): move auth interface into own file * refactor(passwords): rename basic auth files to passwords * refactor(passwords): rename from BasicAuth to Passwords * refactor(kv): copy bolt user test into kv Co-authored-by: Michael Desa <mjdesa@gmail.com> * feat(kv): add inmem testing to kv store * fix(kv): remove extra user index initialization * feat(kv): attempt at making errors nice * fix(http): return not found error if filter is invalid * fix(http): s/platform/influxdb/ for user service * fix(http): s/platform/influxdb/ for user service * feat(kv): initial port of telegraf configs to kv * feat(kv): initial port of scrapers in bolt to kv * feat(kv): first pass at migrating bolt org service to kv * feat(kv): first pass at bucket service * feat(kv): first pass at migrating kvlog to kv package * feat(kv): add resource op logs * feat(kv): first pass at user resource mapping migration * feat(kv): add urm usage to bucket and org services * feat(kv): first pass at kv authz service * feat(kv): add cascading auth delete for users * feat(kv): first pass d authorizer.OrganizationService in kv * feat(cmd/influxd/launcher): user kv services where appropriate * fix(kv): initialize authorizations * fix(influxdb): use same buckets while slowly migrating stuff * fix(kv): make staticcheck pass * feat(kv): add dashboards to kv review: make suggestions from pr review fix: use common bucket names for bolt/kv stores * test(kv): add complete password test coverage * chore(kv): fixes for staticcheck * feat(kv): implement labels generically on kv * feat(kv): implement macro service * feat(kv): add source service * feat(kv): add session service * feat(kv): add kv secret service * refactor(kv): update telegraf and urm with error messages * feat(kv): add lookup service * feat(kv): add kv onboarding service * refactor(kv): update telegraf to avoid repetition * feat(cmd/influxd): use kv lookup service * feat(kv): add telegraf to lookup service * feat(cmd/influxd): use kv telegraf service * feat(kv): update scraper error messaging * feat(cmd/influxd): add kv scraper * feat(kv): add inmem backend tests * refactor(kv): copy paste errors * refactor(kv): add code to password errors * fix(testing): update error messages for incorrect passwords * feat(kv): rename macro to variable * refactor(kv): auth/bucket/org/user unique checks return errors now * feat(inmem): add way to get all bucket names from store * feat(inmem): Buckets to return slice of bytes rather than strings * feat(inmem): add locks around Buckets to avoid races * feat(cmd/influx): check for unauthorized error in wrapCheckSetup * chore(e2e): add video and screenshot artifcats to gitignore * docs(ci): add build instructions for e2e tests * feat(kv): add id lookup for authorized resources
2019-02-19 23:47:19 +00:00
User: "Setec Astronomy",
Password: "too many secrets",
Org: "thing",
Bucket: "holder",
RetentionPeriod: 1,
})
if err != nil {
t.Fatal(err)
}
if err := svc.CreateOrganization(context.Background(), otherOrg); err != nil {
t.Fatal(err)
}
otherBucket := &influxdb.Bucket{
Name: "other_bucket",
OrgID: otherOrg.ID,
}
if err = svc.CreateBucket(context.Background(), otherBucket); err != nil {
t.Fatal(err)
}
var (
orgID = r.Org.ID
validTaskService = authorizer.NewTaskService(zaptest.NewLogger(t), mockTaskService(orgID, taskID, runID))
// Read all tasks in org.
orgReadAllTaskPermissions = []influxdb.Permission{
{Action: influxdb.ReadAction, Resource: influxdb.Resource{Type: influxdb.TasksResourceType, OrgID: &orgID}},
}
// Read all tasks in some other org.
wrongOrgReadAllTaskPermissions = []influxdb.Permission{
{Action: influxdb.ReadAction, Resource: influxdb.Resource{Type: influxdb.TasksResourceType, OrgID: &taskID}},
}
// Write all tasks in org, no specific bucket permissions.
orgWriteAllTaskPermissions = []influxdb.Permission{
{Action: influxdb.WriteAction, Resource: influxdb.Resource{Type: influxdb.TasksResourceType, OrgID: &orgID}},
}
// Write all tasks in org, and read/write the onboarding bucket.
orgWriteAllTaskBucketPermissions = []influxdb.Permission{
{Action: influxdb.WriteAction, Resource: influxdb.Resource{Type: influxdb.TasksResourceType, OrgID: &orgID}},
{Action: influxdb.WriteAction, Resource: influxdb.Resource{Type: influxdb.BucketsResourceType, OrgID: &orgID, ID: &r.Bucket.ID}},
{Action: influxdb.ReadAction, Resource: influxdb.Resource{Type: influxdb.BucketsResourceType, OrgID: &orgID, ID: &r.Bucket.ID}},
}
// Write the specific task, and read/write the onboarding bucket.
orgWriteTaskBucketPermissions = []influxdb.Permission{
{Action: influxdb.WriteAction, Resource: influxdb.Resource{Type: influxdb.TasksResourceType, OrgID: &orgID, ID: &taskID}},
{Action: influxdb.WriteAction, Resource: influxdb.Resource{Type: influxdb.BucketsResourceType, OrgID: &orgID, ID: &r.Bucket.ID}},
{Action: influxdb.ReadAction, Resource: influxdb.Resource{Type: influxdb.BucketsResourceType, OrgID: &orgID, ID: &r.Bucket.ID}},
}
// Permission only to specifically write the target task.
orgWriteTaskPermissions = []influxdb.Permission{
{Action: influxdb.WriteAction, Resource: influxdb.Resource{Type: influxdb.TasksResourceType, OrgID: &orgID, ID: &taskID}},
}
// Permission only to specifically read the target task.
orgReadTaskPermissions = []influxdb.Permission{
{Action: influxdb.ReadAction, Resource: influxdb.Resource{Type: influxdb.TasksResourceType, OrgID: &orgID, ID: &taskID}},
}
)
tests := []struct {
name string
check func(context.Context, influxdb.TaskService) error
auth *influxdb.Authorization
}{
{
name: "create failure",
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.CreateTask(ctx, influxdb.TaskCreate{
OrganizationID: r.Org.ID,
Flux: `option task = {
name: "my_task",
every: 1s,
}
from(bucket:"holder") |> range(start:-5m) |> to(bucket:"holder", org:"thing")`,
})
if err == nil {
return errors.New("failed to error without permission")
}
return nil
},
auth: &influxdb.Authorization{},
},
{
name: "create success",
auth: r.Auth,
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.CreateTask(ctx, influxdb.TaskCreate{
OrganizationID: r.Org.ID,
OwnerID: r.Auth.GetUserID(),
Flux: `option task = {
name: "my_task",
every: 1s,
}
from(bucket:"holder") |> range(start:-5m) |> to(bucket:"holder", org:"thing")`,
})
return err
},
},
{
name: "FindTaskByID missing auth",
auth: &influxdb.Authorization{Permissions: []influxdb.Permission{}},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.FindTaskByID(ctx, taskID)
if err == nil {
return errors.New("returned without error without permission")
}
return nil
},
},
{
name: "FindTaskByID with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.FindTaskByID(ctx, taskID)
return err
},
},
{
name: "FindTaskByID with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.FindTaskByID(ctx, taskID)
return err
},
},
{
name: "FindTasks with bad auth",
auth: &influxdb.Authorization{Status: "active", Permissions: wrongOrgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
ts, _, err := svc.FindTasks(ctx, influxdb.TaskFilter{
OrganizationID: &orgID,
})
if err == nil && len(ts) > 0 {
return errors.New("returned no error with a invalid auth")
}
return nil
},
},
{
name: "FindTasks with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindTasks(ctx, influxdb.TaskFilter{
OrganizationID: &orgID,
})
return err
},
},
{
name: "FindTasks with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindTasks(ctx, influxdb.TaskFilter{
OrganizationID: &orgID,
})
return err
},
},
{
name: "FindTasks without org filter",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindTasks(ctx, influxdb.TaskFilter{})
return err
},
},
{
name: "UpdateTask with readonly auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
flux := `option task = {
name: "my_task",
every: 1s,
}
from(bucket:"holder") |> range(start:-5m) |> to(bucket:"holder", org:"thing")`
_, err := svc.UpdateTask(ctx, taskID, influxdb.TaskUpdate{
Flux: &flux,
})
if err == nil {
return errors.New("returned no error with a invalid auth")
}
return nil
},
},
{
name: "UpdateTask with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteAllTaskBucketPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
flux := `option task = {
name: "my_task",
every: 1s,
}
from(bucket:"holder") |> range(start:-5m) |> to(bucket:"holder", org:"thing")`
_, err := svc.UpdateTask(ctx, taskID, influxdb.TaskUpdate{
Flux: &flux,
})
return err
},
},
{
name: "UpdateTask with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteTaskBucketPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
flux := `option task = {
name: "my_task",
every: 1s,
}
from(bucket:"holder") |> range(start:-5m) |> to(bucket:"holder", org:"thing")`
_, err := svc.UpdateTask(ctx, taskID, influxdb.TaskUpdate{
Flux: &flux,
})
return err
},
},
{
name: "DeleteTask missing auth",
auth: &influxdb.Authorization{Permissions: []influxdb.Permission{}},
check: func(ctx context.Context, svc influxdb.TaskService) error {
err := svc.DeleteTask(ctx, taskID)
if err == nil {
return errors.New("returned without error without permission")
}
return nil
},
},
{
name: "DeleteTask readonly auth",
auth: &influxdb.Authorization{Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
err := svc.DeleteTask(ctx, taskID)
if err == nil {
return errors.New("returned without error without permission")
}
return nil
},
},
{
name: "DeleteTask with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
err := svc.DeleteTask(ctx, taskID)
return err
},
},
{
name: "DeleteTask with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
err := svc.DeleteTask(ctx, taskID)
return err
},
},
{
name: "FindLogs with bad auth",
auth: &influxdb.Authorization{Status: "active", Permissions: wrongOrgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindLogs(ctx, influxdb.LogFilter{
Task: taskID,
})
if err == nil {
return errors.New("returned no error with a invalid auth")
}
return nil
},
},
{
name: "FindLogs with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindLogs(ctx, influxdb.LogFilter{
Task: taskID,
})
return err
},
},
{
name: "FindLogs with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindLogs(ctx, influxdb.LogFilter{
Task: taskID,
})
return err
},
},
{
name: "FindRuns with bad auth",
auth: &influxdb.Authorization{Status: "active", Permissions: wrongOrgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindRuns(ctx, influxdb.RunFilter{
Task: taskID,
})
if err == nil {
return errors.New("returned no error with a invalid auth")
}
return nil
},
},
{
name: "FindRuns with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindRuns(ctx, influxdb.RunFilter{
Task: taskID,
})
return err
},
},
{
name: "FindRuns with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, _, err := svc.FindRuns(ctx, influxdb.RunFilter{
Task: taskID,
})
return err
},
},
{
name: "FindRunByID missing auth",
auth: &influxdb.Authorization{Permissions: []influxdb.Permission{}},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.FindRunByID(ctx, taskID, 10)
if err == nil {
return errors.New("returned without error without permission")
}
return nil
},
},
{
name: "FindRunByID with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.FindRunByID(ctx, taskID, 10)
return err
},
},
{
name: "FindRunByID with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgReadTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.FindRunByID(ctx, taskID, 10)
return err
},
},
{
name: "CancelRun with bad auth",
auth: &influxdb.Authorization{Status: "active", Permissions: wrongOrgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
err := svc.CancelRun(ctx, taskID, 10)
if err == nil {
return errors.New("returned no error with a invalid auth")
}
return nil
},
},
{
name: "CancelRun with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
err := svc.CancelRun(ctx, taskID, 10)
return err
},
},
{
name: "CancelRun with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
err := svc.CancelRun(ctx, taskID, 10)
return err
},
},
{
name: "RetryRun with bad auth",
auth: &influxdb.Authorization{Status: "active", Permissions: wrongOrgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.RetryRun(ctx, taskID, 10)
if err == nil {
return errors.New("returned no error with a invalid auth")
}
return nil
},
},
{
name: "RetryRun with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.RetryRun(ctx, taskID, 10)
return err
},
},
{
name: "RetryRun with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.RetryRun(ctx, taskID, 10)
return err
},
},
{
name: "ForceRun with bad auth",
auth: &influxdb.Authorization{Status: "active", Permissions: wrongOrgReadAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.ForceRun(ctx, taskID, 10000)
if err == nil {
return errors.New("returned no error with a invalid auth")
}
return nil
},
},
{
name: "ForceRun with org auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteAllTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.ForceRun(ctx, taskID, 10000)
return err
},
},
{
name: "ForceRun with task auth",
auth: &influxdb.Authorization{Status: "active", Permissions: orgWriteTaskPermissions},
check: func(ctx context.Context, svc influxdb.TaskService) error {
_, err := svc.ForceRun(ctx, taskID, 10000)
return err
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := pctx.SetAuthorizer(context.Background(), test.auth)
if err := test.check(ctx, validTaskService); err != nil {
if aerr, ok := err.(http.AuthzError); ok {
t.Error(aerr.AuthzError())
}
t.Error(err)
}
})
}
}
func newKVSVC(t *testing.T) *kv.Service {
t.Helper()
svc := kv.NewService(zaptest.NewLogger(t), inmem.NewKVStore())
if err := svc.Initialize(context.Background()); err != nil {
t.Fatal(err)
}
return svc
}