diff --git a/server/datastore/mysql/users.go b/server/datastore/mysql/users.go index 0a31983020bf..c1215cd2a934 100644 --- a/server/datastore/mysql/users.go +++ b/server/datastore/mysql/users.go @@ -326,11 +326,10 @@ func (ds *Datastore) UserSettings(ctx context.Context, userID uint) (*fleet.User ` err := sqlx.GetContext(ctx, ds.reader(ctx), &bytes, stmt, userID) if err != nil { - // okay for a user not to have any settings if err == sql.ErrNoRows { - return settings, nil + return nil, ctxerr.Wrap(ctx, notFound("UserSettings").WithID(userID)) } - return nil, ctxerr.Wrap(ctx, err, "selecting app config") + return nil, ctxerr.Wrap(ctx, err, "selecting user settings") } if len(bytes) == 0 { diff --git a/server/fleet/users.go b/server/fleet/users.go index 2c56e596961f..3546a58506b3 100644 --- a/server/fleet/users.go +++ b/server/fleet/users.go @@ -37,7 +37,20 @@ type User struct { } type UserSettings struct { - HiddenHostsTableColumns *[]string `json:"hidden_hosts_table_columns,omitempty"` + HiddenHostsTableColumns []string `json:"hidden_hosts_table_columns,omitempty"` +} + +// Scan implements the sql.Scanner interface, tells DB driver how to convert MySQL type (json) to +// custom Go type (UserSettings). +func (us *UserSettings) Scan(val interface{}) error { + switch v := val.(type) { + case []byte: + return json.Unmarshal(v, us) + case string: + return json.Unmarshal([]byte(v), us) + default: + return fmt.Errorf("unsupported type: %T", v) + } } // IsGlobalObserver returns true if user is either a Global Observer or a Global Observer+