diff --git a/server/datastore/datastore_hosts_test.go b/server/datastore/datastore_hosts_test.go index c2415b886..e53f23b10 100644 --- a/server/datastore/datastore_hosts_test.go +++ b/server/datastore/datastore_hosts_test.go @@ -250,43 +250,43 @@ func testListHostsQuery(t *testing.T, ds kolide.Datastore) { require.Nil(t, err) assert.Equal(t, len(hosts), len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "00"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "00"}}) require.Nil(t, err) assert.Equal(t, 10, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "000"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "000"}}) require.Nil(t, err) assert.Equal(t, 1, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "192.168."}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "192.168."}}) require.Nil(t, err) assert.Equal(t, 10, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "192.168.1.1"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "192.168.1.1"}}) require.Nil(t, err) assert.Equal(t, 1, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "hostname%00"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "hostname%00"}}) require.Nil(t, err) assert.Equal(t, 10, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "hostname%003"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "hostname%003"}}) require.Nil(t, err) assert.Equal(t, 1, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "uuid_"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "uuid_"}}) require.Nil(t, err) assert.Equal(t, 10, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "uuid_006"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "uuid_006"}}) require.Nil(t, err) assert.Equal(t, 1, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "serial"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "serial"}}) require.Nil(t, err) assert.Equal(t, 10, len(gotHosts)) - gotHosts, err = ds.ListHosts(kolide.HostListOptions{MatchQuery: "serial009"}) + gotHosts, err = ds.ListHosts(kolide.HostListOptions{ListOptions: kolide.ListOptions{MatchQuery: "serial009"}}) require.Nil(t, err) assert.Equal(t, 1, len(gotHosts)) } diff --git a/server/datastore/datastore_test.go b/server/datastore/datastore_test.go index a4f5cc948..ee162d327 100644 --- a/server/datastore/datastore_test.go +++ b/server/datastore/datastore_test.go @@ -34,6 +34,7 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){ testCreateUser, testSaveUser, testUserByID, + testListUsers, testPasswordResetRequests, testSearchHosts, testSearchHostsLimit, diff --git a/server/datastore/datastore_users_test.go b/server/datastore/datastore_users_test.go index a045d8b8d..b3c755f12 100644 --- a/server/datastore/datastore_users_test.go +++ b/server/datastore/datastore_users_test.go @@ -6,6 +6,7 @@ import ( "github.com/fleetdm/fleet/server/kolide" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func testCreateUser(t *testing.T, ds kolide.Datastore) { @@ -66,6 +67,7 @@ func createTestUsers(t *testing.T, ds kolide.Datastore) []*kolide.User { for _, tt := range createTests { u := &kolide.User{ Username: tt.username, + Name: tt.username, Password: []byte(tt.password), Admin: tt.isAdmin, AdminForcedPasswordReset: tt.passwordReset, @@ -125,3 +127,21 @@ func testAdminAttribute(t *testing.T, ds kolide.Datastore, users []*kolide.User) assert.Equal(t, user.Admin, verify.Admin) } } + +func testListUsers(t *testing.T, ds kolide.Datastore) { + createTestUsers(t, ds) + + users, err := ds.ListUsers(kolide.ListOptions{}) + assert.NoError(t, err) + require.Len(t, users, 2) + + users, err = ds.ListUsers(kolide.ListOptions{MatchQuery: "jason"}) + assert.NoError(t, err) + require.Len(t, users, 1) + assert.Equal(t, "jason@kolide.co", users[0].Email) + + users, err = ds.ListUsers(kolide.ListOptions{MatchQuery: "paia"}) + assert.NoError(t, err) + require.Len(t, users, 1) + assert.Equal(t, "mike@kolide.co", users[0].Email) +} diff --git a/server/datastore/mysql/users.go b/server/datastore/mysql/users.go index 41fd47707..7dae0bc17 100644 --- a/server/datastore/mysql/users.go +++ b/server/datastore/mysql/users.go @@ -8,6 +8,8 @@ import ( "github.com/pkg/errors" ) +var userSearchColumns = []string{"name", "email"} + // NewUser creates a new user func (d *Datastore) NewUser(user *kolide.User) (*kolide.User, error) { sqlStatement := ` @@ -67,11 +69,14 @@ func (d *Datastore) User(username string) (*kolide.User, error) { func (d *Datastore) ListUsers(opt kolide.ListOptions) ([]*kolide.User, error) { sqlStatement := ` SELECT * FROM users + WHERE TRUE ` + + sqlStatement, params := searchLike(sqlStatement, nil, opt.MatchQuery, userSearchColumns...) sqlStatement = appendListOptionsToSQL(sqlStatement, opt) users := []*kolide.User{} - if err := d.db.Select(&users, sqlStatement); err != nil { + if err := d.db.Select(&users, sqlStatement, params...); err != nil { return nil, errors.Wrap(err, "list users") } diff --git a/server/kolide/app.go b/server/kolide/app.go index 0aac408c7..24814e011 100644 --- a/server/kolide/app.go +++ b/server/kolide/app.go @@ -296,6 +296,10 @@ type ListOptions struct { OrderKey string // Direction of ordering OrderDirection OrderDirection + // MatchQuery is the query string to match against columns of the entity + // (varies depending on entity, eg. hostname, IP address for hosts). + // Handling for this parameter must be implemented separately for each type. + MatchQuery string } // EnrollSecret contains information about an enroll secret, name, and active diff --git a/server/kolide/hosts.go b/server/kolide/hosts.go index 1934fa504..5df7cad0c 100644 --- a/server/kolide/hosts.go +++ b/server/kolide/hosts.go @@ -93,8 +93,6 @@ type HostListOptions struct { AdditionalFilters []string // StatusFilter selects the online status of the hosts. StatusFilter HostStatus - // MatchQuery is the query string to match in various columns of the host. - MatchQuery string } type Host struct { diff --git a/server/service/transport.go b/server/service/transport.go index 905c7547a..d18f8e1ac 100644 --- a/server/service/transport.go +++ b/server/service/transport.go @@ -156,11 +156,14 @@ func listOptionsFromRequest(r *http.Request) (kolide.ListOptions, error) { orderKey = "detail_update_time" } + query := r.URL.Query().Get("query") + return kolide.ListOptions{ Page: uint(page), PerPage: uint(perPage), OrderKey: orderKey, OrderDirection: orderDirection, + MatchQuery: query, }, nil } @@ -191,9 +194,6 @@ func hostListOptionsFromRequest(r *http.Request) (kolide.HostListOptions, error) hopt.AdditionalFilters = strings.Split(additionalInfoFiltersString, ",") } - query := r.URL.Query().Get("query") - hopt.MatchQuery = query - return hopt, nil }