dashboard_permission_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package api
  2. import (
  3. "testing"
  4. "github.com/grafana/grafana/pkg/api/dtos"
  5. "github.com/grafana/grafana/pkg/bus"
  6. "github.com/grafana/grafana/pkg/components/simplejson"
  7. "github.com/grafana/grafana/pkg/middleware"
  8. m "github.com/grafana/grafana/pkg/models"
  9. "github.com/grafana/grafana/pkg/services/guardian"
  10. . "github.com/smartystreets/goconvey/convey"
  11. )
  12. func TestDashboardPermissionApiEndpoint(t *testing.T) {
  13. Convey("Dashboard permissions test", t, func() {
  14. Convey("Given dashboard not exists", func() {
  15. bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
  16. return m.ErrDashboardNotFound
  17. })
  18. loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", m.ROLE_EDITOR, func(sc *scenarioContext) {
  19. callGetDashboardPermissions(sc)
  20. So(sc.resp.Code, ShouldEqual, 404)
  21. })
  22. cmd := dtos.UpdateDashboardAclCommand{
  23. Items: []dtos.DashboardAclUpdateItem{
  24. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  25. },
  26. }
  27. updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
  28. callUpdateDashboardPermissions(sc)
  29. So(sc.resp.Code, ShouldEqual, 404)
  30. })
  31. })
  32. Convey("Given user has no admin permissions", func() {
  33. origNewGuardian := guardian.New
  34. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanAdminValue: false})
  35. getDashboardQueryResult := m.NewDashboard("Dash")
  36. bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
  37. query.Result = getDashboardQueryResult
  38. return nil
  39. })
  40. loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", m.ROLE_EDITOR, func(sc *scenarioContext) {
  41. callGetDashboardPermissions(sc)
  42. So(sc.resp.Code, ShouldEqual, 403)
  43. })
  44. cmd := dtos.UpdateDashboardAclCommand{
  45. Items: []dtos.DashboardAclUpdateItem{
  46. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  47. },
  48. }
  49. updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
  50. callUpdateDashboardPermissions(sc)
  51. So(sc.resp.Code, ShouldEqual, 403)
  52. })
  53. Reset(func() {
  54. guardian.New = origNewGuardian
  55. })
  56. })
  57. Convey("Given user has admin permissions and permissions to update", func() {
  58. origNewGuardian := guardian.New
  59. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
  60. CanAdminValue: true,
  61. CheckPermissionBeforeUpdateValue: true,
  62. GetAclValue: []*m.DashboardAclInfoDTO{
  63. {OrgId: 1, DashboardId: 1, UserId: 2, Permission: m.PERMISSION_VIEW},
  64. {OrgId: 1, DashboardId: 1, UserId: 3, Permission: m.PERMISSION_EDIT},
  65. {OrgId: 1, DashboardId: 1, UserId: 4, Permission: m.PERMISSION_ADMIN},
  66. {OrgId: 1, DashboardId: 1, TeamId: 1, Permission: m.PERMISSION_VIEW},
  67. {OrgId: 1, DashboardId: 1, TeamId: 2, Permission: m.PERMISSION_ADMIN},
  68. },
  69. })
  70. getDashboardQueryResult := m.NewDashboard("Dash")
  71. bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
  72. query.Result = getDashboardQueryResult
  73. return nil
  74. })
  75. loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", m.ROLE_ADMIN, func(sc *scenarioContext) {
  76. callGetDashboardPermissions(sc)
  77. So(sc.resp.Code, ShouldEqual, 200)
  78. respJSON, err := simplejson.NewJson(sc.resp.Body.Bytes())
  79. So(err, ShouldBeNil)
  80. So(len(respJSON.MustArray()), ShouldEqual, 5)
  81. So(respJSON.GetIndex(0).Get("userId").MustInt(), ShouldEqual, 2)
  82. So(respJSON.GetIndex(0).Get("permission").MustInt(), ShouldEqual, m.PERMISSION_VIEW)
  83. })
  84. cmd := dtos.UpdateDashboardAclCommand{
  85. Items: []dtos.DashboardAclUpdateItem{
  86. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  87. },
  88. }
  89. updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
  90. callUpdateDashboardPermissions(sc)
  91. So(sc.resp.Code, ShouldEqual, 200)
  92. })
  93. Reset(func() {
  94. guardian.New = origNewGuardian
  95. })
  96. })
  97. Convey("When trying to update permissions with duplicate permissions", func() {
  98. origNewGuardian := guardian.New
  99. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
  100. CanAdminValue: true,
  101. CheckPermissionBeforeUpdateValue: false,
  102. CheckPermissionBeforeUpdateError: guardian.ErrGuardianPermissionExists,
  103. })
  104. getDashboardQueryResult := m.NewDashboard("Dash")
  105. bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
  106. query.Result = getDashboardQueryResult
  107. return nil
  108. })
  109. cmd := dtos.UpdateDashboardAclCommand{
  110. Items: []dtos.DashboardAclUpdateItem{
  111. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  112. },
  113. }
  114. updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
  115. callUpdateDashboardPermissions(sc)
  116. So(sc.resp.Code, ShouldEqual, 400)
  117. })
  118. Reset(func() {
  119. guardian.New = origNewGuardian
  120. })
  121. })
  122. Convey("When trying to override inherited permissions with lower presedence", func() {
  123. origNewGuardian := guardian.New
  124. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
  125. CanAdminValue: true,
  126. CheckPermissionBeforeUpdateValue: false,
  127. CheckPermissionBeforeUpdateError: guardian.ErrGuardianOverride},
  128. )
  129. getDashboardQueryResult := m.NewDashboard("Dash")
  130. bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
  131. query.Result = getDashboardQueryResult
  132. return nil
  133. })
  134. cmd := dtos.UpdateDashboardAclCommand{
  135. Items: []dtos.DashboardAclUpdateItem{
  136. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  137. },
  138. }
  139. updateDashboardPermissionScenario("When calling POST on", "/api/dashboards/id/1/permissions", "/api/dashboards/id/:id/permissions", cmd, func(sc *scenarioContext) {
  140. callUpdateDashboardPermissions(sc)
  141. So(sc.resp.Code, ShouldEqual, 400)
  142. })
  143. Reset(func() {
  144. guardian.New = origNewGuardian
  145. })
  146. })
  147. })
  148. }
  149. func callGetDashboardPermissions(sc *scenarioContext) {
  150. sc.handlerFunc = GetDashboardPermissionList
  151. sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
  152. }
  153. func callUpdateDashboardPermissions(sc *scenarioContext) {
  154. bus.AddHandler("test", func(cmd *m.UpdateDashboardAclCommand) error {
  155. return nil
  156. })
  157. sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
  158. }
  159. func updateDashboardPermissionScenario(desc string, url string, routePattern string, cmd dtos.UpdateDashboardAclCommand, fn scenarioFunc) {
  160. Convey(desc+" "+url, func() {
  161. defer bus.ClearBusHandlers()
  162. sc := setupScenarioContext(url)
  163. sc.defaultHandler = wrap(func(c *middleware.Context) Response {
  164. sc.context = c
  165. sc.context.OrgId = TestOrgID
  166. sc.context.UserId = TestUserID
  167. return UpdateDashboardPermissions(c, cmd)
  168. })
  169. sc.m.Post(routePattern, sc.defaultHandler)
  170. fn(sc)
  171. })
  172. }