From 2257c1f874f8df94fea3f28708c2c4c94305cf8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 21 Jun 2017 19:02:03 -0400 Subject: [PATCH] dashboard acl work --- pkg/api/api.go | 2 +- pkg/api/dashboard_acl.go | 29 +++++++++++++------ pkg/api/dtos/acl.go | 16 +++++++++++ pkg/metrics/metrics.go | 4 +-- pkg/models/dashboard_acl.go | 20 ++++++++----- pkg/services/sqlstore/dashboard_acl.go | 33 ++++++++++++++++++++++ public/app/features/dashboard/acl/acl.html | 2 +- public/app/features/dashboard/acl/acl.ts | 19 +++++++------ 8 files changed, 97 insertions(+), 28 deletions(-) create mode 100644 pkg/api/dtos/acl.go diff --git a/pkg/api/api.go b/pkg/api/api.go index e4edc76f96d..c74f00aade5 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -250,7 +250,7 @@ func (hs *HttpServer) registerRoutes() { r.Group("/acl", func() { r.Get("/", wrap(GetDashboardAclList)) - r.Post("/", bind(m.SetDashboardAclCommand{}), wrap(PostDashboardAcl)) + r.Post("/", bind(dtos.UpdateDashboardAclCommand{}), wrap(UpdateDashboardAcl)) r.Delete("/:aclId", wrap(DeleteDashboardAcl)) }) }, reqSignedIn) diff --git a/pkg/api/dashboard_acl.go b/pkg/api/dashboard_acl.go index 0137c0bd8f1..b0e1dde1683 100644 --- a/pkg/api/dashboard_acl.go +++ b/pkg/api/dashboard_acl.go @@ -1,12 +1,14 @@ package api import ( + "time" + + "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/metrics" "github.com/grafana/grafana/pkg/middleware" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/guardian" - "github.com/grafana/grafana/pkg/util" ) func GetDashboardAclList(c *middleware.Context) Response { @@ -27,7 +29,7 @@ func GetDashboardAclList(c *middleware.Context) Response { return Json(200, list) } -func PostDashboardAcl(c *middleware.Context, cmd m.SetDashboardAclCommand) Response { +func UpdateDashboardAcl(c *middleware.Context, apiCmd dtos.UpdateDashboardAclCommand) Response { dashId := c.ParamsInt64(":dashboardId") guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser) @@ -35,9 +37,22 @@ func PostDashboardAcl(c *middleware.Context, cmd m.SetDashboardAclCommand) Respo return dashboardGuardianResponse(err) } - cmd.OrgId = c.OrgId + cmd := m.UpdateDashboardAclCommand{} cmd.DashboardId = dashId + for _, item := range apiCmd.Items { + cmd.Items = append(cmd.Items, &m.DashboardAcl{ + OrgId: c.OrgId, + DashboardId: dashId, + UserId: item.UserId, + UserGroupId: item.UserGroupId, + Role: item.Role, + Permission: item.Permission, + Created: time.Now(), + Updated: time.Now(), + }) + } + if err := bus.Dispatch(&cmd); err != nil { if err == m.ErrDashboardAclInfoMissing || err == m.ErrDashboardPermissionDashboardEmpty { return ApiError(409, err.Error(), err) @@ -45,12 +60,8 @@ func PostDashboardAcl(c *middleware.Context, cmd m.SetDashboardAclCommand) Respo return ApiError(500, "Failed to create permission", err) } - metrics.M_Api_Dashboard_Acl_Create.Inc(1) - - return Json(200, &util.DynMap{ - "permissionId": cmd.Result.Id, - "message": "Permission created", - }) + metrics.M_Api_Dashboard_Acl_Update.Inc(1) + return ApiSuccess("Dashboard acl updated") } func DeleteDashboardAcl(c *middleware.Context) Response { diff --git a/pkg/api/dtos/acl.go b/pkg/api/dtos/acl.go new file mode 100644 index 00000000000..df9b05cbd10 --- /dev/null +++ b/pkg/api/dtos/acl.go @@ -0,0 +1,16 @@ +package dtos + +import ( + m "github.com/grafana/grafana/pkg/models" +) + +type UpdateDashboardAclCommand struct { + Items []DashboardAclUpdateItem `json:"items"` +} + +type DashboardAclUpdateItem struct { + UserId int64 `json:"userId"` + UserGroupId int64 `json:"userGroupId"` + Role m.RoleType `json:"role"` + Permission m.PermissionType `json:"permission"` +} diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index f01a254eb2c..53c846588ab 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -36,7 +36,7 @@ var ( M_Api_Dashboard_Snapshot_External Counter M_Api_Dashboard_Snapshot_Get Counter M_Api_UserGroup_Create Counter - M_Api_Dashboard_Acl_Create Counter + M_Api_Dashboard_Acl_Update Counter M_Models_Dashboard_Insert Counter M_Alerting_Result_State_Alerting Counter M_Alerting_Result_State_Ok Counter @@ -95,7 +95,7 @@ func initMetricVars(settings *MetricSettings) { M_Api_User_SignUpInvite = RegCounter("api.user.signup_invite") M_Api_UserGroup_Create = RegCounter("api.usergroup.create") - M_Api_Dashboard_Acl_Create = RegCounter("api.dashboard.acl.create") + M_Api_Dashboard_Acl_Update = RegCounter("api.dashboard.acl.update") M_Api_Dashboard_Save = RegTimer("api.dashboard.save") M_Api_Dashboard_Get = RegTimer("api.dashboard.get") diff --git a/pkg/models/dashboard_acl.go b/pkg/models/dashboard_acl.go index ca2635d91ee..ff9db8ae612 100644 --- a/pkg/models/dashboard_acl.go +++ b/pkg/models/dashboard_acl.go @@ -36,6 +36,7 @@ type DashboardAcl struct { UserId int64 UserGroupId int64 + Role RoleType Permission PermissionType Created time.Time @@ -64,14 +65,19 @@ type DashboardAclInfoDTO struct { // COMMANDS // -type SetDashboardAclCommand struct { - DashboardId int64 `json:"-"` - OrgId int64 `json:"-"` - UserId int64 `json:"userId"` - UserGroupId int64 `json:"userGroupId"` - Permission PermissionType `json:"permission" binding:"Required"` +type UpdateDashboardAclCommand struct { + DashboardId int64 + Items []*DashboardAcl +} - Result DashboardAcl `json:"-"` +type SetDashboardAclCommand struct { + DashboardId int64 + OrgId int64 + UserId int64 + UserGroupId int64 + Permission PermissionType + + Result DashboardAcl } type RemoveDashboardAclCommand struct { diff --git a/pkg/services/sqlstore/dashboard_acl.go b/pkg/services/sqlstore/dashboard_acl.go index 202179b9099..511f8c9beba 100644 --- a/pkg/services/sqlstore/dashboard_acl.go +++ b/pkg/services/sqlstore/dashboard_acl.go @@ -9,11 +9,44 @@ import ( func init() { bus.AddHandler("sql", SetDashboardAcl) + bus.AddHandler("sql", UpdateDashboardAcl) bus.AddHandler("sql", RemoveDashboardAcl) bus.AddHandler("sql", GetDashboardAclInfoList) bus.AddHandler("sql", GetInheritedDashboardAcl) } +func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error { + return inTransaction(func(sess *DBSession) error { + // delete existing items + _, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", cmd.DashboardId) + if err != nil { + return err + } + + for _, item := range cmd.Items { + if item.UserId == 0 && item.UserGroupId == 0 && !item.Role.IsValid() { + return m.ErrDashboardAclInfoMissing + } + + if item.DashboardId == 0 { + return m.ErrDashboardPermissionDashboardEmpty + } + + sess.Nullable("user_id", "user_group_id") + if _, err := sess.Insert(item); err != nil { + return err + } + } + + // Update dashboard HasAcl flag + dashboard := m.Dashboard{HasAcl: true} + if _, err := sess.Cols("has_acl").Where("id=? OR parent_id=?", cmd.DashboardId, cmd.DashboardId).Update(&dashboard); err != nil { + return err + } + return nil + }) +} + func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error { return inTransaction(func(sess *DBSession) error { if cmd.UserId == 0 && cmd.UserGroupId == 0 { diff --git a/public/app/features/dashboard/acl/acl.html b/public/app/features/dashboard/acl/acl.html index 78c8b6d52e2..646ccee9a19 100644 --- a/public/app/features/dashboard/acl/acl.html +++ b/public/app/features/dashboard/acl/acl.html @@ -12,7 +12,7 @@