PluginManager: Make Plugins, Renderer and DataSources non-global (#31866)
* PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package sqlstore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -166,18 +167,18 @@ func deleteAlertDefinition(dashboardId int64, sess *DBSession) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func SaveAlerts(cmd *models.SaveAlertsCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
existingAlerts, err := GetAlertsByDashboardId2(cmd.DashboardId, sess)
|
||||
func (ss *SQLStore) SaveAlerts(dashID int64, alerts []*models.Alert) error {
|
||||
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
existingAlerts, err := GetAlertsByDashboardId2(dashID, sess)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updateAlerts(existingAlerts, cmd, sess); err != nil {
|
||||
if err := updateAlerts(existingAlerts, alerts, sess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := deleteMissingAlerts(existingAlerts, cmd, sess); err != nil {
|
||||
if err := deleteMissingAlerts(existingAlerts, alerts, sess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -185,8 +186,27 @@ func SaveAlerts(cmd *models.SaveAlertsCommand) error {
|
||||
})
|
||||
}
|
||||
|
||||
func updateAlerts(existingAlerts []*models.Alert, cmd *models.SaveAlertsCommand, sess *DBSession) error {
|
||||
for _, alert := range cmd.Alerts {
|
||||
func SaveAlerts(cmd *models.SaveAlertsCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
existingAlerts, err := GetAlertsByDashboardId2(cmd.DashboardId, sess)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updateAlerts(existingAlerts, cmd.Alerts, sess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := deleteMissingAlerts(existingAlerts, cmd.Alerts, sess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func updateAlerts(existingAlerts []*models.Alert, alerts []*models.Alert, sess *DBSession) error {
|
||||
for _, alert := range alerts {
|
||||
update := false
|
||||
var alertToUpdate *models.Alert
|
||||
|
||||
@@ -245,11 +265,11 @@ func updateAlerts(existingAlerts []*models.Alert, cmd *models.SaveAlertsCommand,
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteMissingAlerts(alerts []*models.Alert, cmd *models.SaveAlertsCommand, sess *DBSession) error {
|
||||
func deleteMissingAlerts(alerts []*models.Alert, existingAlerts []*models.Alert, sess *DBSession) error {
|
||||
for _, missingAlert := range alerts {
|
||||
missing := true
|
||||
|
||||
for _, k := range cmd.Alerts {
|
||||
for _, k := range existingAlerts {
|
||||
if missingAlert.PanelId == k.PanelId {
|
||||
missing = false
|
||||
break
|
||||
|
||||
@@ -30,10 +30,11 @@ func TestAlertingDataAccess(t *testing.T) {
|
||||
defer resetTimeNow()
|
||||
|
||||
Convey("Testing Alerting data access", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
testDash := insertTestDashboard(t, "dashboard with alerts", 1, 0, false, "alert")
|
||||
evalData, _ := simplejson.NewJson([]byte(`{"test": "test"}`))
|
||||
testDash := insertTestDashboard(t, sqlStore, "dashboard with alerts", 1, 0, false, "alert")
|
||||
evalData, err := simplejson.NewJson([]byte(`{"test": "test"}`))
|
||||
So(err, ShouldBeNil)
|
||||
items := []*models.Alert{
|
||||
{
|
||||
PanelId: 1,
|
||||
@@ -54,7 +55,7 @@ func TestAlertingDataAccess(t *testing.T) {
|
||||
UserId: 1,
|
||||
}
|
||||
|
||||
err := SaveAlerts(&cmd)
|
||||
err = SaveAlerts(&cmd)
|
||||
|
||||
Convey("Can create one alert", func() {
|
||||
So(err, ShouldBeNil)
|
||||
@@ -271,10 +272,11 @@ func TestPausingAlerts(t *testing.T) {
|
||||
defer resetTimeNow()
|
||||
|
||||
Convey("Given an alert", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
testDash := insertTestDashboard(t, "dashboard with alerts", 1, 0, false, "alert")
|
||||
alert, _ := insertTestAlert("Alerting title", "Alerting message", testDash.OrgId, testDash.Id, simplejson.New())
|
||||
testDash := insertTestDashboard(t, sqlStore, "dashboard with alerts", 1, 0, false, "alert")
|
||||
alert, err := insertTestAlert("Alerting title", "Alerting message", testDash.OrgId, testDash.Id, simplejson.New())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
stateDateBeforePause := alert.NewStateDate
|
||||
stateDateAfterPause := stateDateBeforePause
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -24,7 +26,6 @@ var shadowSearchCounter = prometheus.NewCounterVec(
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", SaveDashboard)
|
||||
bus.AddHandler("sql", GetDashboard)
|
||||
bus.AddHandler("sql", GetDashboards)
|
||||
bus.AddHandler("sql", DeleteDashboard)
|
||||
@@ -35,7 +36,6 @@ func init() {
|
||||
bus.AddHandler("sql", GetDashboardsByPluginId)
|
||||
bus.AddHandler("sql", GetDashboardPermissionsForUser)
|
||||
bus.AddHandler("sql", GetDashboardsBySlug)
|
||||
bus.AddHandler("sql", ValidateDashboardBeforeSave)
|
||||
bus.AddHandler("sql", HasEditPermissionInFolders)
|
||||
bus.AddHandler("sql", HasAdminPermissionInFolders)
|
||||
|
||||
@@ -44,10 +44,11 @@ func init() {
|
||||
|
||||
var generateNewUid func() string = util.GenerateShortUID
|
||||
|
||||
func SaveDashboard(cmd *models.SaveDashboardCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
return saveDashboard(sess, cmd)
|
||||
func (ss *SQLStore) SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error) {
|
||||
err := ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
return saveDashboard(sess, &cmd)
|
||||
})
|
||||
return cmd.Result, err
|
||||
}
|
||||
|
||||
func saveDashboard(sess *DBSession, cmd *models.SaveDashboardCommand) error {
|
||||
@@ -162,7 +163,7 @@ func saveDashboard(sess *DBSession, cmd *models.SaveDashboardCommand) error {
|
||||
|
||||
cmd.Result = dash
|
||||
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateNewDashboardUid(sess *DBSession, orgId int64) (string, error) {
|
||||
@@ -182,6 +183,26 @@ func generateNewDashboardUid(sess *DBSession, orgId int64) (string, error) {
|
||||
return "", models.ErrDashboardFailedGenerateUniqueUid
|
||||
}
|
||||
|
||||
// GetDashboard gets a dashboard.
|
||||
func (ss *SQLStore) GetDashboard(id, orgID int64, uid, slug string) (*models.Dashboard, error) {
|
||||
if id == 0 && slug == "" && uid == "" {
|
||||
return nil, models.ErrDashboardIdentifierNotSet
|
||||
}
|
||||
|
||||
dashboard := models.Dashboard{Slug: slug, OrgId: orgID, Id: id, Uid: uid}
|
||||
has, err := ss.engine.Get(&dashboard)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, models.ErrDashboardNotFound
|
||||
}
|
||||
|
||||
dashboard.SetId(dashboard.Id)
|
||||
dashboard.SetUid(dashboard.Uid)
|
||||
return &dashboard, nil
|
||||
}
|
||||
|
||||
// TODO: Remove me
|
||||
func GetDashboard(query *models.GetDashboardQuery) error {
|
||||
if query.Id == 0 && len(query.Slug) == 0 && len(query.Uid) == 0 {
|
||||
return models.ErrDashboardIdentifierNotSet
|
||||
@@ -573,20 +594,20 @@ func GetDashboardUIDById(query *models.GetDashboardRefByIdQuery) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, cmd *models.ValidateDashboardBeforeSaveCommand) (err error) {
|
||||
dash := cmd.Dashboard
|
||||
|
||||
func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, dash *models.Dashboard, overwrite bool) (bool, error) {
|
||||
dashWithIdExists := false
|
||||
isParentFolderChanged := false
|
||||
var existingById models.Dashboard
|
||||
|
||||
if dash.Id > 0 {
|
||||
var err error
|
||||
dashWithIdExists, err = sess.Where("id=? AND org_id=?", dash.Id, dash.OrgId).Get(&existingById)
|
||||
if err != nil {
|
||||
return err
|
||||
return isParentFolderChanged, fmt.Errorf("SQL query for existing dashboard by ID failed: %w", err)
|
||||
}
|
||||
|
||||
if !dashWithIdExists {
|
||||
return models.ErrDashboardNotFound
|
||||
return isParentFolderChanged, models.ErrDashboardNotFound
|
||||
}
|
||||
|
||||
if dash.Uid == "" {
|
||||
@@ -598,30 +619,32 @@ func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, cmd *models.Validat
|
||||
var existingByUid models.Dashboard
|
||||
|
||||
if dash.Uid != "" {
|
||||
var err error
|
||||
dashWithUidExists, err = sess.Where("org_id=? AND uid=?", dash.OrgId, dash.Uid).Get(&existingByUid)
|
||||
if err != nil {
|
||||
return err
|
||||
return isParentFolderChanged, fmt.Errorf("SQL query for existing dashboard by UID failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if dash.FolderId > 0 {
|
||||
var existingFolder models.Dashboard
|
||||
folderExists, folderErr := sess.Where("org_id=? AND id=? AND is_folder=?", dash.OrgId, dash.FolderId, dialect.BooleanStr(true)).Get(&existingFolder)
|
||||
if folderErr != nil {
|
||||
return folderErr
|
||||
folderExists, err := sess.Where("org_id=? AND id=? AND is_folder=?", dash.OrgId, dash.FolderId,
|
||||
dialect.BooleanStr(true)).Get(&existingFolder)
|
||||
if err != nil {
|
||||
return isParentFolderChanged, fmt.Errorf("SQL query for folder failed: %w", err)
|
||||
}
|
||||
|
||||
if !folderExists {
|
||||
return models.ErrDashboardFolderNotFound
|
||||
return isParentFolderChanged, models.ErrDashboardFolderNotFound
|
||||
}
|
||||
}
|
||||
|
||||
if !dashWithIdExists && !dashWithUidExists {
|
||||
return nil
|
||||
return isParentFolderChanged, nil
|
||||
}
|
||||
|
||||
if dashWithIdExists && dashWithUidExists && existingById.Id != existingByUid.Id {
|
||||
return models.ErrDashboardWithSameUIDExists
|
||||
return isParentFolderChanged, models.ErrDashboardWithSameUIDExists
|
||||
}
|
||||
|
||||
existing := existingById
|
||||
@@ -632,84 +655,92 @@ func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, cmd *models.Validat
|
||||
existing = existingByUid
|
||||
|
||||
if !dash.IsFolder {
|
||||
cmd.Result.IsParentFolderChanged = true
|
||||
isParentFolderChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
if (existing.IsFolder && !dash.IsFolder) ||
|
||||
(!existing.IsFolder && dash.IsFolder) {
|
||||
return models.ErrDashboardTypeMismatch
|
||||
return isParentFolderChanged, models.ErrDashboardTypeMismatch
|
||||
}
|
||||
|
||||
if !dash.IsFolder && dash.FolderId != existing.FolderId {
|
||||
cmd.Result.IsParentFolderChanged = true
|
||||
isParentFolderChanged = true
|
||||
}
|
||||
|
||||
// check for is someone else has written in between
|
||||
if dash.Version != existing.Version {
|
||||
if cmd.Overwrite {
|
||||
if overwrite {
|
||||
dash.SetVersion(existing.Version)
|
||||
} else {
|
||||
return models.ErrDashboardVersionMismatch
|
||||
return isParentFolderChanged, models.ErrDashboardVersionMismatch
|
||||
}
|
||||
}
|
||||
|
||||
// do not allow plugin dashboard updates without overwrite flag
|
||||
if existing.PluginId != "" && !cmd.Overwrite {
|
||||
return models.UpdatePluginDashboardError{PluginId: existing.PluginId}
|
||||
if existing.PluginId != "" && !overwrite {
|
||||
return isParentFolderChanged, models.UpdatePluginDashboardError{PluginId: existing.PluginId}
|
||||
}
|
||||
|
||||
return nil
|
||||
return isParentFolderChanged, nil
|
||||
}
|
||||
|
||||
func getExistingDashboardByTitleAndFolder(sess *DBSession, cmd *models.ValidateDashboardBeforeSaveCommand) error {
|
||||
dash := cmd.Dashboard
|
||||
func getExistingDashboardByTitleAndFolder(sess *DBSession, dash *models.Dashboard, overwrite,
|
||||
isParentFolderChanged bool) (bool, error) {
|
||||
var existing models.Dashboard
|
||||
|
||||
exists, err := sess.Where("org_id=? AND slug=? AND (is_folder=? OR folder_id=?)", dash.OrgId, dash.Slug, dialect.BooleanStr(true), dash.FolderId).Get(&existing)
|
||||
exists, err := sess.Where("org_id=? AND slug=? AND (is_folder=? OR folder_id=?)", dash.OrgId, dash.Slug,
|
||||
dialect.BooleanStr(true), dash.FolderId).Get(&existing)
|
||||
if err != nil {
|
||||
return err
|
||||
return isParentFolderChanged, fmt.Errorf("SQL query for existing dashboard by org ID or folder ID failed: %w", err)
|
||||
}
|
||||
|
||||
if exists && dash.Id != existing.Id {
|
||||
if existing.IsFolder && !dash.IsFolder {
|
||||
return models.ErrDashboardWithSameNameAsFolder
|
||||
return isParentFolderChanged, models.ErrDashboardWithSameNameAsFolder
|
||||
}
|
||||
|
||||
if !existing.IsFolder && dash.IsFolder {
|
||||
return models.ErrDashboardFolderWithSameNameAsDashboard
|
||||
return isParentFolderChanged, models.ErrDashboardFolderWithSameNameAsDashboard
|
||||
}
|
||||
|
||||
if !dash.IsFolder && (dash.FolderId != existing.FolderId || dash.Id == 0) {
|
||||
cmd.Result.IsParentFolderChanged = true
|
||||
isParentFolderChanged = true
|
||||
}
|
||||
|
||||
if cmd.Overwrite {
|
||||
if overwrite {
|
||||
dash.SetId(existing.Id)
|
||||
dash.SetUid(existing.Uid)
|
||||
dash.SetVersion(existing.Version)
|
||||
} else {
|
||||
return models.ErrDashboardWithSameNameInFolderExists
|
||||
return isParentFolderChanged, models.ErrDashboardWithSameNameInFolderExists
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return isParentFolderChanged, nil
|
||||
}
|
||||
|
||||
func ValidateDashboardBeforeSave(cmd *models.ValidateDashboardBeforeSaveCommand) (err error) {
|
||||
cmd.Result = &models.ValidateDashboardBeforeSaveResult{}
|
||||
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
if err = getExistingDashboardByIdOrUidForUpdate(sess, cmd); err != nil {
|
||||
func (ss *SQLStore) ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error) {
|
||||
isParentFolderChanged := false
|
||||
err := ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
var err error
|
||||
isParentFolderChanged, err = getExistingDashboardByIdOrUidForUpdate(sess, dashboard, overwrite)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = getExistingDashboardByTitleAndFolder(sess, cmd); err != nil {
|
||||
isParentFolderChanged, err = getExistingDashboardByTitleAndFolder(sess, dashboard, overwrite,
|
||||
isParentFolderChanged)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return isParentFolderChanged, nil
|
||||
}
|
||||
|
||||
func HasEditPermissionInFolders(query *models.HasEditPermissionInFoldersQuery) error {
|
||||
@@ -719,7 +750,8 @@ func HasEditPermissionInFolders(query *models.HasEditPermissionInFoldersQuery) e
|
||||
}
|
||||
|
||||
builder := &SQLBuilder{}
|
||||
builder.Write("SELECT COUNT(dashboard.id) AS count FROM dashboard WHERE dashboard.org_id = ? AND dashboard.is_folder = ?", query.SignedInUser.OrgId, dialect.BooleanStr(true))
|
||||
builder.Write("SELECT COUNT(dashboard.id) AS count FROM dashboard WHERE dashboard.org_id = ? AND dashboard.is_folder = ?",
|
||||
query.SignedInUser.OrgId, dialect.BooleanStr(true))
|
||||
builder.WriteDashboardPermissionFilter(query.SignedInUser, models.PERMISSION_EDIT)
|
||||
|
||||
type folderCount struct {
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", UpdateDashboardAcl)
|
||||
bus.AddHandler("sql", GetDashboardAclInfoList)
|
||||
}
|
||||
|
||||
func UpdateDashboardAcl(cmd *models.UpdateDashboardAclCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
func (ss *SQLStore) UpdateDashboardACL(dashboardID int64, items []*models.DashboardAcl) error {
|
||||
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
// delete existing items
|
||||
_, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", cmd.DashboardID)
|
||||
_, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", dashboardID)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("deleting from dashboard_acl failed: %w", err)
|
||||
}
|
||||
|
||||
for _, item := range cmd.Items {
|
||||
for _, item := range items {
|
||||
if item.UserID == 0 && item.TeamID == 0 && (item.Role == nil || !item.Role.IsValid()) {
|
||||
return models.ErrDashboardAclInfoMissing
|
||||
}
|
||||
@@ -35,7 +37,7 @@ func UpdateDashboardAcl(cmd *models.UpdateDashboardAclCommand) error {
|
||||
|
||||
// Update dashboard HasAcl flag
|
||||
dashboard := models.Dashboard{HasAcl: true}
|
||||
_, err = sess.Cols("has_acl").Where("id=?", cmd.DashboardID).Update(&dashboard)
|
||||
_, err = sess.Cols("has_acl").Where("id=?", dashboardID).Update(&dashboard)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -11,14 +11,15 @@ import (
|
||||
|
||||
func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("Testing DB", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Given a dashboard folder and a user", func() {
|
||||
currentUser := createUser(t, "viewer", "Viewer", false)
|
||||
savedFolder := insertTestDashboard(t, "1 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
childDash := insertTestDashboard(t, "2 test dash", 1, savedFolder.Id, false, "prod", "webapp")
|
||||
currentUser := createUser(t, sqlStore, "viewer", "Viewer", false)
|
||||
savedFolder := insertTestDashboard(t, sqlStore, "1 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
childDash := insertTestDashboard(t, sqlStore, "2 test dash", 1, savedFolder.Id, false, "prod", "webapp")
|
||||
|
||||
Convey("When adding dashboard permission with userId and teamId set to 0", func() {
|
||||
err := testHelperUpdateDashboardAcl(savedFolder.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, savedFolder.Id, models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
DashboardID: savedFolder.Id,
|
||||
Permission: models.PERMISSION_EDIT,
|
||||
@@ -61,10 +62,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given dashboard folder with removed default permissions", func() {
|
||||
err := UpdateDashboardAcl(&models.UpdateDashboardAclCommand{
|
||||
DashboardID: savedFolder.Id,
|
||||
Items: []*models.DashboardAcl{},
|
||||
})
|
||||
err := sqlStore.UpdateDashboardACL(savedFolder.Id, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When reading dashboard acl should return no acl items", func() {
|
||||
@@ -78,7 +76,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given dashboard folder permission", func() {
|
||||
err := testHelperUpdateDashboardAcl(savedFolder.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, savedFolder.Id, models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
UserID: currentUser.Id,
|
||||
DashboardID: savedFolder.Id,
|
||||
@@ -97,7 +95,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given child dashboard permission", func() {
|
||||
err := testHelperUpdateDashboardAcl(childDash.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, childDash.Id, models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
UserID: currentUser.Id,
|
||||
DashboardID: childDash.Id,
|
||||
@@ -121,7 +119,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given child dashboard permission in folder with no permissions", func() {
|
||||
err := testHelperUpdateDashboardAcl(childDash.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, childDash.Id, models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
UserID: currentUser.Id,
|
||||
DashboardID: childDash.Id,
|
||||
@@ -149,7 +147,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to add dashboard permission", func() {
|
||||
err := testHelperUpdateDashboardAcl(savedFolder.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, savedFolder.Id, models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
UserID: currentUser.Id,
|
||||
DashboardID: savedFolder.Id,
|
||||
@@ -169,7 +167,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(q1.Result[0].UserEmail, ShouldEqual, currentUser.Email)
|
||||
|
||||
Convey("Should be able to delete an existing permission", func() {
|
||||
err := testHelperUpdateDashboardAcl(savedFolder.Id)
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, savedFolder.Id)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q3 := &models.GetDashboardAclInfoListQuery{DashboardID: savedFolder.Id, OrgID: 1}
|
||||
@@ -180,14 +178,13 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given a team", func() {
|
||||
group1 := models.CreateTeamCommand{Name: "group1 name", OrgId: 1}
|
||||
err := CreateTeam(&group1)
|
||||
team1, err := sqlStore.CreateTeam("group1 name", "", 1)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Should be able to add a user permission for a team", func() {
|
||||
err := testHelperUpdateDashboardAcl(savedFolder.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, savedFolder.Id, models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
TeamID: group1.Result.Id,
|
||||
TeamID: team1.Id,
|
||||
DashboardID: savedFolder.Id,
|
||||
Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
@@ -198,13 +195,13 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
So(q1.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
|
||||
So(q1.Result[0].Permission, ShouldEqual, models.PERMISSION_EDIT)
|
||||
So(q1.Result[0].TeamId, ShouldEqual, group1.Result.Id)
|
||||
So(q1.Result[0].TeamId, ShouldEqual, team1.Id)
|
||||
})
|
||||
|
||||
Convey("Should be able to update an existing permission for a team", func() {
|
||||
err := testHelperUpdateDashboardAcl(savedFolder.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, savedFolder.Id, models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
TeamID: group1.Result.Id,
|
||||
TeamID: team1.Id,
|
||||
DashboardID: savedFolder.Id,
|
||||
Permission: models.PERMISSION_ADMIN,
|
||||
})
|
||||
@@ -216,7 +213,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(len(q3.Result), ShouldEqual, 1)
|
||||
So(q3.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
|
||||
So(q3.Result[0].Permission, ShouldEqual, models.PERMISSION_ADMIN)
|
||||
So(q3.Result[0].TeamId, ShouldEqual, group1.Result.Id)
|
||||
So(q3.Result[0].TeamId, ShouldEqual, team1.Id)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,21 +7,22 @@ import (
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/search"
|
||||
)
|
||||
|
||||
func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
Convey("Testing DB", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Given one dashboard folder with two dashboards and one dashboard in the root folder", func() {
|
||||
folder := insertTestDashboard(t, "1 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
dashInRoot := insertTestDashboard(t, "test dash 67", 1, 0, false, "prod", "webapp")
|
||||
childDash := insertTestDashboard(t, "test dash 23", 1, folder.Id, false, "prod", "webapp")
|
||||
insertTestDashboard(t, "test dash 45", 1, folder.Id, false, "prod")
|
||||
folder := insertTestDashboard(t, sqlStore, "1 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
dashInRoot := insertTestDashboard(t, sqlStore, "test dash 67", 1, 0, false, "prod", "webapp")
|
||||
childDash := insertTestDashboard(t, sqlStore, "test dash 23", 1, folder.Id, false, "prod", "webapp")
|
||||
insertTestDashboard(t, sqlStore, "test dash 45", 1, folder.Id, false, "prod")
|
||||
|
||||
currentUser := createUser(t, "viewer", "Viewer", false)
|
||||
currentUser := createUser(t, sqlStore, "viewer", "Viewer", false)
|
||||
|
||||
Convey("and no acls are set", func() {
|
||||
Convey("should return all dashboards", func() {
|
||||
@@ -40,7 +41,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
|
||||
Convey("and acl is set for dashboard folder", func() {
|
||||
var otherUser int64 = 999
|
||||
err := testHelperUpdateDashboardAcl(folder.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder.Id, models.DashboardAcl{
|
||||
DashboardID: folder.Id,
|
||||
OrgID: 1,
|
||||
UserID: otherUser,
|
||||
@@ -61,7 +62,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("when the user is given permission", func() {
|
||||
err := testHelperUpdateDashboardAcl(folder.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder.Id, models.DashboardAcl{
|
||||
DashboardID: folder.Id, OrgID: 1, UserID: currentUser.Id, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -102,9 +103,9 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
|
||||
Convey("and acl is set for dashboard child and folder has all permissions removed", func() {
|
||||
var otherUser int64 = 999
|
||||
err := testHelperUpdateDashboardAcl(folder.Id)
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder.Id)
|
||||
So(err, ShouldBeNil)
|
||||
err = testHelperUpdateDashboardAcl(childDash.Id, models.DashboardAcl{
|
||||
err = testHelperUpdateDashboardAcl(t, sqlStore, childDash.Id, models.DashboardAcl{
|
||||
DashboardID: folder.Id, OrgID: 1, UserID: otherUser, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -120,7 +121,9 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("when the user is given permission to child", func() {
|
||||
err := testHelperUpdateDashboardAcl(childDash.Id, models.DashboardAcl{DashboardID: childDash.Id, OrgID: 1, UserID: currentUser.Id, Permission: models.PERMISSION_EDIT})
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, childDash.Id, models.DashboardAcl{
|
||||
DashboardID: childDash.Id, OrgID: 1, UserID: currentUser.Id, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("should be able to search for child dashboard but not folder", func() {
|
||||
@@ -156,18 +159,24 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given two dashboard folders with one dashboard each and one dashboard in the root folder", func() {
|
||||
folder1 := insertTestDashboard(t, "1 test dash folder", 1, 0, true, "prod")
|
||||
folder2 := insertTestDashboard(t, "2 test dash folder", 1, 0, true, "prod")
|
||||
dashInRoot := insertTestDashboard(t, "test dash 67", 1, 0, false, "prod")
|
||||
childDash1 := insertTestDashboard(t, "child dash 1", 1, folder1.Id, false, "prod")
|
||||
childDash2 := insertTestDashboard(t, "child dash 2", 1, folder2.Id, false, "prod")
|
||||
folder1 := insertTestDashboard(t, sqlStore, "1 test dash folder", 1, 0, true, "prod")
|
||||
folder2 := insertTestDashboard(t, sqlStore, "2 test dash folder", 1, 0, true, "prod")
|
||||
dashInRoot := insertTestDashboard(t, sqlStore, "test dash 67", 1, 0, false, "prod")
|
||||
childDash1 := insertTestDashboard(t, sqlStore, "child dash 1", 1, folder1.Id, false, "prod")
|
||||
childDash2 := insertTestDashboard(t, sqlStore, "child dash 2", 1, folder2.Id, false, "prod")
|
||||
|
||||
currentUser := createUser(t, "viewer", "Viewer", false)
|
||||
currentUser := createUser(t, sqlStore, "viewer", "Viewer", false)
|
||||
var rootFolderId int64 = 0
|
||||
|
||||
Convey("and one folder is expanded, the other collapsed", func() {
|
||||
Convey("should return dashboards in root and expanded folder", func() {
|
||||
query := &search.FindPersistedDashboardsQuery{FolderIds: []int64{rootFolderId, folder1.Id}, SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1}
|
||||
query := &search.FindPersistedDashboardsQuery{
|
||||
FolderIds: []int64{
|
||||
rootFolderId, folder1.Id}, SignedInUser: &models.SignedInUser{UserId: currentUser.Id,
|
||||
OrgId: 1, OrgRole: models.ROLE_VIEWER,
|
||||
},
|
||||
OrgId: 1,
|
||||
}
|
||||
err := SearchDashboards(query)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result), ShouldEqual, 4)
|
||||
@@ -179,14 +188,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("and acl is set for one dashboard folder", func() {
|
||||
var otherUser int64 = 999
|
||||
err := testHelperUpdateDashboardAcl(folder1.Id, models.DashboardAcl{
|
||||
const otherUser int64 = 999
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder1.Id, models.DashboardAcl{
|
||||
DashboardID: folder1.Id, OrgID: 1, UserID: otherUser, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("and a dashboard is moved from folder without acl to the folder with an acl", func() {
|
||||
moveDashboard(1, childDash2.Data, folder1.Id)
|
||||
moveDashboard(t, sqlStore, 1, childDash2.Data, folder1.Id)
|
||||
|
||||
Convey("should not return folder with acl or its children", func() {
|
||||
query := &search.FindPersistedDashboardsQuery{
|
||||
@@ -201,7 +210,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
})
|
||||
Convey("and a dashboard is moved from folder with acl to the folder without an acl", func() {
|
||||
moveDashboard(1, childDash1.Data, folder2.Id)
|
||||
moveDashboard(t, sqlStore, 1, childDash1.Data, folder2.Id)
|
||||
|
||||
Convey("should return folder without acl and its children", func() {
|
||||
query := &search.FindPersistedDashboardsQuery{
|
||||
@@ -220,12 +229,12 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("and a dashboard with an acl is moved to the folder without an acl", func() {
|
||||
err := testHelperUpdateDashboardAcl(childDash1.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, childDash1.Id, models.DashboardAcl{
|
||||
DashboardID: childDash1.Id, OrgID: 1, UserID: otherUser, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
moveDashboard(1, childDash1.Data, folder2.Id)
|
||||
moveDashboard(t, sqlStore, 1, childDash1.Data, folder2.Id)
|
||||
|
||||
Convey("should return folder without acl but not the dashboard with acl", func() {
|
||||
query := &search.FindPersistedDashboardsQuery{
|
||||
@@ -246,13 +255,13 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given two dashboard folders", func() {
|
||||
folder1 := insertTestDashboard(t, "1 test dash folder", 1, 0, true, "prod")
|
||||
folder2 := insertTestDashboard(t, "2 test dash folder", 1, 0, true, "prod")
|
||||
insertTestDashboard(t, "folder in another org", 2, 0, true, "prod")
|
||||
folder1 := insertTestDashboard(t, sqlStore, "1 test dash folder", 1, 0, true, "prod")
|
||||
folder2 := insertTestDashboard(t, sqlStore, "2 test dash folder", 1, 0, true, "prod")
|
||||
insertTestDashboard(t, sqlStore, "folder in another org", 2, 0, true, "prod")
|
||||
|
||||
adminUser := createUser(t, "admin", "Admin", true)
|
||||
editorUser := createUser(t, "editor", "Editor", false)
|
||||
viewerUser := createUser(t, "viewer", "Viewer", false)
|
||||
adminUser := createUser(t, sqlStore, "admin", "Admin", true)
|
||||
editorUser := createUser(t, sqlStore, "editor", "Editor", false)
|
||||
viewerUser := createUser(t, sqlStore, "viewer", "Viewer", false)
|
||||
|
||||
Convey("Admin users", func() {
|
||||
Convey("Should have write access to all dashboard folders in their org", func() {
|
||||
@@ -343,7 +352,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should have write access to one dashboard folder if default role changed to view for one folder", func() {
|
||||
err := testHelperUpdateDashboardAcl(folder1.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder1.Id, models.DashboardAcl{
|
||||
DashboardID: folder1.Id, OrgID: 1, UserID: editorUser.Id, Permission: models.PERMISSION_VIEW,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -407,7 +416,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to get one dashboard folder if default role changed to edit for one folder", func() {
|
||||
err := testHelperUpdateDashboardAcl(folder1.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder1.Id, models.DashboardAcl{
|
||||
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.Id, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -438,7 +447,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("and admin permission is given for user with org role viewer in one dashboard folder", func() {
|
||||
err := testHelperUpdateDashboardAcl(folder1.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder1.Id, models.DashboardAcl{
|
||||
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.Id, Permission: models.PERMISSION_ADMIN,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -454,7 +463,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("and edit permission is given for user with org role viewer in one dashboard folder", func() {
|
||||
err := testHelperUpdateDashboardAcl(folder1.Id, models.DashboardAcl{
|
||||
err := testHelperUpdateDashboardAcl(t, sqlStore, folder1.Id, models.DashboardAcl{
|
||||
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.Id, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -472,3 +481,19 @@ func TestDashboardFolderDataAccess(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func moveDashboard(t *testing.T, sqlStore *SQLStore, orgId int64, dashboard *simplejson.Json,
|
||||
newFolderId int64) *models.Dashboard {
|
||||
t.Helper()
|
||||
|
||||
cmd := models.SaveDashboardCommand{
|
||||
OrgId: orgId,
|
||||
FolderId: newFolderId,
|
||||
Dashboard: dashboard,
|
||||
Overwrite: true,
|
||||
}
|
||||
dash, err := sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
return dash
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@@ -8,9 +9,6 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", GetProvisionedDashboardDataQuery)
|
||||
bus.AddHandler("sql", SaveProvisionedDashboard)
|
||||
bus.AddHandler("sql", GetProvisionedDataByDashboardId)
|
||||
bus.AddHandler("sql", UnprovisionDashboard)
|
||||
bus.AddHandler("sql", DeleteOrphanedProvisionedDashboards)
|
||||
}
|
||||
@@ -22,64 +20,62 @@ type DashboardExtras struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
func GetProvisionedDataByDashboardId(cmd *models.GetProvisionedDashboardDataByIdQuery) error {
|
||||
result := &models.DashboardProvisioning{}
|
||||
|
||||
exist, err := x.Where("dashboard_id = ?", cmd.DashboardId).Get(result)
|
||||
func (ss *SQLStore) GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error) {
|
||||
var data models.DashboardProvisioning
|
||||
exists, err := x.Where("dashboard_id = ?", dashboardID).Get(&data)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if exist {
|
||||
cmd.Result = result
|
||||
if exists {
|
||||
return &data, nil
|
||||
}
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func SaveProvisionedDashboard(cmd *models.SaveProvisionedDashboardCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
err := saveDashboard(sess, cmd.DashboardCmd)
|
||||
if err != nil {
|
||||
func (ss *SQLStore) SaveProvisionedDashboard(cmd models.SaveDashboardCommand,
|
||||
provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
|
||||
err := ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
if err := saveDashboard(sess, &cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Result = cmd.DashboardCmd.Result
|
||||
if cmd.DashboardProvisioning.Updated == 0 {
|
||||
cmd.DashboardProvisioning.Updated = cmd.Result.Updated.Unix()
|
||||
if provisioning.Updated == 0 {
|
||||
provisioning.Updated = cmd.Result.Updated.Unix()
|
||||
}
|
||||
|
||||
return saveProvisionedData(sess, cmd.DashboardProvisioning, cmd.Result)
|
||||
return saveProvisionedData(sess, provisioning, cmd.Result)
|
||||
})
|
||||
|
||||
return cmd.Result, err
|
||||
}
|
||||
|
||||
func saveProvisionedData(sess *DBSession, cmd *models.DashboardProvisioning, dashboard *models.Dashboard) error {
|
||||
func saveProvisionedData(sess *DBSession, provisioning *models.DashboardProvisioning, dashboard *models.Dashboard) error {
|
||||
result := &models.DashboardProvisioning{}
|
||||
|
||||
exist, err := sess.Where("dashboard_id=? AND name = ?", dashboard.Id, cmd.Name).Get(result)
|
||||
exist, err := sess.Where("dashboard_id=? AND name = ?", dashboard.Id, provisioning.Name).Get(result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Id = result.Id
|
||||
cmd.DashboardId = dashboard.Id
|
||||
provisioning.Id = result.Id
|
||||
provisioning.DashboardId = dashboard.Id
|
||||
|
||||
if exist {
|
||||
_, err = sess.ID(result.Id).Update(cmd)
|
||||
_, err = sess.ID(result.Id).Update(provisioning)
|
||||
} else {
|
||||
_, err = sess.Insert(cmd)
|
||||
_, err = sess.Insert(provisioning)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func GetProvisionedDashboardDataQuery(cmd *models.GetProvisionedDashboardDataQuery) error {
|
||||
func (ss *SQLStore) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) {
|
||||
var result []*models.DashboardProvisioning
|
||||
|
||||
if err := x.Where("name = ?", cmd.Name).Find(&result); err != nil {
|
||||
return err
|
||||
if err := ss.engine.Where("name = ?", name).Find(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd.Result = result
|
||||
return nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UnprovisionDashboard removes row in dashboard_provisioning for the dashboard making it seem as if manually created.
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
|
||||
func TestDashboardProvisioningTest(t *testing.T) {
|
||||
Convey("Testing Dashboard provisioning", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
folderCmd := &models.SaveDashboardCommand{
|
||||
folderCmd := models.SaveDashboardCommand{
|
||||
OrgId: 1,
|
||||
FolderId: 0,
|
||||
IsFolder: true,
|
||||
@@ -25,13 +25,13 @@ func TestDashboardProvisioningTest(t *testing.T) {
|
||||
}),
|
||||
}
|
||||
|
||||
err := SaveDashboard(folderCmd)
|
||||
dash, err := sqlStore.SaveDashboard(folderCmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
saveDashboardCmd := &models.SaveDashboardCommand{
|
||||
saveDashboardCmd := models.SaveDashboardCommand{
|
||||
OrgId: 1,
|
||||
IsFolder: false,
|
||||
FolderId: folderCmd.Result.Id,
|
||||
FolderId: dash.Id,
|
||||
Dashboard: simplejson.NewFromAny(map[string]interface{}{
|
||||
"id": nil,
|
||||
"title": "test dashboard",
|
||||
@@ -41,43 +41,38 @@ func TestDashboardProvisioningTest(t *testing.T) {
|
||||
Convey("Saving dashboards with provisioning meta data", func() {
|
||||
now := time.Now()
|
||||
|
||||
cmd := &models.SaveProvisionedDashboardCommand{
|
||||
DashboardCmd: saveDashboardCmd,
|
||||
DashboardProvisioning: &models.DashboardProvisioning{
|
||||
Name: "default",
|
||||
ExternalId: "/var/grafana.json",
|
||||
Updated: now.Unix(),
|
||||
},
|
||||
provisioning := &models.DashboardProvisioning{
|
||||
Name: "default",
|
||||
ExternalId: "/var/grafana.json",
|
||||
Updated: now.Unix(),
|
||||
}
|
||||
|
||||
err := SaveProvisionedDashboard(cmd)
|
||||
dash, err := sqlStore.SaveProvisionedDashboard(saveDashboardCmd, provisioning)
|
||||
So(err, ShouldBeNil)
|
||||
So(cmd.Result, ShouldNotBeNil)
|
||||
So(cmd.Result.Id, ShouldNotEqual, 0)
|
||||
dashId := cmd.Result.Id
|
||||
So(dash, ShouldNotBeNil)
|
||||
So(dash.Id, ShouldNotEqual, 0)
|
||||
dashId := dash.Id
|
||||
|
||||
Convey("Deleting orphaned provisioned dashboards", func() {
|
||||
anotherCmd := &models.SaveProvisionedDashboardCommand{
|
||||
DashboardCmd: &models.SaveDashboardCommand{
|
||||
OrgId: 1,
|
||||
IsFolder: false,
|
||||
FolderId: folderCmd.Result.Id,
|
||||
Dashboard: simplejson.NewFromAny(map[string]interface{}{
|
||||
"id": nil,
|
||||
"title": "another_dashboard",
|
||||
}),
|
||||
},
|
||||
DashboardProvisioning: &models.DashboardProvisioning{
|
||||
Name: "another_reader",
|
||||
ExternalId: "/var/grafana.json",
|
||||
Updated: now.Unix(),
|
||||
},
|
||||
saveCmd := models.SaveDashboardCommand{
|
||||
OrgId: 1,
|
||||
IsFolder: false,
|
||||
FolderId: dash.Id,
|
||||
Dashboard: simplejson.NewFromAny(map[string]interface{}{
|
||||
"id": nil,
|
||||
"title": "another_dashboard",
|
||||
}),
|
||||
}
|
||||
provisioning := &models.DashboardProvisioning{
|
||||
Name: "another_reader",
|
||||
ExternalId: "/var/grafana.json",
|
||||
Updated: now.Unix(),
|
||||
}
|
||||
|
||||
err := SaveProvisionedDashboard(anotherCmd)
|
||||
anotherDash, err := sqlStore.SaveProvisionedDashboard(saveCmd, provisioning)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
query := &models.GetDashboardsQuery{DashboardIds: []int64{anotherCmd.Result.Id}}
|
||||
query := &models.GetDashboardsQuery{DashboardIds: []int64{anotherDash.Id}}
|
||||
err = GetDashboards(query)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result, ShouldNotBeNil)
|
||||
@@ -85,7 +80,7 @@ func TestDashboardProvisioningTest(t *testing.T) {
|
||||
deleteCmd := &models.DeleteOrphanedProvisionedDashboardsCommand{ReaderNames: []string{"default"}}
|
||||
So(DeleteOrphanedProvisionedDashboards(deleteCmd), ShouldBeNil)
|
||||
|
||||
query = &models.GetDashboardsQuery{DashboardIds: []int64{cmd.Result.Id, anotherCmd.Result.Id}}
|
||||
query = &models.GetDashboardsQuery{DashboardIds: []int64{dash.Id, anotherDash.Id}}
|
||||
err = GetDashboards(query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -94,45 +89,38 @@ func TestDashboardProvisioningTest(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Can query for provisioned dashboards", func() {
|
||||
query := &models.GetProvisionedDashboardDataQuery{Name: "default"}
|
||||
err := GetProvisionedDashboardDataQuery(query)
|
||||
rslt, err := sqlStore.GetProvisionedDashboardData("default")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 1)
|
||||
So(query.Result[0].DashboardId, ShouldEqual, dashId)
|
||||
So(query.Result[0].Updated, ShouldEqual, now.Unix())
|
||||
So(len(rslt), ShouldEqual, 1)
|
||||
So(rslt[0].DashboardId, ShouldEqual, dashId)
|
||||
So(rslt[0].Updated, ShouldEqual, now.Unix())
|
||||
})
|
||||
|
||||
Convey("Can query for one provisioned dashboard", func() {
|
||||
query := &models.GetProvisionedDashboardDataByIdQuery{DashboardId: cmd.Result.Id}
|
||||
|
||||
err := GetProvisionedDataByDashboardId(query)
|
||||
data, err := sqlStore.GetProvisionedDataByDashboardID(dash.Id)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(query.Result, ShouldNotBeNil)
|
||||
So(data, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("Can query for none provisioned dashboard", func() {
|
||||
query := &models.GetProvisionedDashboardDataByIdQuery{DashboardId: 3000}
|
||||
|
||||
err := GetProvisionedDataByDashboardId(query)
|
||||
data, err := sqlStore.GetProvisionedDataByDashboardID(3000)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result, ShouldBeNil)
|
||||
So(data, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("Deleting folder should delete provision meta data", func() {
|
||||
deleteCmd := &models.DeleteDashboardCommand{
|
||||
Id: folderCmd.Result.Id,
|
||||
Id: dash.Id,
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
So(DeleteDashboard(deleteCmd), ShouldBeNil)
|
||||
|
||||
query := &models.GetProvisionedDashboardDataByIdQuery{DashboardId: cmd.Result.Id}
|
||||
|
||||
err = GetProvisionedDataByDashboardId(query)
|
||||
data, err := sqlStore.GetProvisionedDataByDashboardID(dash.Id)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result, ShouldBeNil)
|
||||
So(data, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("UnprovisionDashboard should delete provisioning metadata", func() {
|
||||
@@ -142,11 +130,9 @@ func TestDashboardProvisioningTest(t *testing.T) {
|
||||
|
||||
So(UnprovisionDashboard(unprovisionCmd), ShouldBeNil)
|
||||
|
||||
query := &models.GetProvisionedDashboardDataByIdQuery{DashboardId: dashId}
|
||||
|
||||
err = GetProvisionedDataByDashboardId(query)
|
||||
data, err := sqlStore.GetProvisionedDataByDashboardID(dashId)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result, ShouldBeNil)
|
||||
So(data, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,13 +22,13 @@ import (
|
||||
|
||||
func TestDashboardDataAccess(t *testing.T) {
|
||||
Convey("Testing DB", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Given saved dashboard", func() {
|
||||
savedFolder := insertTestDashboard(t, "1 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
savedDash := insertTestDashboard(t, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||
insertTestDashboard(t, "test dash 45", 1, savedFolder.Id, false, "prod")
|
||||
insertTestDashboard(t, "test dash 67", 1, 0, false, "prod", "webapp")
|
||||
savedFolder := insertTestDashboard(t, sqlStore, "1 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
savedDash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||
insertTestDashboard(t, sqlStore, "test dash 45", 1, savedFolder.Id, false, "prod")
|
||||
insertTestDashboard(t, sqlStore, "test dash 67", 1, 0, false, "prod", "webapp")
|
||||
|
||||
Convey("Should return dashboard model", func() {
|
||||
So(savedDash.Title, ShouldEqual, "test dash 23")
|
||||
@@ -104,7 +104,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to delete dashboard", func() {
|
||||
dash := insertTestDashboard(t, "delete me", 1, 0, false, "delete this")
|
||||
dash := insertTestDashboard(t, sqlStore, "delete me", 1, 0, false, "delete this")
|
||||
|
||||
err := DeleteDashboard(&models.DeleteDashboardCommand{
|
||||
Id: dash.Id,
|
||||
@@ -129,8 +129,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
"tags": []interface{}{},
|
||||
}),
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
_, err := sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
generateNewUid = util.GenerateShortUID
|
||||
@@ -145,13 +144,12 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
}),
|
||||
UserId: 100,
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
dashboard, err := sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
So(cmd.Result.CreatedBy, ShouldEqual, 100)
|
||||
So(cmd.Result.Created.IsZero(), ShouldBeFalse)
|
||||
So(cmd.Result.UpdatedBy, ShouldEqual, 100)
|
||||
So(cmd.Result.Updated.IsZero(), ShouldBeFalse)
|
||||
So(dashboard.CreatedBy, ShouldEqual, 100)
|
||||
So(dashboard.Created.IsZero(), ShouldBeFalse)
|
||||
So(dashboard.UpdatedBy, ShouldEqual, 100)
|
||||
So(dashboard.Updated.IsZero(), ShouldBeFalse)
|
||||
})
|
||||
|
||||
Convey("Should be able to update dashboard by id and remove folderId", func() {
|
||||
@@ -166,10 +164,9 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
FolderId: 2,
|
||||
UserId: 100,
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
dash, err := sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
So(cmd.Result.FolderId, ShouldEqual, 2)
|
||||
So(dash.FolderId, ShouldEqual, 2)
|
||||
|
||||
cmd = models.SaveDashboardCommand{
|
||||
OrgId: 1,
|
||||
@@ -182,8 +179,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
Overwrite: true,
|
||||
UserId: 100,
|
||||
}
|
||||
|
||||
err = SaveDashboard(&cmd)
|
||||
_, err = sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
query := models.GetDashboardQuery{
|
||||
@@ -201,7 +197,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to delete empty folder", func() {
|
||||
emptyFolder := insertTestDashboard(t, "2 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
emptyFolder := insertTestDashboard(t, sqlStore, "2 test dash folder", 1, 0, true, "prod", "webapp")
|
||||
|
||||
deleteCmd := &models.DeleteDashboardCommand{Id: emptyFolder.Id}
|
||||
err := DeleteDashboard(deleteCmd)
|
||||
@@ -236,7 +232,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
}),
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
_, err := sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldEqual, models.ErrDashboardNotFound)
|
||||
})
|
||||
|
||||
@@ -250,8 +246,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
"tags": []interface{}{},
|
||||
}),
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
_, err := sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@@ -366,7 +361,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given two dashboards, one is starred dashboard by user 10, other starred by user 1", func() {
|
||||
starredDash := insertTestDashboard(t, "starred dash", 1, 0, false)
|
||||
starredDash := insertTestDashboard(t, sqlStore, "starred dash", 1, 0, false)
|
||||
err := StarDashboard(&models.StarDashboardCommand{
|
||||
DashboardId: starredDash.Id,
|
||||
UserId: 10,
|
||||
@@ -396,9 +391,9 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
Convey("Given a plugin with imported dashboards", func() {
|
||||
pluginId := "test-app"
|
||||
|
||||
appFolder := insertTestDashboardForPlugin("app-test", 1, 0, true, pluginId)
|
||||
insertTestDashboardForPlugin("app-dash1", 1, appFolder.Id, false, pluginId)
|
||||
insertTestDashboardForPlugin("app-dash2", 1, appFolder.Id, false, pluginId)
|
||||
appFolder := insertTestDashboardForPlugin(t, sqlStore, "app-test", 1, 0, true, pluginId)
|
||||
insertTestDashboardForPlugin(t, sqlStore, "app-dash1", 1, appFolder.Id, false, pluginId)
|
||||
insertTestDashboardForPlugin(t, sqlStore, "app-dash2", 1, appFolder.Id, false, pluginId)
|
||||
|
||||
Convey("Should return imported dashboard", func() {
|
||||
query := models.GetDashboardsByPluginIdQuery{
|
||||
@@ -417,9 +412,9 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
func TestDashboard_SortingOptions(t *testing.T) {
|
||||
// insertTestDashboard uses GoConvey's assertions. Workaround.
|
||||
Convey("test with multiple sorting options", t, func() {
|
||||
InitTestDB(t)
|
||||
dashB := insertTestDashboard(t, "Beta", 1, 0, false)
|
||||
dashA := insertTestDashboard(t, "Alfa", 1, 0, false)
|
||||
sqlStore := InitTestDB(t)
|
||||
dashB := insertTestDashboard(t, sqlStore, "Beta", 1, 0, false)
|
||||
dashA := insertTestDashboard(t, sqlStore, "Alfa", 1, 0, false)
|
||||
|
||||
assert.NotZero(t, dashA.Id)
|
||||
assert.Less(t, dashB.Id, dashA.Id)
|
||||
@@ -441,7 +436,8 @@ func TestDashboard_SortingOptions(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func insertTestDashboard(t *testing.T, title string, orgId int64, folderId int64, isFolder bool, tags ...interface{}) *models.Dashboard {
|
||||
func insertTestDashboard(t *testing.T, sqlStore *SQLStore, title string, orgId int64,
|
||||
folderId int64, isFolder bool, tags ...interface{}) *models.Dashboard {
|
||||
t.Helper()
|
||||
|
||||
cmd := models.SaveDashboardCommand{
|
||||
@@ -454,17 +450,20 @@ func insertTestDashboard(t *testing.T, title string, orgId int64, folderId int64
|
||||
"tags": tags,
|
||||
}),
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
dash, err := sqlStore.SaveDashboard(cmd)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, dash)
|
||||
|
||||
cmd.Result.Data.Set("id", cmd.Result.Id)
|
||||
cmd.Result.Data.Set("uid", cmd.Result.Uid)
|
||||
dash.Data.Set("id", dash.Id)
|
||||
dash.Data.Set("uid", dash.Uid)
|
||||
|
||||
return cmd.Result
|
||||
return dash
|
||||
}
|
||||
|
||||
func insertTestDashboardForPlugin(title string, orgId int64, folderId int64, isFolder bool, pluginId string) *models.Dashboard {
|
||||
func insertTestDashboardForPlugin(t *testing.T, sqlStore *SQLStore, title string, orgId int64,
|
||||
folderId int64, isFolder bool, pluginId string) *models.Dashboard {
|
||||
t.Helper()
|
||||
|
||||
cmd := models.SaveDashboardCommand{
|
||||
OrgId: orgId,
|
||||
FolderId: folderId,
|
||||
@@ -476,13 +475,13 @@ func insertTestDashboardForPlugin(title string, orgId int64, folderId int64, isF
|
||||
PluginId: pluginId,
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
dash, err := sqlStore.SaveDashboard(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
return cmd.Result
|
||||
return dash
|
||||
}
|
||||
|
||||
func createUser(t *testing.T, name string, role string, isAdmin bool) models.User {
|
||||
func createUser(t *testing.T, sqlStore *SQLStore, name string, role string, isAdmin bool) models.User {
|
||||
t.Helper()
|
||||
|
||||
setting.AutoAssignOrg = true
|
||||
@@ -490,27 +489,13 @@ func createUser(t *testing.T, name string, role string, isAdmin bool) models.Use
|
||||
setting.AutoAssignOrgRole = role
|
||||
|
||||
currentUserCmd := models.CreateUserCommand{Login: name, Email: name + "@test.com", Name: "a " + name, IsAdmin: isAdmin}
|
||||
err := CreateUser(context.Background(), ¤tUserCmd)
|
||||
currentUser, err := sqlStore.CreateUser(context.Background(), currentUserCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
q1 := models.GetUserOrgListQuery{UserId: currentUserCmd.Result.Id}
|
||||
q1 := models.GetUserOrgListQuery{UserId: currentUser.Id}
|
||||
err = GetUserOrgList(&q1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, models.RoleType(role), q1.Result[0].Role)
|
||||
|
||||
return currentUserCmd.Result
|
||||
}
|
||||
|
||||
func moveDashboard(orgId int64, dashboard *simplejson.Json, newFolderId int64) *models.Dashboard {
|
||||
cmd := models.SaveDashboardCommand{
|
||||
OrgId: orgId,
|
||||
FolderId: newFolderId,
|
||||
Dashboard: dashboard,
|
||||
Overwrite: true,
|
||||
}
|
||||
|
||||
err := SaveDashboard(&cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
return cmd.Result
|
||||
return *currentUser
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func updateTestDashboard(dashboard *models.Dashboard, data map[string]interface{}) {
|
||||
func updateTestDashboard(t *testing.T, sqlStore *SQLStore, dashboard *models.Dashboard, data map[string]interface{}) {
|
||||
t.Helper()
|
||||
|
||||
data["id"] = dashboard.Id
|
||||
|
||||
saveCmd := models.SaveDashboardCommand{
|
||||
@@ -21,17 +23,16 @@ func updateTestDashboard(dashboard *models.Dashboard, data map[string]interface{
|
||||
Overwrite: true,
|
||||
Dashboard: simplejson.NewFromAny(data),
|
||||
}
|
||||
|
||||
err := SaveDashboard(&saveCmd)
|
||||
_, err := sqlStore.SaveDashboard(saveCmd)
|
||||
So(err, ShouldBeNil)
|
||||
}
|
||||
|
||||
func TestGetDashboardVersion(t *testing.T) {
|
||||
Convey("Testing dashboard version retrieval", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Get a Dashboard ID and version ID", func() {
|
||||
savedDash := insertTestDashboard(t, "test dash 26", 1, 0, false, "diff")
|
||||
savedDash := insertTestDashboard(t, sqlStore, "test dash 26", 1, 0, false, "diff")
|
||||
|
||||
query := models.GetDashboardVersionQuery{
|
||||
DashboardId: savedDash.Id,
|
||||
@@ -71,8 +72,8 @@ func TestGetDashboardVersion(t *testing.T) {
|
||||
|
||||
func TestGetDashboardVersions(t *testing.T) {
|
||||
Convey("Testing dashboard versions retrieval", t, func() {
|
||||
InitTestDB(t)
|
||||
savedDash := insertTestDashboard(t, "test dash 43", 1, 0, false, "diff-all")
|
||||
sqlStore := InitTestDB(t)
|
||||
savedDash := insertTestDashboard(t, sqlStore, "test dash 43", 1, 0, false, "diff-all")
|
||||
|
||||
Convey("Get all versions for a given Dashboard ID", func() {
|
||||
query := models.GetDashboardVersionsQuery{DashboardId: savedDash.Id, OrgId: 1}
|
||||
@@ -92,7 +93,7 @@ func TestGetDashboardVersions(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Get all versions for an updated dashboard", func() {
|
||||
updateTestDashboard(savedDash, map[string]interface{}{
|
||||
updateTestDashboard(t, sqlStore, savedDash, map[string]interface{}{
|
||||
"tags": "different-tag",
|
||||
})
|
||||
|
||||
@@ -107,14 +108,14 @@ func TestGetDashboardVersions(t *testing.T) {
|
||||
|
||||
func TestDeleteExpiredVersions(t *testing.T) {
|
||||
Convey("Testing dashboard versions clean up", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
versionsToKeep := 5
|
||||
versionsToWrite := 10
|
||||
setting.DashboardVersionsToKeep = versionsToKeep
|
||||
|
||||
savedDash := insertTestDashboard(t, "test dash 53", 1, 0, false, "diff-all")
|
||||
savedDash := insertTestDashboard(t, sqlStore, "test dash 53", 1, 0, false, "diff-all")
|
||||
for i := 0; i < versionsToWrite-1; i++ {
|
||||
updateTestDashboard(savedDash, map[string]interface{}{
|
||||
updateTestDashboard(t, sqlStore, savedDash, map[string]interface{}{
|
||||
"tags": "different-tag",
|
||||
})
|
||||
}
|
||||
@@ -152,7 +153,7 @@ func TestDeleteExpiredVersions(t *testing.T) {
|
||||
|
||||
versionsToWriteBigNumber := perBatch*maxBatches + versionsToWrite
|
||||
for i := 0; i < versionsToWriteBigNumber-versionsToWrite; i++ {
|
||||
updateTestDashboard(savedDash, map[string]interface{}{
|
||||
updateTestDashboard(t, sqlStore, savedDash, map[string]interface{}{
|
||||
"tags": "different-tag",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
func TestAccountDataAccess(t *testing.T) {
|
||||
Convey("Testing Account DB Access", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Given we have organizations, we can query them by IDs", func() {
|
||||
var err error
|
||||
@@ -78,13 +78,13 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
ac1cmd := models.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
|
||||
ac2cmd := models.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name"}
|
||||
|
||||
err := CreateUser(context.Background(), &ac1cmd)
|
||||
ac1, err := sqlStore.CreateUser(context.Background(), ac1cmd)
|
||||
So(err, ShouldBeNil)
|
||||
err = CreateUser(context.Background(), &ac2cmd)
|
||||
ac2, err := sqlStore.CreateUser(context.Background(), ac2cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q1 := models.GetUserOrgListQuery{UserId: ac1cmd.Result.Id}
|
||||
q2 := models.GetUserOrgListQuery{UserId: ac2cmd.Result.Id}
|
||||
q1 := models.GetUserOrgListQuery{UserId: ac1.Id}
|
||||
q2 := models.GetUserOrgListQuery{UserId: ac2.Id}
|
||||
err = GetUserOrgList(&q1)
|
||||
So(err, ShouldBeNil)
|
||||
err = GetUserOrgList(&q2)
|
||||
@@ -101,13 +101,10 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
ac1cmd := models.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
|
||||
ac2cmd := models.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name", IsAdmin: true}
|
||||
|
||||
err := CreateUser(context.Background(), &ac1cmd)
|
||||
err = CreateUser(context.Background(), &ac2cmd)
|
||||
ac1, err := sqlStore.CreateUser(context.Background(), ac1cmd)
|
||||
ac2, err := sqlStore.CreateUser(context.Background(), ac2cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
ac1 := ac1cmd.Result
|
||||
ac2 := ac2cmd.Result
|
||||
|
||||
Convey("Should be able to read user info projection", func() {
|
||||
query := models.GetUserProfileQuery{UserId: ac1.Id}
|
||||
err = GetUserProfile(&query)
|
||||
@@ -266,9 +263,8 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Given an org user with dashboard permissions", func() {
|
||||
ac3cmd := models.CreateUserCommand{Login: "ac3", Email: "ac3@test.com", Name: "ac3 name", IsAdmin: false}
|
||||
err := CreateUser(context.Background(), &ac3cmd)
|
||||
ac3, err := sqlStore.CreateUser(context.Background(), ac3cmd)
|
||||
So(err, ShouldBeNil)
|
||||
ac3 := ac3cmd.Result
|
||||
|
||||
orgUserCmd := models.AddOrgUserCommand{
|
||||
OrgId: ac1.OrgId,
|
||||
@@ -284,13 +280,17 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result), ShouldEqual, 3)
|
||||
|
||||
dash1 := insertTestDashboard(t, "1 test dash", ac1.OrgId, 0, false, "prod", "webapp")
|
||||
dash2 := insertTestDashboard(t, "2 test dash", ac3.OrgId, 0, false, "prod", "webapp")
|
||||
dash1 := insertTestDashboard(t, sqlStore, "1 test dash", ac1.OrgId, 0, false, "prod", "webapp")
|
||||
dash2 := insertTestDashboard(t, sqlStore, "2 test dash", ac3.OrgId, 0, false, "prod", "webapp")
|
||||
|
||||
err = testHelperUpdateDashboardAcl(dash1.Id, models.DashboardAcl{DashboardID: dash1.Id, OrgID: ac1.OrgId, UserID: ac3.Id, Permission: models.PERMISSION_EDIT})
|
||||
err = testHelperUpdateDashboardAcl(t, sqlStore, dash1.Id, models.DashboardAcl{
|
||||
DashboardID: dash1.Id, OrgID: ac1.OrgId, UserID: ac3.Id, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = testHelperUpdateDashboardAcl(dash2.Id, models.DashboardAcl{DashboardID: dash2.Id, OrgID: ac3.OrgId, UserID: ac3.Id, Permission: models.PERMISSION_EDIT})
|
||||
err = testHelperUpdateDashboardAcl(t, sqlStore, dash2.Id, models.DashboardAcl{
|
||||
DashboardID: dash2.Id, OrgID: ac3.OrgId, UserID: ac3.Id, Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When org user is deleted", func() {
|
||||
@@ -322,13 +322,16 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func testHelperUpdateDashboardAcl(dashboardId int64, items ...models.DashboardAcl) error {
|
||||
cmd := models.UpdateDashboardAclCommand{DashboardID: dashboardId}
|
||||
for _, i := range items {
|
||||
item := i
|
||||
func testHelperUpdateDashboardAcl(t *testing.T, sqlStore *SQLStore, dashboardID int64,
|
||||
items ...models.DashboardAcl) error {
|
||||
t.Helper()
|
||||
|
||||
var itemPtrs []*models.DashboardAcl
|
||||
for _, it := range items {
|
||||
item := it
|
||||
item.Created = time.Now()
|
||||
item.Updated = time.Now()
|
||||
cmd.Items = append(cmd.Items, &item)
|
||||
itemPtrs = append(itemPtrs, &item)
|
||||
}
|
||||
return UpdateDashboardAcl(&cmd)
|
||||
return sqlStore.UpdateDashboardACL(dashboardID, itemPtrs)
|
||||
}
|
||||
|
||||
@@ -10,25 +10,27 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", GetPluginSettings)
|
||||
bus.AddHandler("sql", GetPluginSettingById)
|
||||
bus.AddHandler("sql", UpdatePluginSetting)
|
||||
bus.AddHandler("sql", UpdatePluginSettingVersion)
|
||||
}
|
||||
|
||||
func GetPluginSettings(query *models.GetPluginSettingsQuery) error {
|
||||
func (ss *SQLStore) GetPluginSettings(orgID int64) ([]*models.PluginSettingInfoDTO, error) {
|
||||
sql := `SELECT org_id, plugin_id, enabled, pinned, plugin_version
|
||||
FROM plugin_setting `
|
||||
params := make([]interface{}, 0)
|
||||
|
||||
if query.OrgId != 0 {
|
||||
if orgID != 0 {
|
||||
sql += "WHERE org_id=?"
|
||||
params = append(params, query.OrgId)
|
||||
params = append(params, orgID)
|
||||
}
|
||||
|
||||
sess := x.SQL(sql, params...)
|
||||
query.Result = make([]*models.PluginSettingInfoDTO, 0)
|
||||
return sess.Find(&query.Result)
|
||||
var rslt []*models.PluginSettingInfoDTO
|
||||
if err := sess.Find(&rslt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rslt, nil
|
||||
}
|
||||
|
||||
func GetPluginSettingById(query *models.GetPluginSettingByIdQuery) error {
|
||||
|
||||
@@ -5,7 +5,6 @@ package searchstore_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -34,13 +33,11 @@ func TestBuilder_EqualResults_Basic(t *testing.T) {
|
||||
}
|
||||
|
||||
db := setupTestEnvironment(t)
|
||||
err := createDashboards(0, 1, user.OrgId)
|
||||
require.NoError(t, err)
|
||||
createDashboards(t, db, 0, 1, user.OrgId)
|
||||
|
||||
// create one dashboard in another organization that shouldn't
|
||||
// be listed in the results.
|
||||
err = createDashboards(1, 2, 2)
|
||||
require.NoError(t, err)
|
||||
createDashboards(t, db, 1, 2, 2)
|
||||
|
||||
builder := &searchstore.Builder{
|
||||
Filters: []interface{}{
|
||||
@@ -51,7 +48,7 @@ func TestBuilder_EqualResults_Basic(t *testing.T) {
|
||||
}
|
||||
|
||||
res := []sqlstore.DashboardSearchProjection{}
|
||||
err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
err := db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
sql, params := builder.ToSQL(limit, page)
|
||||
return sess.SQL(sql, params...).Find(&res)
|
||||
})
|
||||
@@ -77,8 +74,7 @@ func TestBuilder_Pagination(t *testing.T) {
|
||||
}
|
||||
|
||||
db := setupTestEnvironment(t)
|
||||
err := createDashboards(0, 25, user.OrgId)
|
||||
require.NoError(t, err)
|
||||
createDashboards(t, db, 0, 25, user.OrgId)
|
||||
|
||||
builder := &searchstore.Builder{
|
||||
Filters: []interface{}{
|
||||
@@ -91,7 +87,7 @@ func TestBuilder_Pagination(t *testing.T) {
|
||||
resPg1 := []sqlstore.DashboardSearchProjection{}
|
||||
resPg2 := []sqlstore.DashboardSearchProjection{}
|
||||
resPg3 := []sqlstore.DashboardSearchProjection{}
|
||||
err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
err := db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
sql, params := builder.ToSQL(15, 1)
|
||||
err := sess.SQL(sql, params...).Find(&resPg1)
|
||||
if err != nil {
|
||||
@@ -124,8 +120,7 @@ func TestBuilder_Permissions(t *testing.T) {
|
||||
}
|
||||
|
||||
db := setupTestEnvironment(t)
|
||||
err := createDashboards(0, 1, user.OrgId)
|
||||
require.NoError(t, err)
|
||||
createDashboards(t, db, 0, 1, user.OrgId)
|
||||
|
||||
level := models.PERMISSION_EDIT
|
||||
|
||||
@@ -145,7 +140,7 @@ func TestBuilder_Permissions(t *testing.T) {
|
||||
}
|
||||
|
||||
res := []sqlstore.DashboardSearchProjection{}
|
||||
err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
err := db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
sql, params := builder.ToSQL(limit, page)
|
||||
return sess.SQL(sql, params...).Find(&res)
|
||||
})
|
||||
@@ -161,10 +156,10 @@ func setupTestEnvironment(t *testing.T) *sqlstore.SQLStore {
|
||||
return store
|
||||
}
|
||||
|
||||
func createDashboards(startID, endID int, orgID int64) error {
|
||||
if endID < startID {
|
||||
return fmt.Errorf("startID must be smaller than endID")
|
||||
}
|
||||
func createDashboards(t *testing.T, db *sqlstore.SQLStore, startID, endID int, orgID int64) {
|
||||
t.Helper()
|
||||
|
||||
require.GreaterOrEqual(t, endID, startID)
|
||||
|
||||
for i := startID; i < endID; i++ {
|
||||
dashboard, err := simplejson.NewJson([]byte(`{
|
||||
@@ -176,20 +171,15 @@ func createDashboards(startID, endID int, orgID int64) error {
|
||||
"schemaVersion": 16,
|
||||
"version": 0
|
||||
}`))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sqlstore.SaveDashboard(&models.SaveDashboardCommand{
|
||||
require.NoError(t, err)
|
||||
_, err = db.SaveDashboard(models.SaveDashboardCommand{
|
||||
Dashboard: dashboard,
|
||||
UserId: 1,
|
||||
OrgId: orgID,
|
||||
UpdatedAt: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// lexiCounter counts in a lexicographically sortable order.
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSQLBuilder(t *testing.T) {
|
||||
@@ -138,8 +139,8 @@ func TestSQLBuilder(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
var shouldFind = true
|
||||
var shouldNotFind = false
|
||||
const shouldFind = true
|
||||
const shouldNotFind = false
|
||||
|
||||
type DashboardProps struct {
|
||||
OrgId int64
|
||||
@@ -164,38 +165,35 @@ type dashboardResponse struct {
|
||||
}
|
||||
|
||||
func test(t *testing.T, dashboardProps DashboardProps, dashboardPermission *DashboardPermission, search Search, shouldFind bool) {
|
||||
// Will also cleanup the db
|
||||
sqlStore := InitTestDB(t)
|
||||
t.Helper()
|
||||
|
||||
dashboard, err := createDummyDashboard(dashboardProps)
|
||||
if !assert.Equal(t, nil, err) {
|
||||
return
|
||||
}
|
||||
t.Run("", func(t *testing.T) {
|
||||
// Will also cleanup the db
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
var aclUserId int64
|
||||
if dashboardPermission != nil {
|
||||
aclUserId, err = createDummyAcl(dashboardPermission, search, dashboard.Id)
|
||||
if !assert.Equal(t, nil, err) {
|
||||
return
|
||||
dashboard := createDummyDashboard(t, sqlStore, dashboardProps)
|
||||
|
||||
var aclUserID int64
|
||||
if dashboardPermission != nil {
|
||||
aclUserID = createDummyACL(t, sqlStore, dashboardPermission, search, dashboard.Id)
|
||||
t.Logf("Created ACL with user ID %d\n", aclUserID)
|
||||
}
|
||||
}
|
||||
dashboards, err := getDashboards(sqlStore, search, aclUserId)
|
||||
if !assert.Equal(t, nil, err) {
|
||||
return
|
||||
}
|
||||
dashboards := getDashboards(t, sqlStore, search, aclUserID)
|
||||
|
||||
if shouldFind {
|
||||
if assert.Equal(t, 1, len(dashboards), "Should return one dashboard") {
|
||||
assert.Equal(t, dashboards[0].Id, dashboard.Id, "Should return created dashboard")
|
||||
if shouldFind {
|
||||
require.Len(t, dashboards, 1, "Should return one dashboard")
|
||||
assert.Equal(t, dashboard.Id, dashboards[0].Id, "Should return created dashboard")
|
||||
} else {
|
||||
assert.Empty(t, dashboards, "Should not return any dashboard")
|
||||
}
|
||||
} else {
|
||||
assert.Equal(t, 0, len(dashboards), "Should node return any dashboard")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func createDummyUser() (*models.User, error) {
|
||||
func createDummyUser(t *testing.T, sqlStore *SQLStore) *models.User {
|
||||
t.Helper()
|
||||
|
||||
uid := strconv.Itoa(rand.Intn(9999999))
|
||||
createUserCmd := &models.CreateUserCommand{
|
||||
createUserCmd := models.CreateUserCommand{
|
||||
Email: uid + "@example.com",
|
||||
Login: uid,
|
||||
Name: uid,
|
||||
@@ -207,33 +205,28 @@ func createDummyUser() (*models.User, error) {
|
||||
SkipOrgSetup: false,
|
||||
DefaultOrgRole: string(models.ROLE_VIEWER),
|
||||
}
|
||||
err := CreateUser(context.Background(), createUserCmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, err := sqlStore.CreateUser(context.Background(), createUserCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
return &createUserCmd.Result, nil
|
||||
return user
|
||||
}
|
||||
|
||||
func createDummyTeam() (*models.Team, error) {
|
||||
cmd := &models.CreateTeamCommand{
|
||||
// Does not matter in this tests actually
|
||||
OrgId: 1,
|
||||
Name: "test",
|
||||
Email: "test@example.com",
|
||||
}
|
||||
err := CreateTeam(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func createDummyTeam(t *testing.T, sqlStore *SQLStore) models.Team {
|
||||
t.Helper()
|
||||
|
||||
return &cmd.Result, nil
|
||||
team, err := sqlStore.CreateTeam("test", "test@example.com", 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
return team
|
||||
}
|
||||
|
||||
func createDummyDashboard(dashboardProps DashboardProps) (*models.Dashboard, error) {
|
||||
json, _ := simplejson.NewJson([]byte(`{"schemaVersion":17,"title":"gdev dashboards","uid":"","version":1}`))
|
||||
func createDummyDashboard(t *testing.T, sqlStore *SQLStore, dashboardProps DashboardProps) *models.Dashboard {
|
||||
t.Helper()
|
||||
|
||||
saveDashboardCmd := &models.SaveDashboardCommand{
|
||||
json, err := simplejson.NewJson([]byte(`{"schemaVersion":17,"title":"gdev dashboards","uid":"","version":1}`))
|
||||
require.NoError(t, err)
|
||||
|
||||
saveDashboardCmd := models.SaveDashboardCommand{
|
||||
Dashboard: json,
|
||||
UserId: 0,
|
||||
Overwrite: false,
|
||||
@@ -250,53 +243,40 @@ func createDummyDashboard(dashboardProps DashboardProps) (*models.Dashboard, err
|
||||
saveDashboardCmd.OrgId = 1
|
||||
}
|
||||
|
||||
err := SaveDashboard(saveDashboardCmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dash, err := sqlStore.SaveDashboard(saveDashboardCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
return saveDashboardCmd.Result, nil
|
||||
t.Logf("Created dashboard with ID %d and org ID %d\n", dash.Id, dash.OrgId)
|
||||
return dash
|
||||
}
|
||||
|
||||
func createDummyAcl(dashboardPermission *DashboardPermission, search Search, dashboardId int64) (int64, error) {
|
||||
func createDummyACL(t *testing.T, sqlStore *SQLStore, dashboardPermission *DashboardPermission, search Search, dashboardID int64) int64 {
|
||||
t.Helper()
|
||||
|
||||
acl := &models.DashboardAcl{
|
||||
OrgID: 1,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
Permission: dashboardPermission.Permission,
|
||||
DashboardID: dashboardId,
|
||||
DashboardID: dashboardID,
|
||||
}
|
||||
|
||||
var user *models.User
|
||||
var err error
|
||||
if dashboardPermission.User {
|
||||
user, err = createDummyUser()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
t.Logf("Creating user")
|
||||
user = createDummyUser(t, sqlStore)
|
||||
|
||||
acl.UserID = user.Id
|
||||
}
|
||||
|
||||
if dashboardPermission.Team {
|
||||
team, err := createDummyTeam()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
t.Logf("Creating team")
|
||||
team := createDummyTeam(t, sqlStore)
|
||||
if search.UserFromACL {
|
||||
user, err = createDummyUser()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
addTeamMemberCmd := &models.AddTeamMemberCommand{
|
||||
UserId: user.Id,
|
||||
OrgId: 1,
|
||||
TeamId: team.Id,
|
||||
}
|
||||
err = AddTeamMember(addTeamMemberCmd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
user = createDummyUser(t, sqlStore)
|
||||
err := sqlStore.AddTeamMember(user.Id, 1, team.Id, false, 0)
|
||||
require.NoError(t, err)
|
||||
t.Logf("Created team member with ID %d", user.Id)
|
||||
}
|
||||
|
||||
acl.TeamID = team.Id
|
||||
@@ -306,18 +286,17 @@ func createDummyAcl(dashboardPermission *DashboardPermission, search Search, das
|
||||
acl.Role = &dashboardPermission.Role
|
||||
}
|
||||
|
||||
updateAclCmd := &models.UpdateDashboardAclCommand{
|
||||
DashboardID: dashboardId,
|
||||
Items: []*models.DashboardAcl{acl},
|
||||
}
|
||||
err = UpdateDashboardAcl(updateAclCmd)
|
||||
err := sqlStore.UpdateDashboardACL(dashboardID, []*models.DashboardAcl{acl})
|
||||
require.NoError(t, err)
|
||||
if user != nil {
|
||||
return user.Id, err
|
||||
return user.Id
|
||||
}
|
||||
return 0, err
|
||||
return 0
|
||||
}
|
||||
|
||||
func getDashboards(sqlStore *SQLStore, search Search, aclUserId int64) ([]*dashboardResponse, error) {
|
||||
func getDashboards(t *testing.T, sqlStore *SQLStore, search Search, aclUserID int64) []*dashboardResponse {
|
||||
t.Helper()
|
||||
|
||||
builder := &SQLBuilder{}
|
||||
signedInUser := &models.SignedInUser{
|
||||
UserId: 9999999999,
|
||||
@@ -335,12 +314,14 @@ func getDashboards(sqlStore *SQLStore, search Search, aclUserId int64) ([]*dashb
|
||||
signedInUser.OrgRole = models.ROLE_VIEWER
|
||||
}
|
||||
if search.UserFromACL {
|
||||
signedInUser.UserId = aclUserId
|
||||
signedInUser.UserId = aclUserID
|
||||
}
|
||||
|
||||
var res []*dashboardResponse
|
||||
builder.Write("SELECT * FROM dashboard WHERE true")
|
||||
builder.WriteDashboardPermissionFilter(signedInUser, search.RequiredPermission)
|
||||
t.Logf("Searching for dashboards, SQL: %q\n", builder.GetSQLString())
|
||||
err := sqlStore.engine.SQL(builder.GetSQLString(), builder.params...).Find(&res)
|
||||
return res, err
|
||||
require.NoError(t, err)
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/sqlutil"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
_ "github.com/grafana/grafana/pkg/tsdb/mssql"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
_ "github.com/lib/pq"
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
)
|
||||
|
||||
func TestStatsDataAccess(t *testing.T) {
|
||||
InitTestDB(t)
|
||||
populateDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
populateDB(t, sqlStore)
|
||||
|
||||
t.Run("Get system stats should not results in error", func(t *testing.T) {
|
||||
query := models.GetSystemStatsQuery{}
|
||||
@@ -57,18 +57,20 @@ func TestStatsDataAccess(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func populateDB(t *testing.T) {
|
||||
func populateDB(t *testing.T, sqlStore *SQLStore) {
|
||||
t.Helper()
|
||||
|
||||
users := make([]models.User, 3)
|
||||
for i := range users {
|
||||
cmd := &models.CreateUserCommand{
|
||||
cmd := models.CreateUserCommand{
|
||||
Email: fmt.Sprintf("usertest%v@test.com", i),
|
||||
Name: fmt.Sprintf("user name %v", i),
|
||||
Login: fmt.Sprintf("user_test_%v_login", i),
|
||||
OrgName: fmt.Sprintf("Org #%v", i),
|
||||
}
|
||||
err := CreateUser(context.Background(), cmd)
|
||||
user, err := sqlStore.CreateUser(context.Background(), cmd)
|
||||
require.NoError(t, err)
|
||||
users[i] = cmd.Result
|
||||
users[i] = *user
|
||||
}
|
||||
|
||||
// get 1st user's organisation
|
||||
|
||||
@@ -2,6 +2,7 @@ package sqlstore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -11,14 +12,12 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", CreateTeam)
|
||||
bus.AddHandler("sql", UpdateTeam)
|
||||
bus.AddHandler("sql", DeleteTeam)
|
||||
bus.AddHandler("sql", SearchTeams)
|
||||
bus.AddHandler("sql", GetTeamById)
|
||||
bus.AddHandler("sql", GetTeamsByUser)
|
||||
|
||||
bus.AddHandler("sql", AddTeamMember)
|
||||
bus.AddHandler("sql", UpdateTeamMember)
|
||||
bus.AddHandler("sql", RemoveTeamMember)
|
||||
bus.AddHandler("sql", GetTeamMembers)
|
||||
@@ -43,7 +42,7 @@ func getFilteredUsers(signedInUser *models.SignedInUser, hiddenUsers map[string]
|
||||
|
||||
func getTeamMemberCount(filteredUsers []string) string {
|
||||
if len(filteredUsers) > 0 {
|
||||
return `(SELECT COUNT(*) FROM team_member
|
||||
return `(SELECT COUNT(*) FROM team_member
|
||||
INNER JOIN ` + dialect.Quote("user") + ` ON team_member.user_id = ` + dialect.Quote("user") + `.id
|
||||
WHERE team_member.team_id = team.id AND ` + dialect.Quote("user") + `.login NOT IN (?` +
|
||||
strings.Repeat(",?", len(filteredUsers)-1) + ")" +
|
||||
@@ -75,28 +74,25 @@ func getTeamSelectSQLBase(filteredUsers []string) string {
|
||||
` FROM team as team `
|
||||
}
|
||||
|
||||
func CreateTeam(cmd *models.CreateTeamCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
if isNameTaken, err := isTeamNameTaken(cmd.OrgId, cmd.Name, 0, sess); err != nil {
|
||||
func (ss *SQLStore) CreateTeam(name, email string, orgID int64) (models.Team, error) {
|
||||
team := models.Team{
|
||||
Name: name,
|
||||
Email: email,
|
||||
OrgId: orgID,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
}
|
||||
err := ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
if isNameTaken, err := isTeamNameTaken(orgID, name, 0, sess); err != nil {
|
||||
return err
|
||||
} else if isNameTaken {
|
||||
return models.ErrTeamNameTaken
|
||||
}
|
||||
|
||||
team := models.Team{
|
||||
Name: cmd.Name,
|
||||
Email: cmd.Email,
|
||||
OrgId: cmd.OrgId,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
}
|
||||
|
||||
_, err := sess.Insert(&team)
|
||||
|
||||
cmd.Result = team
|
||||
|
||||
return err
|
||||
})
|
||||
return team, err
|
||||
}
|
||||
|
||||
func UpdateTeam(cmd *models.UpdateTeamCommand) error {
|
||||
@@ -152,8 +148,8 @@ func DeleteTeam(cmd *models.DeleteTeamCommand) error {
|
||||
})
|
||||
}
|
||||
|
||||
func teamExists(orgId int64, teamId int64, sess *DBSession) (bool, error) {
|
||||
if res, err := sess.Query("SELECT 1 from team WHERE org_id=? and id=?", orgId, teamId); err != nil {
|
||||
func teamExists(orgID int64, teamID int64, sess *DBSession) (bool, error) {
|
||||
if res, err := sess.Query("SELECT 1 from team WHERE org_id=? and id=?", orgID, teamID); err != nil {
|
||||
return false, err
|
||||
} else if len(res) != 1 {
|
||||
return false, models.ErrTeamNotFound
|
||||
@@ -165,7 +161,6 @@ func teamExists(orgId int64, teamId int64, sess *DBSession) (bool, error) {
|
||||
func isTeamNameTaken(orgId int64, name string, existingId int64, sess *DBSession) (bool, error) {
|
||||
var team models.Team
|
||||
exists, err := sess.Where("org_id=? and name=?", orgId, name).Get(&team)
|
||||
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
@@ -283,26 +278,27 @@ func GetTeamsByUser(query *models.GetTeamsByUserQuery) error {
|
||||
}
|
||||
|
||||
// AddTeamMember adds a user to a team
|
||||
func AddTeamMember(cmd *models.AddTeamMemberCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
if res, err := sess.Query("SELECT 1 from team_member WHERE org_id=? and team_id=? and user_id=?", cmd.OrgId, cmd.TeamId, cmd.UserId); err != nil {
|
||||
func (ss *SQLStore) AddTeamMember(userID, orgID, teamID int64, isExternal bool, permission models.PermissionType) error {
|
||||
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
if res, err := sess.Query("SELECT 1 from team_member WHERE org_id=? and team_id=? and user_id=?",
|
||||
orgID, teamID, userID); err != nil {
|
||||
return err
|
||||
} else if len(res) == 1 {
|
||||
return models.ErrTeamMemberAlreadyAdded
|
||||
}
|
||||
|
||||
if _, err := teamExists(cmd.OrgId, cmd.TeamId, sess); err != nil {
|
||||
if _, err := teamExists(orgID, teamID, sess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entity := models.TeamMember{
|
||||
OrgId: cmd.OrgId,
|
||||
TeamId: cmd.TeamId,
|
||||
UserId: cmd.UserId,
|
||||
External: cmd.External,
|
||||
OrgId: orgID,
|
||||
TeamId: teamID,
|
||||
UserId: userID,
|
||||
External: isExternal,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
Permission: cmd.Permission,
|
||||
Permission: permission,
|
||||
}
|
||||
|
||||
_, err := sess.Insert(&entity)
|
||||
|
||||
@@ -14,32 +14,29 @@ import (
|
||||
|
||||
func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
Convey("Testing Team commands & queries", t, func() {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Given saved users and two teams", func() {
|
||||
var userIds []int64
|
||||
for i := 0; i < 5; i++ {
|
||||
userCmd := &models.CreateUserCommand{
|
||||
userCmd := models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
Login: fmt.Sprint("loginuser", i),
|
||||
}
|
||||
err := CreateUser(context.Background(), userCmd)
|
||||
user, err := sqlStore.CreateUser(context.Background(), userCmd)
|
||||
So(err, ShouldBeNil)
|
||||
userIds = append(userIds, userCmd.Result.Id)
|
||||
userIds = append(userIds, user.Id)
|
||||
}
|
||||
|
||||
var testOrgId int64 = 1
|
||||
group1 := models.CreateTeamCommand{OrgId: testOrgId, Name: "group1 name", Email: "test1@test.com"}
|
||||
group2 := models.CreateTeamCommand{OrgId: testOrgId, Name: "group2 name", Email: "test2@test.com"}
|
||||
|
||||
err := CreateTeam(&group1)
|
||||
const testOrgID int64 = 1
|
||||
team1, err := sqlStore.CreateTeam("group1 name", "test1@test.com", testOrgID)
|
||||
So(err, ShouldBeNil)
|
||||
err = CreateTeam(&group2)
|
||||
team2, err := sqlStore.CreateTeam("group2 name", "test2@test.com", testOrgID)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Should be able to create teams and add users", func() {
|
||||
query := &models.SearchTeamsQuery{OrgId: testOrgId, Name: "group1 name", Page: 1, Limit: 10}
|
||||
query := &models.SearchTeamsQuery{OrgId: testOrgID, Name: "group1 name", Page: 1, Limit: 10}
|
||||
err = SearchTeams(query)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Page, ShouldEqual, 1)
|
||||
@@ -47,33 +44,33 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
team1 := query.Result.Teams[0]
|
||||
So(team1.Name, ShouldEqual, "group1 name")
|
||||
So(team1.Email, ShouldEqual, "test1@test.com")
|
||||
So(team1.OrgId, ShouldEqual, testOrgId)
|
||||
So(team1.OrgId, ShouldEqual, testOrgID)
|
||||
So(team1.MemberCount, ShouldEqual, 0)
|
||||
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: team1.Id, UserId: userIds[0]})
|
||||
err = sqlStore.AddTeamMember(userIds[0], testOrgID, team1.Id, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: team1.Id, UserId: userIds[1], External: true})
|
||||
err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, true, 0)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q1 := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: team1.Id}
|
||||
q1 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id}
|
||||
err = GetTeamMembers(q1)
|
||||
So(err, ShouldBeNil)
|
||||
So(q1.Result, ShouldHaveLength, 2)
|
||||
So(q1.Result[0].TeamId, ShouldEqual, team1.Id)
|
||||
So(q1.Result[0].Login, ShouldEqual, "loginuser0")
|
||||
So(q1.Result[0].OrgId, ShouldEqual, testOrgId)
|
||||
So(q1.Result[0].OrgId, ShouldEqual, testOrgID)
|
||||
So(q1.Result[1].TeamId, ShouldEqual, team1.Id)
|
||||
So(q1.Result[1].Login, ShouldEqual, "loginuser1")
|
||||
So(q1.Result[1].OrgId, ShouldEqual, testOrgId)
|
||||
So(q1.Result[1].OrgId, ShouldEqual, testOrgID)
|
||||
So(q1.Result[1].External, ShouldEqual, true)
|
||||
|
||||
q2 := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: team1.Id, External: true}
|
||||
q2 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id, External: true}
|
||||
err = GetTeamMembers(q2)
|
||||
So(err, ShouldBeNil)
|
||||
So(q2.Result, ShouldHaveLength, 1)
|
||||
So(q2.Result[0].TeamId, ShouldEqual, team1.Id)
|
||||
So(q2.Result[0].Login, ShouldEqual, "loginuser1")
|
||||
So(q2.Result[0].OrgId, ShouldEqual, testOrgId)
|
||||
So(q2.Result[0].OrgId, ShouldEqual, testOrgID)
|
||||
So(q2.Result[0].External, ShouldEqual, true)
|
||||
|
||||
err = SearchTeams(query)
|
||||
@@ -81,13 +78,13 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
team1 = query.Result.Teams[0]
|
||||
So(team1.MemberCount, ShouldEqual, 2)
|
||||
|
||||
getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgId, Id: team1.Id}
|
||||
getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: team1.Id}
|
||||
err = GetTeamById(getTeamQuery)
|
||||
So(err, ShouldBeNil)
|
||||
team1 = getTeamQuery.Result
|
||||
So(team1.Name, ShouldEqual, "group1 name")
|
||||
So(team1.Email, ShouldEqual, "test1@test.com")
|
||||
So(team1.OrgId, ShouldEqual, testOrgId)
|
||||
So(team1.OrgId, ShouldEqual, testOrgID)
|
||||
So(team1.MemberCount, ShouldEqual, 2)
|
||||
})
|
||||
|
||||
@@ -96,49 +93,48 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
err := SetAuthInfo(&models.SetAuthInfoCommand{UserId: userId, AuthModule: "oauth_github", AuthId: "1234567"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
teamQuery := &models.SearchTeamsQuery{OrgId: testOrgId, Name: "group1 name", Page: 1, Limit: 10}
|
||||
teamQuery := &models.SearchTeamsQuery{OrgId: testOrgID, Name: "group1 name", Page: 1, Limit: 10}
|
||||
err = SearchTeams(teamQuery)
|
||||
So(err, ShouldBeNil)
|
||||
So(teamQuery.Page, ShouldEqual, 1)
|
||||
|
||||
team1 := teamQuery.Result.Teams[0]
|
||||
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: team1.Id, UserId: userId, External: true})
|
||||
err = sqlStore.AddTeamMember(userId, testOrgID, team1.Id, true, 0)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
memberQuery := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: team1.Id, External: true}
|
||||
memberQuery := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id, External: true}
|
||||
err = GetTeamMembers(memberQuery)
|
||||
So(err, ShouldBeNil)
|
||||
So(memberQuery.Result, ShouldHaveLength, 1)
|
||||
So(memberQuery.Result[0].TeamId, ShouldEqual, team1.Id)
|
||||
So(memberQuery.Result[0].Login, ShouldEqual, "loginuser1")
|
||||
So(memberQuery.Result[0].OrgId, ShouldEqual, testOrgId)
|
||||
So(memberQuery.Result[0].OrgId, ShouldEqual, testOrgID)
|
||||
So(memberQuery.Result[0].External, ShouldEqual, true)
|
||||
So(memberQuery.Result[0].AuthModule, ShouldEqual, "oauth_github")
|
||||
})
|
||||
|
||||
Convey("Should be able to update users in a team", func() {
|
||||
userId := userIds[0]
|
||||
team := group1.Result
|
||||
addMemberCmd := models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: team.Id, UserId: userId}
|
||||
err = AddTeamMember(&addMemberCmd)
|
||||
team := team1
|
||||
err = sqlStore.AddTeamMember(userId, testOrgID, team.Id, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: team.Id}
|
||||
qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
|
||||
err = GetTeamMembers(qBeforeUpdate)
|
||||
So(err, ShouldBeNil)
|
||||
So(qBeforeUpdate.Result[0].Permission, ShouldEqual, 0)
|
||||
|
||||
err = UpdateTeamMember(&models.UpdateTeamMemberCommand{
|
||||
UserId: userId,
|
||||
OrgId: testOrgId,
|
||||
OrgId: testOrgID,
|
||||
TeamId: team.Id,
|
||||
Permission: models.PERMISSION_ADMIN,
|
||||
})
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: team.Id}
|
||||
qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
|
||||
err = GetTeamMembers(qAfterUpdate)
|
||||
So(err, ShouldBeNil)
|
||||
So(qAfterUpdate.Result[0].Permission, ShouldEqual, models.PERMISSION_ADMIN)
|
||||
@@ -146,12 +142,11 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
|
||||
Convey("Should default to member permission level when updating a user with invalid permission level", func() {
|
||||
userID := userIds[0]
|
||||
team := group1.Result
|
||||
addMemberCmd := models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: team.Id, UserId: userID}
|
||||
err = AddTeamMember(&addMemberCmd)
|
||||
team := team1
|
||||
err = sqlStore.AddTeamMember(userID, testOrgID, team.Id, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: team.Id}
|
||||
qBeforeUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
|
||||
err = GetTeamMembers(qBeforeUpdate)
|
||||
So(err, ShouldBeNil)
|
||||
So(qBeforeUpdate.Result[0].Permission, ShouldEqual, 0)
|
||||
@@ -159,14 +154,14 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
invalidPermissionLevel := models.PERMISSION_EDIT
|
||||
err = UpdateTeamMember(&models.UpdateTeamMemberCommand{
|
||||
UserId: userID,
|
||||
OrgId: testOrgId,
|
||||
OrgId: testOrgID,
|
||||
TeamId: team.Id,
|
||||
Permission: invalidPermissionLevel,
|
||||
})
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: team.Id}
|
||||
qAfterUpdate := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team.Id}
|
||||
err = GetTeamMembers(qAfterUpdate)
|
||||
So(err, ShouldBeNil)
|
||||
So(qAfterUpdate.Result[0].Permission, ShouldEqual, 0)
|
||||
@@ -175,8 +170,8 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
Convey("Shouldn't be able to update a user not in the team.", func() {
|
||||
err = UpdateTeamMember(&models.UpdateTeamMemberCommand{
|
||||
UserId: 1,
|
||||
OrgId: testOrgId,
|
||||
TeamId: group1.Result.Id,
|
||||
OrgId: testOrgID,
|
||||
TeamId: team1.Id,
|
||||
Permission: models.PERMISSION_ADMIN,
|
||||
})
|
||||
|
||||
@@ -184,24 +179,24 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to search for teams", func() {
|
||||
query := &models.SearchTeamsQuery{OrgId: testOrgId, Query: "group", Page: 1}
|
||||
query := &models.SearchTeamsQuery{OrgId: testOrgID, Query: "group", Page: 1}
|
||||
err = SearchTeams(query)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result.Teams), ShouldEqual, 2)
|
||||
So(query.Result.TotalCount, ShouldEqual, 2)
|
||||
|
||||
query2 := &models.SearchTeamsQuery{OrgId: testOrgId, Query: ""}
|
||||
query2 := &models.SearchTeamsQuery{OrgId: testOrgID, Query: ""}
|
||||
err = SearchTeams(query2)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query2.Result.Teams), ShouldEqual, 2)
|
||||
})
|
||||
|
||||
Convey("Should be able to return all teams a user is member of", func() {
|
||||
groupId := group2.Result.Id
|
||||
err := AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: groupId, UserId: userIds[0]})
|
||||
groupId := team2.Id
|
||||
err := sqlStore.AddTeamMember(userIds[0], testOrgID, groupId, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
query := &models.GetTeamsByUserQuery{OrgId: testOrgId, UserId: userIds[0]}
|
||||
query := &models.GetTeamsByUserQuery{OrgId: testOrgID, UserId: userIds[0]}
|
||||
err = GetTeamsByUser(query)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result), ShouldEqual, 1)
|
||||
@@ -210,63 +205,65 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to remove users from a group", func() {
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[0]})
|
||||
err = sqlStore.AddTeamMember(userIds[0], testOrgID, team1.Id, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = RemoveTeamMember(&models.RemoveTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[0]})
|
||||
err = RemoveTeamMember(&models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0]})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q2 := &models.GetTeamMembersQuery{OrgId: testOrgId, TeamId: group1.Result.Id}
|
||||
q2 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id}
|
||||
err = GetTeamMembers(q2)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(q2.Result), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("When ProtectLastAdmin is set to true", func() {
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[0], Permission: models.PERMISSION_ADMIN})
|
||||
err = sqlStore.AddTeamMember(userIds[0], testOrgID, team1.Id, false, models.PERMISSION_ADMIN)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("A user should not be able to remove the last admin", func() {
|
||||
err = RemoveTeamMember(&models.RemoveTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[0], ProtectLastAdmin: true})
|
||||
err = RemoveTeamMember(&models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], ProtectLastAdmin: true})
|
||||
So(err, ShouldEqual, models.ErrLastTeamAdmin)
|
||||
})
|
||||
|
||||
Convey("A user should be able to remove an admin if there are other admins", func() {
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[1], Permission: models.PERMISSION_ADMIN})
|
||||
err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, false, models.PERMISSION_ADMIN)
|
||||
So(err, ShouldBeNil)
|
||||
err = RemoveTeamMember(&models.RemoveTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[0], ProtectLastAdmin: true})
|
||||
err = RemoveTeamMember(&models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], ProtectLastAdmin: true})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("A user should not be able to remove the admin permission for the last admin", func() {
|
||||
err = UpdateTeamMember(&models.UpdateTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true})
|
||||
err = UpdateTeamMember(&models.UpdateTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true})
|
||||
So(err, ShouldBeError, models.ErrLastTeamAdmin)
|
||||
})
|
||||
|
||||
Convey("A user should be able to remove the admin permission if there are other admins", func() {
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[1], Permission: models.PERMISSION_ADMIN})
|
||||
err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, false, models.PERMISSION_ADMIN)
|
||||
So(err, ShouldBeNil)
|
||||
err = UpdateTeamMember(&models.UpdateTeamMemberCommand{OrgId: testOrgId, TeamId: group1.Result.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true})
|
||||
err = UpdateTeamMember(&models.UpdateTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], Permission: 0, ProtectLastAdmin: true})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Should be able to remove a group with users and permissions", func() {
|
||||
groupId := group2.Result.Id
|
||||
err := AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: groupId, UserId: userIds[1]})
|
||||
groupId := team2.Id
|
||||
err := sqlStore.AddTeamMember(userIds[1], testOrgID, groupId, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: groupId, UserId: userIds[2]})
|
||||
err = sqlStore.AddTeamMember(userIds[2], testOrgID, groupId, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
err = testHelperUpdateDashboardAcl(1, models.DashboardAcl{DashboardID: 1, OrgID: testOrgId, Permission: models.PERMISSION_EDIT, TeamID: groupId})
|
||||
err = testHelperUpdateDashboardAcl(t, sqlStore, 1, models.DashboardAcl{
|
||||
DashboardID: 1, OrgID: testOrgID, Permission: models.PERMISSION_EDIT, TeamID: groupId,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
err = DeleteTeam(&models.DeleteTeamCommand{OrgId: testOrgId, Id: groupId})
|
||||
err = DeleteTeam(&models.DeleteTeamCommand{OrgId: testOrgID, Id: groupId})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
query := &models.GetTeamByIdQuery{OrgId: testOrgId, Id: groupId}
|
||||
query := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: groupId}
|
||||
err = GetTeamById(query)
|
||||
So(err, ShouldEqual, models.ErrTeamNotFound)
|
||||
|
||||
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: testOrgId}
|
||||
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: testOrgID}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -274,18 +271,18 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should be able to return if user is admin of teams or not", func() {
|
||||
groupId := group2.Result.Id
|
||||
err := AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: groupId, UserId: userIds[0]})
|
||||
groupId := team2.Id
|
||||
err := sqlStore.AddTeamMember(userIds[0], testOrgID, groupId, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: groupId, UserId: userIds[1], Permission: models.PERMISSION_ADMIN})
|
||||
err = sqlStore.AddTeamMember(userIds[1], testOrgID, groupId, false, models.PERMISSION_ADMIN)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
query := &models.IsAdminOfTeamsQuery{SignedInUser: &models.SignedInUser{OrgId: testOrgId, UserId: userIds[0]}}
|
||||
query := &models.IsAdminOfTeamsQuery{SignedInUser: &models.SignedInUser{OrgId: testOrgID, UserId: userIds[0]}}
|
||||
err = IsAdminOfTeams(query)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result, ShouldBeFalse)
|
||||
|
||||
query = &models.IsAdminOfTeamsQuery{SignedInUser: &models.SignedInUser{OrgId: testOrgId, UserId: userIds[1]}}
|
||||
query = &models.IsAdminOfTeamsQuery{SignedInUser: &models.SignedInUser{OrgId: testOrgID, UserId: userIds[1]}}
|
||||
err = IsAdminOfTeams(query)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result, ShouldBeTrue)
|
||||
@@ -295,29 +292,29 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
signedInUser := &models.SignedInUser{Login: "loginuser0"}
|
||||
hiddenUsers := map[string]struct{}{"loginuser0": {}, "loginuser1": {}}
|
||||
|
||||
teamId := group1.Result.Id
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: teamId, UserId: userIds[0]})
|
||||
teamId := team1.Id
|
||||
err = sqlStore.AddTeamMember(userIds[0], testOrgID, teamId, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: teamId, UserId: userIds[1]})
|
||||
err = sqlStore.AddTeamMember(userIds[1], testOrgID, teamId, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
err = AddTeamMember(&models.AddTeamMemberCommand{OrgId: testOrgId, TeamId: teamId, UserId: userIds[2]})
|
||||
err = sqlStore.AddTeamMember(userIds[2], testOrgID, teamId, false, 0)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
searchQuery := &models.SearchTeamsQuery{OrgId: testOrgId, Page: 1, Limit: 10, SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
|
||||
searchQuery := &models.SearchTeamsQuery{OrgId: testOrgID, Page: 1, Limit: 10, SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
|
||||
err = SearchTeams(searchQuery)
|
||||
So(err, ShouldBeNil)
|
||||
So(searchQuery.Result.Teams, ShouldHaveLength, 2)
|
||||
team1 := searchQuery.Result.Teams[0]
|
||||
So(team1.MemberCount, ShouldEqual, 2)
|
||||
|
||||
searchQueryFilteredByUser := &models.SearchTeamsQuery{OrgId: testOrgId, Page: 1, Limit: 10, UserIdFilter: userIds[0], SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
|
||||
searchQueryFilteredByUser := &models.SearchTeamsQuery{OrgId: testOrgID, Page: 1, Limit: 10, UserIdFilter: userIds[0], SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
|
||||
err = SearchTeams(searchQueryFilteredByUser)
|
||||
So(err, ShouldBeNil)
|
||||
So(searchQueryFilteredByUser.Result.Teams, ShouldHaveLength, 1)
|
||||
team1 = searchQuery.Result.Teams[0]
|
||||
So(team1.MemberCount, ShouldEqual, 2)
|
||||
|
||||
getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgId, Id: teamId, SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
|
||||
getTeamQuery := &models.GetTeamByIdQuery{OrgId: testOrgID, Id: teamId, SignedInUser: signedInUser, HiddenUsers: hiddenUsers}
|
||||
err = GetTeamById(getTeamQuery)
|
||||
So(err, ShouldBeNil)
|
||||
So(getTeamQuery.Result.MemberCount, ShouldEqual, 2)
|
||||
|
||||
@@ -31,12 +31,10 @@ func (ss *SQLStore) addUserQueryAndCommandHandlers() {
|
||||
bus.AddHandler("sql", DisableUser)
|
||||
bus.AddHandler("sql", BatchDisableUsers)
|
||||
bus.AddHandler("sql", DeleteUser)
|
||||
bus.AddHandler("sql", UpdateUserPermissions)
|
||||
bus.AddHandler("sql", SetUserHelpFlag)
|
||||
bus.AddHandlerCtx("sql", CreateUser)
|
||||
}
|
||||
|
||||
func getOrgIdForNewUser(sess *DBSession, cmd *models.CreateUserCommand) (int64, error) {
|
||||
func getOrgIdForNewUser(sess *DBSession, cmd models.CreateUserCommand) (int64, error) {
|
||||
if cmd.SkipOrgSetup {
|
||||
return -1, nil
|
||||
}
|
||||
@@ -191,8 +189,9 @@ func (ss *SQLStore) createUser(ctx context.Context, args userCreationArgs, skipO
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func CreateUser(ctx context.Context, cmd *models.CreateUserCommand) error {
|
||||
return inTransactionCtx(ctx, func(sess *DBSession) error {
|
||||
func (ss *SQLStore) CreateUser(ctx context.Context, cmd models.CreateUserCommand) (*models.User, error) {
|
||||
var user *models.User
|
||||
err := ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
|
||||
orgId, err := getOrgIdForNewUser(sess, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -202,13 +201,16 @@ func CreateUser(ctx context.Context, cmd *models.CreateUserCommand) error {
|
||||
cmd.Email = cmd.Login
|
||||
}
|
||||
|
||||
exists, _ := sess.Where("email=? OR login=?", cmd.Email, cmd.Login).Get(&models.User{})
|
||||
exists, err := sess.Where("email=? OR login=?", cmd.Email, cmd.Login).Get(&models.User{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return models.ErrUserAlreadyExists
|
||||
}
|
||||
|
||||
// create user
|
||||
user := models.User{
|
||||
user = &models.User{
|
||||
Email: cmd.Email,
|
||||
Name: cmd.Name,
|
||||
Login: cmd.Login,
|
||||
@@ -243,7 +245,7 @@ func CreateUser(ctx context.Context, cmd *models.CreateUserCommand) error {
|
||||
|
||||
sess.UseBool("is_admin")
|
||||
|
||||
if _, err := sess.Insert(&user); err != nil {
|
||||
if _, err := sess.Insert(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -255,8 +257,6 @@ func CreateUser(ctx context.Context, cmd *models.CreateUserCommand) error {
|
||||
Email: user.Email,
|
||||
})
|
||||
|
||||
cmd.Result = user
|
||||
|
||||
// create org user link
|
||||
if !cmd.SkipOrgSetup {
|
||||
orgUser := models.OrgUser{
|
||||
@@ -282,6 +282,8 @@ func CreateUser(ctx context.Context, cmd *models.CreateUserCommand) error {
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return user, err
|
||||
}
|
||||
|
||||
func GetUserById(query *models.GetUserByIdQuery) error {
|
||||
@@ -729,14 +731,14 @@ func deleteUserInTransaction(sess *DBSession, cmd *models.DeleteUserCommand) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateUserPermissions(cmd *models.UpdateUserPermissionsCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
user := models.User{}
|
||||
if _, err := sess.ID(cmd.UserId).Get(&user); err != nil {
|
||||
func (ss *SQLStore) UpdateUserPermissions(userID int64, isAdmin bool) error {
|
||||
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
var user models.User
|
||||
if _, err := sess.ID(userID).Get(&user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user.IsAdmin = cmd.IsGrafanaAdmin
|
||||
user.IsAdmin = isAdmin
|
||||
sess.UseBool("is_admin")
|
||||
|
||||
_, err := sess.ID(user.Id).Update(&user)
|
||||
|
||||
@@ -15,18 +15,16 @@ import (
|
||||
|
||||
//nolint:goconst
|
||||
func TestUserAuth(t *testing.T) {
|
||||
InitTestDB(t)
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Given 5 users", t, func() {
|
||||
var err error
|
||||
var cmd *models.CreateUserCommand
|
||||
for i := 0; i < 5; i++ {
|
||||
cmd = &models.CreateUserCommand{
|
||||
cmd := models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
Login: fmt.Sprint("loginuser", i),
|
||||
}
|
||||
err = CreateUser(context.Background(), cmd)
|
||||
_, err := sqlStore.CreateUser(context.Background(), cmd)
|
||||
So(err, ShouldBeNil)
|
||||
}
|
||||
|
||||
@@ -46,7 +44,7 @@ func TestUserAuth(t *testing.T) {
|
||||
login := "loginuser0"
|
||||
|
||||
query := &models.GetUserByAuthInfoQuery{Login: login}
|
||||
err = GetUserByAuthInfo(query)
|
||||
err := GetUserByAuthInfo(query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result.Login, ShouldEqual, login)
|
||||
@@ -82,7 +80,7 @@ func TestUserAuth(t *testing.T) {
|
||||
Convey("Can set & locate by AuthModule and AuthId", func() {
|
||||
// get nonexistent user_auth entry
|
||||
query := &models.GetUserByAuthInfoQuery{AuthModule: "test", AuthId: "test"}
|
||||
err = GetUserByAuthInfo(query)
|
||||
err := GetUserByAuthInfo(query)
|
||||
|
||||
So(err, ShouldEqual, models.ErrUserNotFound)
|
||||
So(query.Result, ShouldBeNil)
|
||||
@@ -144,7 +142,7 @@ func TestUserAuth(t *testing.T) {
|
||||
|
||||
// Calling GetUserByAuthInfoQuery on an existing user will populate an entry in the user_auth table
|
||||
query := &models.GetUserByAuthInfoQuery{Login: login, AuthModule: "test", AuthId: "test"}
|
||||
err = GetUserByAuthInfo(query)
|
||||
err := GetUserByAuthInfo(query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result.Login, ShouldEqual, login)
|
||||
@@ -179,7 +177,7 @@ func TestUserAuth(t *testing.T) {
|
||||
// Make the first log-in during the past
|
||||
getTime = func() time.Time { return time.Now().AddDate(0, 0, -2) }
|
||||
query := &models.GetUserByAuthInfoQuery{Login: login, AuthModule: "test1", AuthId: "test1"}
|
||||
err = GetUserByAuthInfo(query)
|
||||
err := GetUserByAuthInfo(query)
|
||||
getTime = time.Now
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -20,17 +20,17 @@ func TestUserDataAccess(t *testing.T) {
|
||||
ss := InitTestDB(t)
|
||||
|
||||
Convey("Creates a user", func() {
|
||||
cmd := &models.CreateUserCommand{
|
||||
cmd := models.CreateUserCommand{
|
||||
Email: "usertest@test.com",
|
||||
Name: "user name",
|
||||
Login: "user_test_login",
|
||||
}
|
||||
|
||||
err := CreateUser(context.Background(), cmd)
|
||||
user, err := ss.CreateUser(context.Background(), cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Loading a user", func() {
|
||||
query := models.GetUserByIdQuery{Id: cmd.Result.Id}
|
||||
query := models.GetUserByIdQuery{Id: user.Id}
|
||||
err := GetUserById(&query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -43,18 +43,18 @@ func TestUserDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Creates disabled user", func() {
|
||||
cmd := &models.CreateUserCommand{
|
||||
cmd := models.CreateUserCommand{
|
||||
Email: "usertest@test.com",
|
||||
Name: "user name",
|
||||
Login: "user_test_login",
|
||||
IsDisabled: true,
|
||||
}
|
||||
|
||||
err := CreateUser(context.Background(), cmd)
|
||||
user, err := ss.CreateUser(context.Background(), cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Loading a user", func() {
|
||||
query := models.GetUserByIdQuery{Id: cmd.Result.Id}
|
||||
query := models.GetUserByIdQuery{Id: user.Id}
|
||||
err := GetUserById(&query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -78,18 +78,18 @@ func TestUserDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Creates user assigned to other organization", func() {
|
||||
cmd := &models.CreateUserCommand{
|
||||
cmd := models.CreateUserCommand{
|
||||
Email: "usertest@test.com",
|
||||
Name: "user name",
|
||||
Login: "user_test_login",
|
||||
OrgId: orgCmd.Result.Id,
|
||||
}
|
||||
|
||||
err := CreateUser(context.Background(), cmd)
|
||||
user, err := ss.CreateUser(context.Background(), cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Loading a user", func() {
|
||||
query := models.GetUserByIdQuery{Id: cmd.Result.Id}
|
||||
query := models.GetUserByIdQuery{Id: user.Id}
|
||||
err := GetUserById(&query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -104,20 +104,20 @@ func TestUserDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Don't create user assigned to unknown organization", func() {
|
||||
const nonExistingOrgID = 10000
|
||||
cmd := &models.CreateUserCommand{
|
||||
cmd := models.CreateUserCommand{
|
||||
Email: "usertest@test.com",
|
||||
Name: "user name",
|
||||
Login: "user_test_login",
|
||||
OrgId: nonExistingOrgID,
|
||||
}
|
||||
|
||||
err := CreateUser(context.Background(), cmd)
|
||||
_, err := ss.CreateUser(context.Background(), cmd)
|
||||
So(err, ShouldEqual, models.ErrOrgNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Given 5 users", func() {
|
||||
users := createFiveTestUsers(func(i int) *models.CreateUserCommand {
|
||||
users := createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
|
||||
return &models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
@@ -238,7 +238,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Can return list users based on their is_disabled flag", func() {
|
||||
ss = InitTestDB(t)
|
||||
createFiveTestUsers(func(i int) *models.CreateUserCommand {
|
||||
createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
|
||||
return &models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
@@ -269,7 +269,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
So(third, ShouldBeTrue)
|
||||
|
||||
ss = InitTestDB(t)
|
||||
users = createFiveTestUsers(func(i int) *models.CreateUserCommand {
|
||||
users = createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
|
||||
return &models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
@@ -286,7 +286,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = testHelperUpdateDashboardAcl(1, models.DashboardAcl{
|
||||
err = testHelperUpdateDashboardAcl(t, ss, 1, models.DashboardAcl{
|
||||
DashboardID: 1, OrgID: users[0].OrgId, UserID: users[1].Id,
|
||||
Permission: models.PERMISSION_EDIT,
|
||||
})
|
||||
@@ -365,7 +365,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Should enable all users", func() {
|
||||
ss = InitTestDB(t)
|
||||
createFiveTestUsers(func(i int) *models.CreateUserCommand {
|
||||
createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
|
||||
return &models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
@@ -392,7 +392,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Should disable only specific users", func() {
|
||||
ss = InitTestDB(t)
|
||||
users = createFiveTestUsers(func(i int) *models.CreateUserCommand {
|
||||
users = createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
|
||||
return &models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
@@ -438,7 +438,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
|
||||
// Since previous tests were destructive
|
||||
ss = InitTestDB(t)
|
||||
users = createFiveTestUsers(func(i int) *models.CreateUserCommand {
|
||||
users = createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
|
||||
return &models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
@@ -546,25 +546,22 @@ func TestUserDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Given one grafana admin user", func() {
|
||||
var err error
|
||||
createUserCmd := &models.CreateUserCommand{
|
||||
createUserCmd := models.CreateUserCommand{
|
||||
Email: fmt.Sprint("admin", "@test.com"),
|
||||
Name: "admin",
|
||||
Login: "admin",
|
||||
IsAdmin: true,
|
||||
}
|
||||
err = CreateUser(context.Background(), createUserCmd)
|
||||
user, err := ss.CreateUser(context.Background(), createUserCmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Cannot make themselves a non-admin", func() {
|
||||
updateUserPermsCmd := models.UpdateUserPermissionsCommand{IsGrafanaAdmin: false, UserId: 1}
|
||||
updatePermsError := UpdateUserPermissions(&updateUserPermsCmd)
|
||||
updatePermsError := ss.UpdateUserPermissions(1, false)
|
||||
|
||||
So(updatePermsError, ShouldEqual, models.ErrLastGrafanaAdmin)
|
||||
|
||||
query := models.GetUserByIdQuery{Id: createUserCmd.Result.Id}
|
||||
query := models.GetUserByIdQuery{Id: user.Id}
|
||||
getUserError := GetUserById(&query)
|
||||
|
||||
So(getUserError, ShouldBeNil)
|
||||
|
||||
So(query.Result.IsAdmin, ShouldEqual, true)
|
||||
@@ -574,33 +571,33 @@ func TestUserDataAccess(t *testing.T) {
|
||||
Convey("Given one user", func() {
|
||||
const email = "user@test.com"
|
||||
const username = "user"
|
||||
createUserCmd := &models.CreateUserCommand{
|
||||
createUserCmd := models.CreateUserCommand{
|
||||
Email: email,
|
||||
Name: "user",
|
||||
Login: username,
|
||||
}
|
||||
err := CreateUser(context.Background(), createUserCmd)
|
||||
_, err := ss.CreateUser(context.Background(), createUserCmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When trying to create a new user with the same email, an error is returned", func() {
|
||||
createUserCmd := &models.CreateUserCommand{
|
||||
createUserCmd := models.CreateUserCommand{
|
||||
Email: email,
|
||||
Name: "user2",
|
||||
Login: "user2",
|
||||
SkipOrgSetup: true,
|
||||
}
|
||||
err := CreateUser(context.Background(), createUserCmd)
|
||||
_, err := ss.CreateUser(context.Background(), createUserCmd)
|
||||
So(err, ShouldEqual, models.ErrUserAlreadyExists)
|
||||
})
|
||||
|
||||
Convey("When trying to create a new user with the same login, an error is returned", func() {
|
||||
createUserCmd := &models.CreateUserCommand{
|
||||
createUserCmd := models.CreateUserCommand{
|
||||
Email: "user2@test.com",
|
||||
Name: "user2",
|
||||
Login: username,
|
||||
SkipOrgSetup: true,
|
||||
}
|
||||
err := CreateUser(context.Background(), createUserCmd)
|
||||
_, err := ss.CreateUser(context.Background(), createUserCmd)
|
||||
So(err, ShouldEqual, models.ErrUserAlreadyExists)
|
||||
})
|
||||
})
|
||||
@@ -618,15 +615,15 @@ func GetOrgUsersForTest(query *models.GetOrgUsersQuery) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func createFiveTestUsers(fn func(i int) *models.CreateUserCommand) []models.User {
|
||||
var err error
|
||||
var cmd *models.CreateUserCommand
|
||||
func createFiveTestUsers(t *testing.T, sqlStore *SQLStore, fn func(i int) *models.CreateUserCommand) []models.User {
|
||||
t.Helper()
|
||||
|
||||
users := []models.User{}
|
||||
for i := 0; i < 5; i++ {
|
||||
cmd = fn(i)
|
||||
cmd := fn(i)
|
||||
|
||||
err = CreateUser(context.Background(), cmd)
|
||||
users = append(users, cmd.Result)
|
||||
user, err := sqlStore.CreateUser(context.Background(), *cmd)
|
||||
users = append(users, *user)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user