mirror of https://github.com/grafana/grafana
RBAC: remove simple RBAC disabled checks (#71137)
* remove simple RBAC disabled checks * fixing tests * remove old AC testspull/71223/head^2
parent
8f2f6d63eb
commit
a65cb4d808
@ -1,580 +0,0 @@ |
||||
package db |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"math/rand" |
||||
"strconv" |
||||
"testing" |
||||
"time" |
||||
|
||||
"github.com/stretchr/testify/assert" |
||||
"github.com/stretchr/testify/require" |
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson" |
||||
"github.com/grafana/grafana/pkg/services/dashboards" |
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion" |
||||
"github.com/grafana/grafana/pkg/services/featuremgmt" |
||||
"github.com/grafana/grafana/pkg/services/org" |
||||
"github.com/grafana/grafana/pkg/services/sqlstore" |
||||
"github.com/grafana/grafana/pkg/services/user" |
||||
"github.com/grafana/grafana/pkg/util" |
||||
) |
||||
|
||||
func TestIntegrationSQLBuilder(t *testing.T) { |
||||
if testing.Short() { |
||||
t.Skip("skipping integration test") |
||||
} |
||||
|
||||
t.Run("WriteDashboardPermissionFilter", func(t *testing.T) { |
||||
t.Run("user ACL", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_EDIT}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
}) |
||||
|
||||
t.Run("user ACL with nested folders", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_EDIT}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{User: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
}) |
||||
|
||||
t.Run("role ACL", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleViewer, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleViewer, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleEditor, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleEditor, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
}) |
||||
|
||||
t.Run("role ACL with nested folders", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleViewer, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleViewer, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleEditor, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Role: org.RoleEditor, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
}) |
||||
|
||||
t.Run("team ACL", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_EDIT}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_EDIT}, |
||||
Search{UserFromACL: false, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
}) |
||||
|
||||
t.Run("team ACL with nested folders", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_VIEW}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_EDIT}, |
||||
Search{UserFromACL: true, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{}, |
||||
&DashboardPermission{Team: true, Permission: dashboards.PERMISSION_EDIT}, |
||||
Search{UserFromACL: false, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
}) |
||||
|
||||
t.Run("defaults for user ACL", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{OrgId: -1}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{OrgId: -1}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleEditor, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{OrgId: -1}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(), |
||||
) |
||||
}) |
||||
|
||||
t.Run("defaults for user ACL with nested folders", func(t *testing.T) { |
||||
test(t, |
||||
DashboardProps{}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{OrgId: -1}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_VIEW}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{OrgId: -1}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleEditor, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
|
||||
test(t, |
||||
DashboardProps{OrgId: -1}, |
||||
nil, |
||||
Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: dashboards.PERMISSION_EDIT}, |
||||
shouldNotFind, |
||||
featuremgmt.WithFeatures(featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders)), |
||||
) |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
const shouldFind = true |
||||
const shouldNotFind = false |
||||
|
||||
type DashboardProps struct { |
||||
OrgId int64 |
||||
} |
||||
|
||||
type DashboardPermission struct { |
||||
User bool |
||||
Team bool |
||||
Role org.RoleType |
||||
Permission dashboards.PermissionType |
||||
} |
||||
|
||||
type Search struct { |
||||
UsersOrgRole org.RoleType |
||||
UserFromACL bool |
||||
RequiredPermission dashboards.PermissionType |
||||
OrgId int64 |
||||
} |
||||
|
||||
type dashboardResponse struct { |
||||
Id int64 |
||||
} |
||||
|
||||
func test(t *testing.T, dashboardProps DashboardProps, dashboardPermission *DashboardPermission, search Search, shouldFind bool, features featuremgmt.FeatureToggles) { |
||||
t.Helper() |
||||
|
||||
t.Run("", func(t *testing.T) { |
||||
// Will also cleanup the db
|
||||
sqlStore := InitTestDB(t) |
||||
|
||||
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 := getDashboards(t, sqlStore, search, aclUserID, features) |
||||
|
||||
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") |
||||
} |
||||
}) |
||||
} |
||||
|
||||
func createDummyUser(t *testing.T, sqlStore DB) *user.User { |
||||
t.Helper() |
||||
|
||||
uid := strconv.Itoa(rand.Intn(9999999)) |
||||
usr := &user.User{ |
||||
Email: uid + "@example.com", |
||||
Login: uid, |
||||
Name: uid, |
||||
Company: "", |
||||
Password: uid, |
||||
EmailVerified: true, |
||||
IsAdmin: false, |
||||
Created: time.Now(), |
||||
Updated: time.Now(), |
||||
} |
||||
|
||||
var id int64 |
||||
err := sqlStore.WithDbSession(context.Background(), func(sess *Session) error { |
||||
sess.UseBool("is_admin") |
||||
var err error |
||||
_, err = sess.Insert(usr) |
||||
id = usr.ID |
||||
return err |
||||
}) |
||||
require.NoError(t, err) |
||||
usr.ID = id |
||||
return usr |
||||
} |
||||
|
||||
func createDummyDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, dashboardProps DashboardProps) *dashboards.Dashboard { |
||||
t.Helper() |
||||
|
||||
json, err := simplejson.NewJson([]byte(`{"schemaVersion":17,"title":"gdev dashboards","uid":"","version":1}`)) |
||||
require.NoError(t, err) |
||||
|
||||
saveDashboardCmd := dashboards.SaveDashboardCommand{ |
||||
Dashboard: json, |
||||
UserID: 0, |
||||
Overwrite: false, |
||||
Message: "", |
||||
RestoredFrom: 0, |
||||
PluginID: "", |
||||
FolderID: 0, |
||||
IsFolder: false, |
||||
UpdatedAt: time.Time{}, |
||||
} |
||||
if dashboardProps.OrgId != 0 { |
||||
saveDashboardCmd.OrgID = dashboardProps.OrgId |
||||
} else { |
||||
saveDashboardCmd.OrgID = 1 |
||||
} |
||||
|
||||
dash := insertTestDashboard(t, sqlStore, "", saveDashboardCmd.OrgID, 0, false, nil) |
||||
require.NoError(t, err) |
||||
|
||||
t.Logf("Created dashboard with ID %d and org ID %d\n", dash.ID, dash.OrgID) |
||||
return dash |
||||
} |
||||
|
||||
func createDummyACL(t *testing.T, sqlStore *sqlstore.SQLStore, dashboardPermission *DashboardPermission, search Search, dashboardID int64) int64 { |
||||
t.Helper() |
||||
|
||||
acl := &dashboards.DashboardACL{ |
||||
OrgID: 1, |
||||
Created: time.Now(), |
||||
Updated: time.Now(), |
||||
Permission: dashboardPermission.Permission, |
||||
DashboardID: dashboardID, |
||||
} |
||||
|
||||
var user *user.User |
||||
if dashboardPermission.User { |
||||
t.Logf("Creating user") |
||||
user = createDummyUser(t, sqlStore) |
||||
|
||||
acl.UserID = user.ID |
||||
} |
||||
|
||||
if dashboardPermission.Team { |
||||
// TODO: Restore/refactor sqlBuilder tests after user, org and team services are split
|
||||
t.Skip("Creating team: skip, team service is moved") |
||||
} |
||||
|
||||
if len(string(dashboardPermission.Role)) > 0 { |
||||
acl.Role = &dashboardPermission.Role |
||||
} |
||||
|
||||
err := updateDashboardACL(t, sqlStore, dashboardID, acl) |
||||
require.NoError(t, err) |
||||
if user != nil { |
||||
return user.ID |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
func getDashboards(t *testing.T, sqlStore *sqlstore.SQLStore, search Search, aclUserID int64, features featuremgmt.FeatureToggles) []*dashboardResponse { |
||||
t.Helper() |
||||
|
||||
old := sqlStore.Cfg.RBACEnabled |
||||
sqlStore.Cfg.RBACEnabled = false |
||||
defer func() { |
||||
sqlStore.Cfg.RBACEnabled = old |
||||
}() |
||||
|
||||
recursiveQueriesAreSupported, err := sqlStore.RecursiveQueriesAreSupported() |
||||
require.NoError(t, err) |
||||
|
||||
builder := NewSqlBuilder(sqlStore.Cfg, features, sqlStore.GetDialect(), recursiveQueriesAreSupported) |
||||
signedInUser := &user.SignedInUser{ |
||||
UserID: 9999999999, |
||||
} |
||||
|
||||
if search.OrgId == 0 { |
||||
signedInUser.OrgID = 1 |
||||
} else { |
||||
signedInUser.OrgID = search.OrgId |
||||
} |
||||
|
||||
if len(string(search.UsersOrgRole)) > 0 { |
||||
signedInUser.OrgRole = search.UsersOrgRole |
||||
} else { |
||||
signedInUser.OrgRole = org.RoleViewer |
||||
} |
||||
if search.UserFromACL { |
||||
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.GetEngine().SQL(builder.GetSQLString(), builder.params...).Find(&res) |
||||
require.NoError(t, err) |
||||
return res |
||||
} |
||||
|
||||
// TODO: Use FakeDashboardStore when org has its own service
|
||||
func insertTestDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, title string, orgId int64, |
||||
folderId int64, isFolder bool, tags ...interface{}) *dashboards.Dashboard { |
||||
t.Helper() |
||||
cmd := dashboards.SaveDashboardCommand{ |
||||
OrgID: orgId, |
||||
FolderID: folderId, |
||||
IsFolder: isFolder, |
||||
Dashboard: simplejson.NewFromAny(map[string]interface{}{ |
||||
"id": nil, |
||||
"title": title, |
||||
"tags": tags, |
||||
}), |
||||
} |
||||
|
||||
var dash *dashboards.Dashboard |
||||
err := sqlStore.WithDbSession(context.Background(), func(sess *Session) error { |
||||
dash = cmd.GetDashboardModel() |
||||
dash.SetVersion(1) |
||||
dash.Created = time.Now() |
||||
dash.Updated = time.Now() |
||||
dash.UID = util.GenerateShortUID() |
||||
_, err := sess.Insert(dash) |
||||
return err |
||||
}) |
||||
|
||||
require.NoError(t, err) |
||||
require.NotNil(t, dash) |
||||
dash.Data.Set("id", dash.ID) |
||||
dash.Data.Set("uid", dash.UID) |
||||
|
||||
err = sqlStore.WithDbSession(context.Background(), func(sess *Session) error { |
||||
dashVersion := &dashver.DashboardVersion{ |
||||
DashboardID: dash.ID, |
||||
ParentVersion: dash.Version, |
||||
RestoredFrom: cmd.RestoredFrom, |
||||
Version: dash.Version, |
||||
Created: time.Now(), |
||||
CreatedBy: dash.UpdatedBy, |
||||
Message: cmd.Message, |
||||
Data: dash.Data, |
||||
} |
||||
require.NoError(t, err) |
||||
|
||||
if affectedRows, err := sess.Insert(dashVersion); err != nil { |
||||
return err |
||||
} else if affectedRows == 0 { |
||||
return dashboards.ErrDashboardNotFound |
||||
} |
||||
|
||||
return nil |
||||
}) |
||||
require.NoError(t, err) |
||||
|
||||
return dash |
||||
} |
||||
|
||||
// TODO: Use FakeDashboardStore when org has its own service
|
||||
func updateDashboardACL(t *testing.T, sqlStore *sqlstore.SQLStore, dashboardID int64, items ...*dashboards.DashboardACL) error { |
||||
t.Helper() |
||||
|
||||
err := sqlStore.WithDbSession(context.Background(), func(sess *Session) error { |
||||
_, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", dashboardID) |
||||
if err != nil { |
||||
return fmt.Errorf("deleting from dashboard_acl failed: %w", err) |
||||
} |
||||
|
||||
for _, item := range items { |
||||
item.Created = time.Now() |
||||
item.Updated = time.Now() |
||||
if item.UserID == 0 && item.TeamID == 0 && (item.Role == nil || !item.Role.IsValid()) { |
||||
return dashboards.ErrDashboardACLInfoMissing |
||||
} |
||||
|
||||
if item.DashboardID == 0 { |
||||
return dashboards.ErrDashboardPermissionDashboardEmpty |
||||
} |
||||
|
||||
sess.Nullable("user_id", "team_id") |
||||
if _, err := sess.Insert(item); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
|
||||
// Update dashboard HasACL flag
|
||||
dashboard := dashboards.Dashboard{HasACL: true} |
||||
_, err = sess.Cols("has_acl").Where("id=?", dashboardID).Update(&dashboard) |
||||
return err |
||||
}) |
||||
return err |
||||
} |
||||
Loading…
Reference in new issue