Add "observer can run" to query objects (#777)

- Database migration.
- Update model and datastore methods.
This commit is contained in:
Zach Wasserman 2021-05-17 12:23:56 -07:00 committed by GitHub
parent 79138d4b60
commit 85d9d00096
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 11 deletions

View file

@ -17,7 +17,7 @@ func testApplyQueries(t *testing.T, ds kolide.Datastore) {
zwass := test.NewUser(t, ds, "Zach", "zwass", "zwass@kolide.co", true)
groob := test.NewUser(t, ds, "Victor", "groob", "victor@kolide.co", true)
expectedQueries := []*kolide.Query{
{Name: "foo", Description: "get the foos", Query: "select * from foo"},
{Name: "foo", Description: "get the foos", Query: "select * from foo", ObserverCanRun: true},
{Name: "bar", Description: "do some bars", Query: "select baz from bar"},
}
@ -34,6 +34,7 @@ func testApplyQueries(t *testing.T, ds kolide.Datastore) {
assert.Equal(t, comp.Description, q.Description)
assert.Equal(t, comp.Query, q.Query)
assert.Equal(t, &zwass.ID, q.AuthorID)
assert.Equal(t, comp.ObserverCanRun, q.ObserverCanRun)
}
// Victor modifies a query (but also pushes the same version of the
@ -160,6 +161,7 @@ func testSaveQuery(t *testing.T, ds kolide.Datastore) {
assert.NotEqual(t, 0, query.ID)
query.Query = "baz"
query.ObserverCanRun = true
err = ds.SaveQuery(query)
require.Nil(t, err)
@ -169,6 +171,7 @@ func testSaveQuery(t *testing.T, ds kolide.Datastore) {
require.NotNil(t, queryVerify)
assert.Equal(t, "baz", queryVerify.Query)
assert.Equal(t, "Zach", queryVerify.AuthorName)
assert.True(t, queryVerify.ObserverCanRun)
}
func testListQuery(t *testing.T, ds kolide.Datastore) {

View file

@ -0,0 +1,26 @@
package tables
import (
"database/sql"
"github.com/pkg/errors"
)
func init() {
MigrationClient.AddMigration(Up_20210517112751, Down_20210517112751)
}
func Up_20210517112751(tx *sql.Tx) error {
sql := `
ALTER TABLE queries
ADD COLUMN observer_can_run TINYINT(1) NOT NULL DEFAULT FALSE
`
if _, err := tx.Exec(sql); err != nil {
return errors.Wrap(err, "add column observer_run")
}
return nil
}
func Down_20210517112751(tx *sql.Tx) error {
return nil
}

View file

@ -34,14 +34,16 @@ func (d *Datastore) ApplyQueries(authorID uint, queries []*kolide.Query) (err er
description,
query,
author_id,
saved
) VALUES ( ?, ?, ?, ?, true )
saved,
observer_can_run
) VALUES ( ?, ?, ?, ?, true, ? )
ON DUPLICATE KEY UPDATE
name = VALUES(name),
description = VALUES(description),
query = VALUES(query),
author_id = VALUES(author_id),
saved = VALUES(saved)
saved = VALUES(saved),
observer_can_run = VALUES(observer_can_run)
`
stmt, err := tx.Prepare(sql)
if err != nil {
@ -52,7 +54,7 @@ func (d *Datastore) ApplyQueries(authorID uint, queries []*kolide.Query) (err er
if q.Name == "" {
return errors.New("query name must not be empty")
}
_, err := stmt.Exec(q.Name, q.Description, q.Query, authorID)
_, err := stmt.Exec(q.Name, q.Description, q.Query, authorID, q.ObserverCanRun)
if err != nil {
return errors.Wrap(err, "exec ApplyQueries insert")
}
@ -95,10 +97,11 @@ func (d *Datastore) NewQuery(query *kolide.Query, opts ...kolide.OptionalArg) (*
description,
query,
saved,
author_id
) VALUES ( ?, ?, ?, ?, ? )
author_id,
observer_can_run
) VALUES ( ?, ?, ?, ?, ?, ? )
`
result, err := db.Exec(sqlStatement, query.Name, query.Description, query.Query, query.Saved, query.AuthorID)
result, err := db.Exec(sqlStatement, query.Name, query.Description, query.Query, query.Saved, query.AuthorID, query.ObserverCanRun)
if err != nil && isDuplicate(err) {
return nil, alreadyExists("Query", 0)
@ -116,10 +119,10 @@ func (d *Datastore) NewQuery(query *kolide.Query, opts ...kolide.OptionalArg) (*
func (d *Datastore) SaveQuery(q *kolide.Query) error {
sql := `
UPDATE queries
SET name = ?, description = ?, query = ?, author_id = ?, saved = ?
SET name = ?, description = ?, query = ?, author_id = ?, saved = ?, observer_can_run = ?
WHERE id = ?
`
result, err := d.db.Exec(sql, q.Name, q.Description, q.Query, q.AuthorID, q.Saved, q.ID)
result, err := d.db.Exec(sql, q.Name, q.Description, q.Query, q.AuthorID, q.Saved, q.ObserverCanRun, q.ID)
if err != nil {
return errors.Wrap(err, "updating query")
}

View file

@ -73,7 +73,10 @@ type Query struct {
Description string `json:"description"`
Query string `json:"query"`
Saved bool `json:"saved"`
AuthorID *uint `json:"author_id" db:"author_id"`
// ObserverCanRun indicates whether users with Observer role can run this as
// a live query.
ObserverCanRun bool `json:"observer_can_run" db:"observer_can_run"`
AuthorID *uint `json:"author_id" db:"author_id"`
// AuthorName is retrieved with a join to the users table in the MySQL
// backend (using AuthorID)
AuthorName string `json:"author_name" db:"author_name"`