mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 17:05:18 +00:00
261b7f916c
When an osqueryd agent sends an enroll request it automatically sends some details about the system. We now save these details which helps ensure we send the correct platform config. Closes #2065
250 lines
5.4 KiB
Go
250 lines
5.4 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/go-kit/kit/endpoint"
|
|
"github.com/kolide/fleet/server/config"
|
|
"github.com/kolide/fleet/server/contexts/viewer"
|
|
"github.com/kolide/fleet/server/datastore/inmem"
|
|
"github.com/kolide/fleet/server/kolide"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestEndpointPermissions tests that
|
|
// the endpoint.Middleware correctly grants or denies
|
|
// permissions to access or modify resources
|
|
func TestEndpointPermissions(t *testing.T) {
|
|
req := struct{}{}
|
|
ds, err := inmem.New(config.TestConfig())
|
|
assert.Nil(t, err)
|
|
|
|
createTestUsers(t, ds)
|
|
|
|
admin1, err := ds.User("admin1")
|
|
assert.Nil(t, err)
|
|
admin1Session, err := ds.NewSession(&kolide.Session{
|
|
UserID: admin1.ID,
|
|
Key: "admin1",
|
|
})
|
|
assert.Nil(t, err)
|
|
|
|
user1, err := ds.User("user1")
|
|
assert.Nil(t, err)
|
|
user1Session, err := ds.NewSession(&kolide.Session{
|
|
UserID: user1.ID,
|
|
Key: "user1",
|
|
})
|
|
assert.Nil(t, err)
|
|
|
|
user2, err := ds.User("user2")
|
|
assert.Nil(t, err)
|
|
user2Session, err := ds.NewSession(&kolide.Session{
|
|
UserID: user2.ID,
|
|
Key: "user2",
|
|
})
|
|
assert.Nil(t, err)
|
|
user2.Enabled = false
|
|
|
|
e := endpoint.Nop // a test endpoint
|
|
var endpointTests = []struct {
|
|
endpoint endpoint.Endpoint
|
|
// who is making the request
|
|
vc *viewer.Viewer
|
|
// what resource are we editing
|
|
requestID uint
|
|
// what error to expect
|
|
wantErr interface{}
|
|
// custom request struct
|
|
request interface{}
|
|
}{
|
|
{
|
|
endpoint: mustBeAdmin(e),
|
|
wantErr: errNoContext,
|
|
},
|
|
{
|
|
endpoint: canReadUser(e),
|
|
wantErr: errNoContext,
|
|
},
|
|
{
|
|
endpoint: canModifyUser(e),
|
|
wantErr: errNoContext,
|
|
},
|
|
{
|
|
endpoint: mustBeAdmin(e),
|
|
vc: &viewer.Viewer{User: admin1, Session: admin1Session},
|
|
},
|
|
{
|
|
endpoint: mustBeAdmin(e),
|
|
vc: &viewer.Viewer{User: user1, Session: user1Session},
|
|
wantErr: permissionError{message: "must be an admin"},
|
|
},
|
|
{
|
|
endpoint: canModifyUser(e),
|
|
vc: &viewer.Viewer{User: admin1, Session: admin1Session},
|
|
},
|
|
{
|
|
endpoint: canModifyUser(e),
|
|
vc: &viewer.Viewer{User: user1, Session: user1Session},
|
|
wantErr: permissionError{message: "no write permissions on user"},
|
|
},
|
|
{
|
|
endpoint: canModifyUser(e),
|
|
vc: &viewer.Viewer{User: user1, Session: user1Session},
|
|
requestID: admin1.ID,
|
|
wantErr: permissionError{message: "no write permissions on user"},
|
|
},
|
|
{
|
|
endpoint: canReadUser(e),
|
|
vc: &viewer.Viewer{User: user1, Session: user1Session},
|
|
requestID: admin1.ID,
|
|
},
|
|
{
|
|
endpoint: canReadUser(e),
|
|
vc: &viewer.Viewer{User: user2, Session: user2Session},
|
|
requestID: admin1.ID,
|
|
wantErr: permissionError{message: "no read permissions on user"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range endpointTests {
|
|
tt := tt
|
|
t.Run("", func(st *testing.T) {
|
|
st.Parallel()
|
|
ctx := context.Background()
|
|
if tt.vc != nil {
|
|
ctx = viewer.NewContext(ctx, *tt.vc)
|
|
}
|
|
if tt.requestID != 0 {
|
|
ctx = context.WithValue(ctx, "request-id", tt.requestID)
|
|
}
|
|
var request interface{}
|
|
if tt.request != nil {
|
|
request = tt.request
|
|
} else {
|
|
request = req
|
|
}
|
|
_, eerr := tt.endpoint(ctx, request)
|
|
assert.IsType(st, tt.wantErr, eerr)
|
|
if ferr, ok := eerr.(permissionError); ok {
|
|
assert.Equal(st, tt.wantErr.(permissionError).message, ferr.Error())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestGetNodeKey tests the reflection logic for pulling the node key from
|
|
// various (fake) request types
|
|
func TestGetNodeKey(t *testing.T) {
|
|
type Foo struct {
|
|
Foo string
|
|
NodeKey string
|
|
}
|
|
|
|
type Bar struct {
|
|
Bar string
|
|
NodeKey string
|
|
}
|
|
|
|
type Nope struct {
|
|
Nope string
|
|
}
|
|
|
|
type Almost struct {
|
|
NodeKey int
|
|
}
|
|
|
|
var getNodeKeyTests = []struct {
|
|
i interface{}
|
|
expectKey string
|
|
shouldErr bool
|
|
}{
|
|
{
|
|
i: Foo{Foo: "foo", NodeKey: "fookey"},
|
|
expectKey: "fookey",
|
|
shouldErr: false,
|
|
},
|
|
{
|
|
i: Bar{Bar: "bar", NodeKey: "barkey"},
|
|
expectKey: "barkey",
|
|
shouldErr: false,
|
|
},
|
|
{
|
|
i: Nope{Nope: "nope"},
|
|
expectKey: "",
|
|
shouldErr: true,
|
|
},
|
|
{
|
|
i: Almost{NodeKey: 10},
|
|
expectKey: "",
|
|
shouldErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range getNodeKeyTests {
|
|
t.Run("", func(t *testing.T) {
|
|
key, err := getNodeKey(tt.i)
|
|
assert.Equal(t, tt.expectKey, key)
|
|
if tt.shouldErr {
|
|
assert.IsType(t, osqueryError{}, err)
|
|
} else {
|
|
assert.Nil(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAuthenticatedHost(t *testing.T) {
|
|
ds, err := inmem.New(config.TestConfig())
|
|
require.Nil(t, err)
|
|
_, err = ds.NewAppConfig(&kolide.AppConfig{EnrollSecret: "foobarbaz"})
|
|
require.Nil(t, err)
|
|
svc, err := newTestService(ds, nil)
|
|
require.Nil(t, err)
|
|
|
|
endpoint := authenticatedHost(
|
|
svc,
|
|
func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
return nil, nil
|
|
},
|
|
)
|
|
|
|
ctx := context.Background()
|
|
goodNodeKey, err := svc.EnrollAgent(ctx, "foobarbaz", "host123", nil)
|
|
assert.Nil(t, err)
|
|
require.NotEmpty(t, goodNodeKey)
|
|
|
|
var authenticatedHostTests = []struct {
|
|
nodeKey string
|
|
shouldErr bool
|
|
}{
|
|
{
|
|
nodeKey: "invalid",
|
|
shouldErr: true,
|
|
},
|
|
{
|
|
nodeKey: "",
|
|
shouldErr: true,
|
|
},
|
|
{
|
|
nodeKey: goodNodeKey,
|
|
shouldErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range authenticatedHostTests {
|
|
t.Run("", func(t *testing.T) {
|
|
var r = struct{ NodeKey string }{NodeKey: tt.nodeKey}
|
|
_, err = endpoint(context.Background(), r)
|
|
if tt.shouldErr {
|
|
assert.IsType(t, osqueryError{}, err)
|
|
} else {
|
|
assert.Nil(t, err)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|