dashboard_permission_test.go 6.99 KB
Newer Older
1 2 3 4 5
package api

import (
	"testing"

6
	"github.com/grafana/grafana/pkg/api/dtos"
7 8
	"github.com/grafana/grafana/pkg/bus"
	"github.com/grafana/grafana/pkg/components/simplejson"
Torkel Ödegaard committed
9
	m "github.com/grafana/grafana/pkg/models"
10
	"github.com/grafana/grafana/pkg/services/guardian"
11 12 13 14

	. "github.com/smartystreets/goconvey/convey"
)

15
func TestDashboardPermissionApiEndpoint(t *testing.T) {
16 17 18 19 20
	Convey("Dashboard permissions test", t, func() {
		Convey("Given dashboard not exists", func() {
			bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
				return m.ErrDashboardNotFound
			})
21

22 23 24 25
			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", m.ROLE_EDITOR, func(sc *scenarioContext) {
				callGetDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 404)
			})
26

27 28 29 30 31
			cmd := dtos.UpdateDashboardAclCommand{
				Items: []dtos.DashboardAclUpdateItem{
					{UserId: 1000, Permission: m.PERMISSION_ADMIN},
				},
			}
32

33 34 35 36
			updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
				callUpdateDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 404)
			})
37 38
		})

39 40 41
		Convey("Given user has no admin permissions", func() {
			origNewGuardian := guardian.New
			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanAdminValue: false})
42

43 44 45 46 47
			getDashboardQueryResult := m.NewDashboard("Dash")
			bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
				query.Result = getDashboardQueryResult
				return nil
			})
48

49 50 51
			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", m.ROLE_EDITOR, func(sc *scenarioContext) {
				callGetDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 403)
52
			})
53

54 55 56 57 58
			cmd := dtos.UpdateDashboardAclCommand{
				Items: []dtos.DashboardAclUpdateItem{
					{UserId: 1000, Permission: m.PERMISSION_ADMIN},
				},
			}
59

60 61 62
			updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
				callUpdateDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 403)
63 64
			})

65 66
			Reset(func() {
				guardian.New = origNewGuardian
67
			})
68 69
		})

70 71 72 73 74 75 76 77 78 79 80 81 82
		Convey("Given user has admin permissions and permissions to update", func() {
			origNewGuardian := guardian.New
			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
				CanAdminValue:                    true,
				CheckPermissionBeforeUpdateValue: true,
				GetAclValue: []*m.DashboardAclInfoDTO{
					{OrgId: 1, DashboardId: 1, UserId: 2, Permission: m.PERMISSION_VIEW},
					{OrgId: 1, DashboardId: 1, UserId: 3, Permission: m.PERMISSION_EDIT},
					{OrgId: 1, DashboardId: 1, UserId: 4, Permission: m.PERMISSION_ADMIN},
					{OrgId: 1, DashboardId: 1, TeamId: 1, Permission: m.PERMISSION_VIEW},
					{OrgId: 1, DashboardId: 1, TeamId: 2, Permission: m.PERMISSION_ADMIN},
				},
			})
83

84 85 86 87
			getDashboardQueryResult := m.NewDashboard("Dash")
			bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
				query.Result = getDashboardQueryResult
				return nil
88 89
			})

90 91 92 93 94 95 96 97 98
			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", m.ROLE_ADMIN, func(sc *scenarioContext) {
				callGetDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 200)
				respJSON, err := simplejson.NewJson(sc.resp.Body.Bytes())
				So(err, ShouldBeNil)
				So(len(respJSON.MustArray()), ShouldEqual, 5)
				So(respJSON.GetIndex(0).Get("userId").MustInt(), ShouldEqual, 2)
				So(respJSON.GetIndex(0).Get("permission").MustInt(), ShouldEqual, m.PERMISSION_VIEW)
			})
99

100 101 102 103 104
			cmd := dtos.UpdateDashboardAclCommand{
				Items: []dtos.DashboardAclUpdateItem{
					{UserId: 1000, Permission: m.PERMISSION_ADMIN},
				},
			}
105

106 107 108
			updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
				callUpdateDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 200)
109 110
			})

111 112 113 114
			Reset(func() {
				guardian.New = origNewGuardian
			})
		})
115

116 117 118 119 120
		Convey("When trying to update permissions with duplicate permissions", func() {
			origNewGuardian := guardian.New
			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
				CanAdminValue:                    true,
				CheckPermissionBeforeUpdateValue: false,
121
				CheckPermissionBeforeUpdateError: guardian.ErrGuardianPermissionExists,
122 123
			})

124 125 126 127 128
			getDashboardQueryResult := m.NewDashboard("Dash")
			bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
				query.Result = getDashboardQueryResult
				return nil
			})
129

130 131 132 133 134
			cmd := dtos.UpdateDashboardAclCommand{
				Items: []dtos.DashboardAclUpdateItem{
					{UserId: 1000, Permission: m.PERMISSION_ADMIN},
				},
			}
135

136 137 138 139
			updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
				callUpdateDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 400)
			})
140

141 142
			Reset(func() {
				guardian.New = origNewGuardian
143 144 145
			})
		})

146
		Convey("When trying to override inherited permissions with lower precedence", func() {
147 148 149 150
			origNewGuardian := guardian.New
			guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
				CanAdminValue:                    true,
				CheckPermissionBeforeUpdateValue: false,
151
				CheckPermissionBeforeUpdateError: guardian.ErrGuardianOverride},
152 153 154 155 156 157 158 159 160 161 162 163 164
			)

			getDashboardQueryResult := m.NewDashboard("Dash")
			bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
				query.Result = getDashboardQueryResult
				return nil
			})

			cmd := dtos.UpdateDashboardAclCommand{
				Items: []dtos.DashboardAclUpdateItem{
					{UserId: 1000, Permission: m.PERMISSION_ADMIN},
				},
			}
165

166 167 168 169
			updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
				callUpdateDashboardPermissions(sc)
				So(sc.resp.Code, ShouldEqual, 400)
			})
170

171 172
			Reset(func() {
				guardian.New = origNewGuardian
173 174 175 176
			})
		})
	})
}
177

178 179 180
func callGetDashboardPermissions(sc *scenarioContext) {
	sc.handlerFunc = GetDashboardPermissionList
	sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
181
}
182

183
func callUpdateDashboardPermissions(sc *scenarioContext) {
184 185 186 187 188 189 190
	bus.AddHandler("test", func(cmd *m.UpdateDashboardAclCommand) error {
		return nil
	})

	sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
}

191
func updateDashboardPermissionScenario(desc string, url string, routePattern string, cmd dtos.UpdateDashboardAclCommand, fn scenarioFunc) {
192 193 194
	Convey(desc+" "+url, func() {
		defer bus.ClearBusHandlers()

195
		sc := setupScenarioContext(url)
196

197
		sc.defaultHandler = Wrap(func(c *m.ReqContext) Response {
198 199
			sc.context = c
			sc.context.OrgId = TestOrgID
200
			sc.context.UserId = TestUserID
201

202
			return UpdateDashboardPermissions(c, cmd)
203 204 205 206 207 208 209
		})

		sc.m.Post(routePattern, sc.defaultHandler)

		fn(sc)
	})
}