2016-11-16 13:47:49 +00:00
|
|
|
package mysql
|
|
|
|
|
|
|
|
import (
|
2021-09-14 12:11:07 +00:00
|
|
|
"context"
|
2021-08-20 15:27:41 +00:00
|
|
|
"database/sql"
|
|
|
|
"encoding/json"
|
2019-10-16 23:35:17 +00:00
|
|
|
|
2021-06-26 04:46:51 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/server/fleet"
|
2020-05-29 16:12:39 +00:00
|
|
|
"github.com/jmoiron/sqlx"
|
2017-01-13 18:35:25 +00:00
|
|
|
"github.com/pkg/errors"
|
2016-11-16 13:47:49 +00:00
|
|
|
)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
func (d *Datastore) NewAppConfig(ctx context.Context, info *fleet.AppConfig) (*fleet.AppConfig, error) {
|
2021-08-20 15:27:41 +00:00
|
|
|
info.ApplyDefaultsForNewInstalls()
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
if err := d.SaveAppConfig(ctx, info); err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "new app config")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
2016-12-20 21:54:30 +00:00
|
|
|
|
|
|
|
return info, nil
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
func (d *Datastore) AppConfig(ctx context.Context) (*fleet.AppConfig, error) {
|
2021-10-19 20:47:37 +00:00
|
|
|
return appConfigDB(ctx, d.reader)
|
|
|
|
}
|
|
|
|
|
|
|
|
func appConfigDB(ctx context.Context, q sqlx.QueryerContext) (*fleet.AppConfig, error) {
|
2021-08-27 14:15:36 +00:00
|
|
|
info := &fleet.AppConfig{}
|
2021-08-20 15:27:41 +00:00
|
|
|
var bytes []byte
|
2021-10-19 20:47:37 +00:00
|
|
|
err := sqlx.GetContext(ctx, q, &bytes, `SELECT json_value FROM app_config_json LIMIT 1`)
|
2021-08-20 15:27:41 +00:00
|
|
|
if err != nil && err != sql.ErrNoRows {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting app config")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
2021-08-20 15:27:41 +00:00
|
|
|
if err == sql.ErrNoRows {
|
|
|
|
return &fleet.AppConfig{}, nil
|
|
|
|
}
|
|
|
|
|
2021-08-27 14:15:36 +00:00
|
|
|
info.ApplyDefaults()
|
|
|
|
|
|
|
|
err = json.Unmarshal(bytes, info)
|
2021-08-20 15:27:41 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "unmarshaling config")
|
|
|
|
}
|
2021-08-27 14:15:36 +00:00
|
|
|
return info, nil
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
func (d *Datastore) SaveAppConfig(ctx context.Context, info *fleet.AppConfig) error {
|
2021-08-20 15:27:41 +00:00
|
|
|
configBytes, err := json.Marshal(info)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "marshaling config")
|
|
|
|
}
|
|
|
|
|
2021-09-14 14:44:02 +00:00
|
|
|
return d.withTx(ctx, func(tx sqlx.ExtContext) error {
|
|
|
|
_, err := tx.ExecContext(ctx,
|
2021-08-20 15:27:41 +00:00
|
|
|
`INSERT INTO app_config_json(json_value) VALUES(?) ON DUPLICATE KEY UPDATE json_value = VALUES(json_value)`,
|
|
|
|
configBytes,
|
2021-07-09 16:12:21 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-08-20 15:27:41 +00:00
|
|
|
if !info.SSOSettings.EnableSSO {
|
2021-09-14 14:44:02 +00:00
|
|
|
_, err = tx.ExecContext(ctx, `UPDATE users SET sso_enabled=false`)
|
2021-07-09 16:12:21 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
2020-05-29 16:12:39 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
func (d *Datastore) VerifyEnrollSecret(ctx context.Context, secret string) (*fleet.EnrollSecret, error) {
|
2021-06-06 22:07:29 +00:00
|
|
|
var s fleet.EnrollSecret
|
2021-09-14 14:44:02 +00:00
|
|
|
err := sqlx.GetContext(ctx, d.reader, &s, "SELECT team_id FROM enroll_secrets WHERE secret = ?", secret)
|
2020-05-29 16:12:39 +00:00
|
|
|
if err != nil {
|
2021-05-31 16:02:05 +00:00
|
|
|
return nil, errors.New("no matching secret found")
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|
|
|
|
|
2021-05-31 16:02:05 +00:00
|
|
|
return &s, nil
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
func (d *Datastore) ApplyEnrollSecrets(ctx context.Context, teamID *uint, secrets []*fleet.EnrollSecret) error {
|
2021-09-14 14:44:02 +00:00
|
|
|
return d.withRetryTxx(ctx, func(tx sqlx.ExtContext) error {
|
|
|
|
return applyEnrollSecretsDB(ctx, tx, teamID, secrets)
|
2021-09-08 18:43:22 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-09-14 14:44:02 +00:00
|
|
|
func applyEnrollSecretsDB(ctx context.Context, exec sqlx.ExecerContext, teamID *uint, secrets []*fleet.EnrollSecret) error {
|
2021-09-08 18:43:22 +00:00
|
|
|
if teamID != nil {
|
|
|
|
sql := `DELETE FROM enroll_secrets WHERE team_id = ?`
|
2021-09-14 14:44:02 +00:00
|
|
|
if _, err := exec.ExecContext(ctx, sql, teamID); err != nil {
|
2021-09-08 18:43:22 +00:00
|
|
|
return errors.Wrap(err, "clear before insert")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sql := `DELETE FROM enroll_secrets WHERE team_id IS NULL`
|
2021-09-14 14:44:02 +00:00
|
|
|
if _, err := exec.ExecContext(ctx, sql); err != nil {
|
2021-09-08 18:43:22 +00:00
|
|
|
return errors.Wrap(err, "clear before insert")
|
2021-05-31 16:02:05 +00:00
|
|
|
}
|
2021-09-08 18:43:22 +00:00
|
|
|
}
|
2021-05-31 16:02:05 +00:00
|
|
|
|
2021-09-08 18:43:22 +00:00
|
|
|
for _, secret := range secrets {
|
|
|
|
sql := `
|
2021-05-31 16:02:05 +00:00
|
|
|
INSERT INTO enroll_secrets (secret, team_id)
|
|
|
|
VALUES ( ?, ? )
|
2020-05-29 16:12:39 +00:00
|
|
|
`
|
2021-09-14 14:44:02 +00:00
|
|
|
if _, err := exec.ExecContext(ctx, sql, secret.Secret, teamID); err != nil {
|
2021-09-08 18:43:22 +00:00
|
|
|
return errors.Wrap(err, "upsert secret")
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|
2021-09-08 18:43:22 +00:00
|
|
|
}
|
|
|
|
return nil
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
func (d *Datastore) GetEnrollSecrets(ctx context.Context, teamID *uint) ([]*fleet.EnrollSecret, error) {
|
2021-09-14 14:44:02 +00:00
|
|
|
return getEnrollSecretsDB(ctx, d.reader, teamID)
|
2021-09-08 18:43:22 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 14:44:02 +00:00
|
|
|
func getEnrollSecretsDB(ctx context.Context, q sqlx.QueryerContext, teamID *uint) ([]*fleet.EnrollSecret, error) {
|
2021-05-31 16:02:05 +00:00
|
|
|
var args []interface{}
|
|
|
|
sql := "SELECT * FROM enroll_secrets WHERE "
|
|
|
|
// MySQL requires comparing NULL with IS. NULL = NULL evaluates to FALSE.
|
|
|
|
if teamID == nil {
|
|
|
|
sql += "team_id IS NULL"
|
|
|
|
} else {
|
|
|
|
sql += "team_id = ?"
|
|
|
|
args = append(args, teamID)
|
|
|
|
}
|
2021-06-06 22:07:29 +00:00
|
|
|
var secrets []*fleet.EnrollSecret
|
2021-09-14 14:44:02 +00:00
|
|
|
if err := sqlx.SelectContext(ctx, q, &secrets, sql, args...); err != nil {
|
2020-05-29 16:12:39 +00:00
|
|
|
return nil, errors.Wrap(err, "get secrets")
|
|
|
|
}
|
2021-05-31 16:02:05 +00:00
|
|
|
return secrets, nil
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|