Commit fcc8557d by Torkel Ödegaard

dashboard acl work

parent 43ffe826
......@@ -24,37 +24,6 @@ func GetDashboardAclList(c *middleware.Context) Response {
}
list := query.Result
hasViewRoleAcl := false
hasEditRoleAcl := false
for _, item := range list {
if item.Role == m.ROLE_EDITOR {
hasEditRoleAcl = true
}
if item.Role == m.ROLE_VIEWER {
hasViewRoleAcl = true
}
}
if !hasEditRoleAcl {
tmpList := append([]*m.DashboardAclInfoDTO{}, &m.DashboardAclInfoDTO{
Id: 0,
Role: m.ROLE_EDITOR,
Permissions: m.PERMISSION_EDIT,
PermissionName: "Edit",
})
list = append(tmpList, list...)
}
if !hasViewRoleAcl {
tmpList := append([]*m.DashboardAclInfoDTO{}, &m.DashboardAclInfoDTO{
Id: 0,
Role: m.ROLE_VIEWER,
Permissions: m.PERMISSION_VIEW,
PermissionName: "View",
})
list = append(tmpList, list...)
}
return Json(200, list)
}
......
......@@ -13,16 +13,16 @@ import (
func TestDashboardAclApiEndpoint(t *testing.T) {
Convey("Given a dashboard acl", t, func() {
mockResult := []*models.DashboardAcl{
{Id: 1, OrgId: 1, DashboardId: 1, UserId: 2, Permissions: models.PERMISSION_EDIT},
{Id: 2, OrgId: 1, DashboardId: 1, UserId: 3, Permissions: models.PERMISSION_VIEW},
{Id: 3, OrgId: 1, DashboardId: 1, UserGroupId: 1, Permissions: models.PERMISSION_EDIT},
{Id: 4, OrgId: 1, DashboardId: 1, UserGroupId: 2, Permissions: models.PERMISSION_READ_ONLY_EDIT},
{Id: 1, OrgId: 1, DashboardId: 1, UserId: 2, Permission: models.PERMISSION_EDIT},
{Id: 2, OrgId: 1, DashboardId: 1, UserId: 3, Permission: models.PERMISSION_VIEW},
{Id: 3, OrgId: 1, DashboardId: 1, UserGroupId: 1, Permission: models.PERMISSION_EDIT},
{Id: 4, OrgId: 1, DashboardId: 1, UserGroupId: 2, Permission: models.PERMISSION_READ_ONLY_EDIT},
}
dtoRes := []*models.DashboardAclInfoDTO{
{Id: 1, OrgId: 1, DashboardId: 1, UserId: 2, Permissions: models.PERMISSION_EDIT},
{Id: 2, OrgId: 1, DashboardId: 1, UserId: 3, Permissions: models.PERMISSION_VIEW},
{Id: 3, OrgId: 1, DashboardId: 1, UserGroupId: 1, Permissions: models.PERMISSION_EDIT},
{Id: 4, OrgId: 1, DashboardId: 1, UserGroupId: 2, Permissions: models.PERMISSION_READ_ONLY_EDIT},
{Id: 1, OrgId: 1, DashboardId: 1, UserId: 2, Permission: models.PERMISSION_EDIT},
{Id: 2, OrgId: 1, DashboardId: 1, UserId: 3, Permission: models.PERMISSION_VIEW},
{Id: 3, OrgId: 1, DashboardId: 1, UserGroupId: 1, Permission: models.PERMISSION_EDIT},
{Id: 4, OrgId: 1, DashboardId: 1, UserGroupId: 2, Permission: models.PERMISSION_READ_ONLY_EDIT},
}
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
......@@ -59,7 +59,7 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
Convey("When user is editor and in the ACL", func() {
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/acl", "/api/dashboards/id/:dashboardId/acl", models.ROLE_EDITOR, func(sc *scenarioContext) {
mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permissions: models.PERMISSION_EDIT})
mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permission: models.PERMISSION_EDIT})
Convey("Should be able to access ACL", func() {
sc.handlerFunc = GetDashboardAclList
......@@ -70,7 +70,7 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/id/1/acl/1", "/api/dashboards/id/:dashboardId/acl/:aclId", models.ROLE_EDITOR, func(sc *scenarioContext) {
mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permissions: models.PERMISSION_EDIT})
mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permission: models.PERMISSION_EDIT})
bus.AddHandler("test3", func(cmd *models.RemoveDashboardAclCommand) error {
return nil
......@@ -114,7 +114,7 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/id/1/acl/user/1", "/api/dashboards/id/:dashboardsId/acl/user/:userId", models.ROLE_EDITOR, func(sc *scenarioContext) {
mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permissions: models.PERMISSION_VIEW})
mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permission: models.PERMISSION_VIEW})
bus.AddHandler("test3", func(cmd *models.RemoveDashboardAclCommand) error {
return nil
})
......
......@@ -174,7 +174,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
aclMockResp := []*models.DashboardAcl{
{
DashboardId: 1,
Permissions: models.PERMISSION_EDIT,
Permission: models.PERMISSION_EDIT,
UserId: 200,
},
}
......@@ -273,7 +273,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
role := models.ROLE_VIEWER
mockResult := []*models.DashboardAcl{
{Id: 1, OrgId: 1, DashboardId: 2, UserId: 1, Permissions: models.PERMISSION_EDIT},
{Id: 1, OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_EDIT},
}
bus.AddHandler("test", func(query *models.GetInheritedDashboardAclQuery) error {
......@@ -315,7 +315,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
role := models.ROLE_EDITOR
mockResult := []*models.DashboardAcl{
{Id: 1, OrgId: 1, DashboardId: 2, UserId: 1, Permissions: models.PERMISSION_VIEW},
{Id: 1, OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_VIEW},
}
bus.AddHandler("test", func(query *models.GetInheritedDashboardAclQuery) error {
......
......@@ -38,7 +38,7 @@ type DashboardAcl struct {
UserId int64
UserGroupId int64
Permissions PermissionType
Permission PermissionType
Created time.Time
Updated time.Time
......@@ -58,7 +58,7 @@ type DashboardAclInfoDTO struct {
UserGroupId int64 `json:"userGroupId"`
UserGroup string `json:"userGroup"`
Role RoleType `json:"role"`
Permissions PermissionType `json:"permissions"`
Permission PermissionType `json:"permission"`
PermissionName string `json:"permissionName"`
}
......@@ -71,7 +71,7 @@ type SetDashboardAclCommand struct {
OrgId int64 `json:"-"`
UserId int64 `json:"userId"`
UserGroupId int64 `json:"userGroupId"`
Permissions PermissionType `json:"permissions" binding:"Required"`
Permission PermissionType `json:"permission" binding:"Required"`
Result DashboardAcl `json:"-"`
}
......
......@@ -57,12 +57,12 @@ func (g *DashboardGuardian) HasPermission(permission m.PermissionType, fallbackR
}
for _, p := range acl {
if p.UserId == g.user.UserId && p.Permissions >= permission {
if p.UserId == g.user.UserId && p.Permission >= permission {
return true, nil
}
for _, ug := range userGroups {
if ug.Id == p.UserGroupId && p.Permissions >= permission {
if ug.Id == p.UserGroupId && p.Permission >= permission {
return true, nil
}
}
......
......@@ -27,11 +27,13 @@ func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
if res, err := sess.Query("SELECT 1 from "+dialect.Quote("dashboard_acl")+" WHERE dashboard_id =? and (user_group_id=? or user_id=?)", cmd.DashboardId, cmd.UserGroupId, cmd.UserId); err != nil {
return err
} else if len(res) == 1 {
entity := m.DashboardAcl{
Permissions: cmd.Permissions,
Permission: cmd.Permission,
Updated: time.Now(),
}
if _, err := sess.Cols("updated", "permissions").Where("dashboard_id =? and (user_group_id=? or user_id=?)", cmd.DashboardId, cmd.UserGroupId, cmd.UserId).Update(&entity); err != nil {
if _, err := sess.Cols("updated", "permission").Where("dashboard_id =? and (user_group_id=? or user_id=?)", cmd.DashboardId, cmd.UserGroupId, cmd.UserId).Update(&entity); err != nil {
return err
}
......@@ -45,10 +47,10 @@ func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
Created: time.Now(),
Updated: time.Now(),
DashboardId: cmd.DashboardId,
Permissions: cmd.Permissions,
Permission: cmd.Permission,
}
cols := []string{"org_id", "created", "updated", "dashboard_id", "permissions"}
cols := []string{"org_id", "created", "updated", "dashboard_id", "permission"}
if cmd.UserId != 0 {
cols = append(cols, "user_id")
......@@ -58,12 +60,12 @@ func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
cols = append(cols, "user_group_id")
}
entityId, err := sess.Cols(cols...).Insert(&entity)
_, err := sess.Cols(cols...).Insert(&entity)
if err != nil {
return err
}
cmd.Result = entity
cmd.Result.Id = entityId
// Update dashboard HasAcl flag
dashboard := m.Dashboard{
......@@ -97,7 +99,7 @@ func GetInheritedDashboardAcl(query *m.GetInheritedDashboardAclQuery) error {
da.dashboard_id,
da.user_id,
da.user_group_id,
da.permissions,
da.permission,
da.created,
da.updated
FROM dashboard_acl as da
......@@ -112,13 +114,15 @@ func GetInheritedDashboardAcl(query *m.GetInheritedDashboardAclQuery) error {
}
func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
rawSQL := `SELECT
rawSQL := `
SELECT
da.id,
da.org_id,
da.dashboard_id,
da.user_id,
da.user_group_id,
da.permissions,
da.permission,
da.role,
da.created,
da.updated,
u.login AS user_login,
......@@ -127,14 +131,34 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
FROM` + dialect.Quote("dashboard_acl") + ` as da
LEFT OUTER JOIN ` + dialect.Quote("user") + ` AS u ON u.id = da.user_id
LEFT OUTER JOIN user_group ug on ug.id = da.user_group_id
WHERE dashboard_id=?`
WHERE dashboard_id = ?
-- Also include default permission if has_acl = 0
UNION
SELECT
da.id,
da.org_id,
da.dashboard_id,
da.user_id,
da.user_group_id,
da.permission,
da.role,
da.created,
da.updated,
'' as user_login,
'' as user_email,
'' as user_group
FROM dashboard_acl as da, dashboard as dash
WHERE dash.id = ? AND dash.has_acl = 0 AND da.dashboard_id = -1
`
query.Result = make([]*m.DashboardAclInfoDTO, 0)
err := x.SQL(rawSQL, query.DashboardId).Find(&query.Result)
err := x.SQL(rawSQL, query.DashboardId, query.DashboardId).Find(&query.Result)
for _, p := range query.Result {
p.PermissionName = p.Permissions.String()
p.PermissionName = p.Permission.String()
}
return err
......
......@@ -20,7 +20,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
err := SetDashboardAcl(&m.SetDashboardAclCommand{
OrgId: 1,
DashboardId: savedFolder.Id,
Permissions: m.PERMISSION_EDIT,
Permission: m.PERMISSION_EDIT,
})
So(err, ShouldEqual, m.ErrDashboardAclInfoMissing)
})
......@@ -30,7 +30,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
OrgId: 1,
UserId: currentUser.Id,
DashboardId: savedFolder.Id,
Permissions: m.PERMISSION_EDIT,
Permission: m.PERMISSION_EDIT,
})
So(err, ShouldBeNil)
......@@ -49,7 +49,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
OrgId: 1,
UserId: currentUser.Id,
DashboardId: childDash.Id,
Permissions: m.PERMISSION_EDIT,
Permission: m.PERMISSION_EDIT,
})
So(err, ShouldBeNil)
......@@ -67,23 +67,29 @@ func TestDashboardAclDataAccess(t *testing.T) {
})
Convey("Should be able to add dashboard permission", func() {
err := SetDashboardAcl(&m.SetDashboardAclCommand{
setDashAclCmd := m.SetDashboardAclCommand{
OrgId: 1,
UserId: currentUser.Id,
DashboardId: savedFolder.Id,
Permissions: m.PERMISSION_EDIT,
})
Permission: m.PERMISSION_EDIT,
}
err := SetDashboardAcl(&setDashAclCmd)
So(err, ShouldBeNil)
So(setDashAclCmd.Result.Id, ShouldEqual, 3)
q1 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
err = GetDashboardAclInfoList(q1)
So(err, ShouldBeNil)
So(q1.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
So(q1.Result[0].Permissions, ShouldEqual, m.PERMISSION_EDIT)
So(q1.Result[0].Permission, ShouldEqual, m.PERMISSION_EDIT)
So(q1.Result[0].PermissionName, ShouldEqual, "Edit")
So(q1.Result[0].UserId, ShouldEqual, currentUser.Id)
So(q1.Result[0].UserLogin, ShouldEqual, currentUser.Login)
So(q1.Result[0].UserEmail, ShouldEqual, currentUser.Email)
So(q1.Result[0].Id, ShouldEqual, setDashAclCmd.Result.Id)
Convey("Should update hasAcl field to true for dashboard folder and its children", func() {
q2 := &m.GetDashboardsQuery{DashboardIds: []int64{savedFolder.Id, childDash.Id}}
......@@ -98,8 +104,9 @@ func TestDashboardAclDataAccess(t *testing.T) {
OrgId: 1,
UserId: 1,
DashboardId: savedFolder.Id,
Permissions: m.PERMISSION_READ_ONLY_EDIT,
Permission: m.PERMISSION_ADMIN,
})
So(err, ShouldBeNil)
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
......@@ -107,7 +114,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(q3.Result), ShouldEqual, 1)
So(q3.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
So(q3.Result[0].Permissions, ShouldEqual, m.PERMISSION_READ_ONLY_EDIT)
So(q3.Result[0].Permission, ShouldEqual, m.PERMISSION_ADMIN)
So(q3.Result[0].UserId, ShouldEqual, 1)
})
......@@ -115,8 +122,9 @@ func TestDashboardAclDataAccess(t *testing.T) {
Convey("Should be able to delete an existing permission", func() {
err := RemoveDashboardAcl(&m.RemoveDashboardAclCommand{
OrgId: 1,
AclId: 1,
AclId: setDashAclCmd.Result.Id,
})
So(err, ShouldBeNil)
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
......@@ -132,20 +140,35 @@ func TestDashboardAclDataAccess(t *testing.T) {
So(err, ShouldBeNil)
Convey("Should be able to add a user permission for a user group", func() {
err := SetDashboardAcl(&m.SetDashboardAclCommand{
setDashAclCmd := m.SetDashboardAclCommand{
OrgId: 1,
UserGroupId: group1.Result.Id,
DashboardId: savedFolder.Id,
Permissions: m.PERMISSION_EDIT,
})
Permission: m.PERMISSION_EDIT,
}
err := SetDashboardAcl(&setDashAclCmd)
So(err, ShouldBeNil)
q1 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
err = GetDashboardAclInfoList(q1)
So(err, ShouldBeNil)
So(q1.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
So(q1.Result[0].Permissions, ShouldEqual, m.PERMISSION_EDIT)
So(q1.Result[0].Permission, ShouldEqual, m.PERMISSION_EDIT)
So(q1.Result[0].UserGroupId, ShouldEqual, group1.Result.Id)
Convey("Should be able to delete an existing permission for a user group", func() {
err := RemoveDashboardAcl(&m.RemoveDashboardAclCommand{
OrgId: 1,
AclId: setDashAclCmd.Result.Id,
})
So(err, ShouldBeNil)
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
err = GetDashboardAclInfoList(q3)
So(err, ShouldBeNil)
So(len(q3.Result), ShouldEqual, 0)
})
})
Convey("Should be able to update an existing permission for a user group", func() {
......@@ -153,7 +176,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
OrgId: 1,
UserGroupId: group1.Result.Id,
DashboardId: savedFolder.Id,
Permissions: m.PERMISSION_READ_ONLY_EDIT,
Permission: m.PERMISSION_ADMIN,
})
So(err, ShouldBeNil)
......@@ -162,23 +185,10 @@ func TestDashboardAclDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(q3.Result), ShouldEqual, 1)
So(q3.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
So(q3.Result[0].Permissions, ShouldEqual, m.PERMISSION_READ_ONLY_EDIT)
So(q3.Result[0].Permission, ShouldEqual, m.PERMISSION_ADMIN)
So(q3.Result[0].UserGroupId, ShouldEqual, group1.Result.Id)
})
Convey("Should be able to delete an existing permission for a user group", func() {
err := RemoveDashboardAcl(&m.RemoveDashboardAclCommand{
OrgId: 1,
AclId: 1,
})
So(err, ShouldBeNil)
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
err = GetDashboardAclInfoList(q3)
So(err, ShouldBeNil)
So(len(q3.Result), ShouldEqual, 0)
})
})
})
})
......
......@@ -384,7 +384,7 @@ func updateTestDashboardWithAcl(dashId int64, userId int64, permissions m.Permis
OrgId: 1,
UserId: userId,
DashboardId: dashId,
Permissions: permissions,
Permission: permissions,
})
So(err, ShouldBeNil)
}
......@@ -11,12 +11,13 @@ func addDashboardAclMigrations(mg *Migrator) {
{Name: "dashboard_id", Type: DB_BigInt},
{Name: "user_id", Type: DB_BigInt, Nullable: true},
{Name: "user_group_id", Type: DB_BigInt, Nullable: true},
{Name: "permissions", Type: DB_SmallInt, Default: "4"},
{Name: "permission", Type: DB_SmallInt, Default: "4"},
{Name: "role", Type: DB_Varchar, Length: 20, Nullable: true},
{Name: "created", Type: DB_DateTime, Nullable: false},
{Name: "updated", Type: DB_DateTime, Nullable: false},
},
Indices: []*Index{
{Cols: []string{"org_id"}},
{Cols: []string{"dashboard_id"}},
{Cols: []string{"dashboard_id", "user_id"}, Type: UniqueIndex},
{Cols: []string{"dashboard_id", "user_group_id"}, Type: UniqueIndex},
},
......@@ -25,7 +26,26 @@ func addDashboardAclMigrations(mg *Migrator) {
mg.AddMigration("create dashboard acl table", NewAddTableMigration(dashboardAclV1))
//------- indexes ------------------
mg.AddMigration("add unique index dashboard_acl_org_id", NewAddIndexMigration(dashboardAclV1, dashboardAclV1.Indices[0]))
mg.AddMigration("add unique index dashboard_acl_dashboard_id", NewAddIndexMigration(dashboardAclV1, dashboardAclV1.Indices[0]))
mg.AddMigration("add unique index dashboard_acl_dashboard_id_user_id", NewAddIndexMigration(dashboardAclV1, dashboardAclV1.Indices[1]))
mg.AddMigration("add unique index dashboard_acl_dashboard_id_group_id", NewAddIndexMigration(dashboardAclV1, dashboardAclV1.Indices[2]))
const rawSQL = `
INSERT INTO dashboard_acl
(
org_id,
dashboard_id,
role,
created,
updated
)
VALUES
(-1,-1,'Viewer','2017-06-20','2017-06-20'),
(-1,-1,'Editor','2017-06-20','2017-06-20')
`
mg.AddMigration("save default acl rules in dashboard_acl table", new(RawSqlMigration).
Sqlite(rawSQL).
Postgres(rawSQL).
Mysql(rawSQL))
}
......@@ -174,10 +174,10 @@ func TestAccountDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 3)
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: ac1.OrgId, UserId: ac3.Id, Permissions: m.PERMISSION_EDIT})
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: ac1.OrgId, UserId: ac3.Id, Permission: m.PERMISSION_EDIT})
So(err, ShouldBeNil)
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 2, OrgId: ac3.OrgId, UserId: ac3.Id, Permissions: m.PERMISSION_EDIT})
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 2, OrgId: ac3.OrgId, UserId: ac3.Id, Permission: m.PERMISSION_EDIT})
So(err, ShouldBeNil)
Convey("When org user is deleted", func() {
......
......@@ -94,7 +94,7 @@ func TestUserGroupCommandsAndQueries(t *testing.T) {
So(err, ShouldBeNil)
err = AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: groupId, UserId: userIds[2]})
So(err, ShouldBeNil)
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: 1, Permissions: m.PERMISSION_EDIT, UserGroupId: groupId})
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: 1, Permission: m.PERMISSION_EDIT, UserGroupId: groupId})
err = DeleteUserGroup(&m.DeleteUserGroupCommand{Id: groupId})
So(err, ShouldBeNil)
......
......@@ -99,7 +99,7 @@ func TestUserDataAccess(t *testing.T) {
err = AddOrgUser(&m.AddOrgUserCommand{LoginOrEmail: users[0].Login, Role: m.ROLE_VIEWER, OrgId: users[0].OrgId})
So(err, ShouldBeNil)
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: users[0].OrgId, UserId: users[0].Id, Permissions: m.PERMISSION_EDIT})
err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: users[0].OrgId, UserId: users[0].Id, Permission: m.PERMISSION_EDIT})
So(err, ShouldBeNil)
err = SavePreferences(&m.SavePreferencesCommand{UserId: users[0].Id, OrgId: users[0].OrgId, HomeDashboardId: 1, Theme: "dark"})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment