Commit 545b0213 by Torkel Ödegaard

Merge branch 'dashboard_folders' of github.com:grafana/grafana into dashboard_folders

parents 9c6c8c0f 1d43bfbf
...@@ -16,7 +16,7 @@ func GetDashboardAclList(c *middleware.Context) Response { ...@@ -16,7 +16,7 @@ func GetDashboardAclList(c *middleware.Context) Response {
guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser) guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser)
if canView, err := guardian.CanView(); err != nil || !canView { if canAdmin, err := guardian.CanAdmin(); err != nil || !canAdmin {
return dashboardGuardianResponse(err) return dashboardGuardianResponse(err)
} }
...@@ -32,7 +32,7 @@ func UpdateDashboardAcl(c *middleware.Context, apiCmd dtos.UpdateDashboardAclCom ...@@ -32,7 +32,7 @@ func UpdateDashboardAcl(c *middleware.Context, apiCmd dtos.UpdateDashboardAclCom
dashId := c.ParamsInt64(":dashboardId") dashId := c.ParamsInt64(":dashboardId")
guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser) guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser)
if canSave, err := guardian.CanSave(); err != nil || !canSave { if canAdmin, err := guardian.CanAdmin(); err != nil || !canAdmin {
return dashboardGuardianResponse(err) return dashboardGuardianResponse(err)
} }
...@@ -68,7 +68,7 @@ func DeleteDashboardAcl(c *middleware.Context) Response { ...@@ -68,7 +68,7 @@ func DeleteDashboardAcl(c *middleware.Context) Response {
aclId := c.ParamsInt64(":aclId") aclId := c.ParamsInt64(":aclId")
guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser) guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser)
if canSave, err := guardian.CanSave(); err != nil || !canSave { if canAdmin, err := guardian.CanAdmin(); err != nil || !canAdmin {
return dashboardGuardianResponse(err) return dashboardGuardianResponse(err)
} }
......
...@@ -13,17 +13,13 @@ import ( ...@@ -13,17 +13,13 @@ import (
func TestDashboardAclApiEndpoint(t *testing.T) { func TestDashboardAclApiEndpoint(t *testing.T) {
Convey("Given a dashboard acl", t, func() { Convey("Given a dashboard acl", t, func() {
mockResult := []*models.DashboardAcl{ mockResult := []*models.DashboardAcl{
{Id: 1, OrgId: 1, DashboardId: 1, UserId: 2, Permission: models.PERMISSION_EDIT}, {Id: 1, OrgId: 1, DashboardId: 1, UserId: 2, Permission: models.PERMISSION_VIEW},
{Id: 2, OrgId: 1, DashboardId: 1, UserId: 3, Permission: models.PERMISSION_VIEW}, {Id: 2, OrgId: 1, DashboardId: 1, UserId: 3, Permission: models.PERMISSION_EDIT},
{Id: 3, OrgId: 1, DashboardId: 1, UserGroupId: 1, Permission: models.PERMISSION_EDIT}, {Id: 3, OrgId: 1, DashboardId: 1, UserId: 4, Permission: models.PERMISSION_ADMIN},
{Id: 4, OrgId: 1, DashboardId: 1, UserGroupId: 2, Permission: models.PERMISSION_READ_ONLY_EDIT}, {Id: 4, OrgId: 1, DashboardId: 1, UserGroupId: 1, Permission: models.PERMISSION_VIEW},
} {Id: 5, OrgId: 1, DashboardId: 1, UserGroupId: 2, Permission: models.PERMISSION_ADMIN},
dtoRes := []*models.DashboardAclInfoDTO{
{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 := transformDashboardAclsToDTOs(mockResult)
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error { bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
query.Result = dtoRes query.Result = dtoRes
...@@ -51,15 +47,16 @@ func TestDashboardAclApiEndpoint(t *testing.T) { ...@@ -51,15 +47,16 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
respJSON, err := simplejson.NewJson(sc.resp.Body.Bytes()) respJSON, err := simplejson.NewJson(sc.resp.Body.Bytes())
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(len(respJSON.MustArray()), ShouldEqual, 5)
So(respJSON.GetIndex(0).Get("userId").MustInt(), ShouldEqual, 2) So(respJSON.GetIndex(0).Get("userId").MustInt(), ShouldEqual, 2)
So(respJSON.GetIndex(0).Get("permissions").MustInt(), ShouldEqual, models.PERMISSION_EDIT) So(respJSON.GetIndex(0).Get("permission").MustInt(), ShouldEqual, models.PERMISSION_VIEW)
}) })
}) })
}) })
Convey("When user is editor and in the ACL", func() { Convey("When user is editor and has admin permission 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) { 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, Permission: models.PERMISSION_EDIT}) mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permission: models.PERMISSION_ADMIN})
Convey("Should be able to access ACL", func() { Convey("Should be able to access ACL", func() {
sc.handlerFunc = GetDashboardAclList sc.handlerFunc = GetDashboardAclList
...@@ -70,7 +67,7 @@ func TestDashboardAclApiEndpoint(t *testing.T) { ...@@ -70,7 +67,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) { 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, Permission: models.PERMISSION_EDIT}) mockResult = append(mockResult, &models.DashboardAcl{Id: 1, OrgId: 1, DashboardId: 1, UserId: 1, Permission: models.PERMISSION_ADMIN})
bus.AddHandler("test3", func(cmd *models.RemoveDashboardAclCommand) error { bus.AddHandler("test3", func(cmd *models.RemoveDashboardAclCommand) error {
return nil return nil
...@@ -84,9 +81,9 @@ func TestDashboardAclApiEndpoint(t *testing.T) { ...@@ -84,9 +81,9 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
}) })
}) })
Convey("When user is a member of a user group in the ACL with edit permission", func() { Convey("When user is a member of a user group in the ACL with admin permission", func() {
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/id/1/acl/1", "/api/dashboards/id/:dashboardsId/acl/:aclId", models.ROLE_EDITOR, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/id/1/acl/1", "/api/dashboards/id/:dashboardsId/acl/:aclId", models.ROLE_EDITOR, func(sc *scenarioContext) {
userGroupResp = append(userGroupResp, &models.UserGroup{Id: 1, OrgId: 1, Name: "UG1"}) userGroupResp = append(userGroupResp, &models.UserGroup{Id: 2, OrgId: 1, Name: "UG2"})
bus.AddHandler("test3", func(cmd *models.RemoveDashboardAclCommand) error { bus.AddHandler("test3", func(cmd *models.RemoveDashboardAclCommand) error {
return nil return nil
...@@ -102,6 +99,34 @@ func TestDashboardAclApiEndpoint(t *testing.T) { ...@@ -102,6 +99,34 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
}) })
}) })
Convey("When user is editor and has edit permission 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, Permission: models.PERMISSION_EDIT})
Convey("Should not be able to access ACL", func() {
sc.handlerFunc = GetDashboardAclList
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
So(sc.resp.Code, ShouldEqual, 403)
})
})
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, Permission: models.PERMISSION_EDIT})
bus.AddHandler("test3", func(cmd *models.RemoveDashboardAclCommand) error {
return nil
})
Convey("Should be not be able to delete permission", func() {
sc.handlerFunc = DeleteDashboardAcl
sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec()
So(sc.resp.Code, ShouldEqual, 403)
})
})
})
Convey("When user is editor and not in the ACL", func() { Convey("When user is editor and not in the ACL", func() {
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/acl", "/api/dashboards/id/:dashboardsId/acl", models.ROLE_EDITOR, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/acl", "/api/dashboards/id/:dashboardsId/acl", models.ROLE_EDITOR, func(sc *scenarioContext) {
...@@ -129,3 +154,21 @@ func TestDashboardAclApiEndpoint(t *testing.T) { ...@@ -129,3 +154,21 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
}) })
}) })
} }
func transformDashboardAclsToDTOs(acls []*models.DashboardAcl) []*models.DashboardAclInfoDTO {
dtos := make([]*models.DashboardAclInfoDTO, 0)
for _, acl := range acls {
dto := &models.DashboardAclInfoDTO{
Id: acl.Id,
OrgId: acl.OrgId,
DashboardId: acl.DashboardId,
Permission: acl.Permission,
UserId: acl.UserId,
UserGroupId: acl.UserGroupId,
}
dtos = append(dtos, dto)
}
return dtos
}
...@@ -36,6 +36,10 @@ func (g *DashboardGuardian) CanView() (bool, error) { ...@@ -36,6 +36,10 @@ func (g *DashboardGuardian) CanView() (bool, error) {
return g.HasPermission(m.PERMISSION_VIEW) return g.HasPermission(m.PERMISSION_VIEW)
} }
func (g *DashboardGuardian) CanAdmin() (bool, error) {
return g.HasPermission(m.PERMISSION_ADMIN)
}
func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, error) { func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, error) {
if g.user.OrgRole == m.ROLE_ADMIN { if g.user.OrgRole == m.ROLE_ADMIN {
return true, nil return true, nil
......
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