folder_permission_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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. m "github.com/grafana/grafana/pkg/models"
  8. "github.com/grafana/grafana/pkg/services/dashboards"
  9. "github.com/grafana/grafana/pkg/services/guardian"
  10. . "github.com/smartystreets/goconvey/convey"
  11. )
  12. func TestFolderPermissionApiEndpoint(t *testing.T) {
  13. Convey("Folder permissions test", t, func() {
  14. Convey("Given folder not exists", func() {
  15. mock := &fakeFolderService{
  16. GetFolderByUIDError: m.ErrFolderNotFound,
  17. }
  18. origNewFolderService := dashboards.NewFolderService
  19. mockFolderService(mock)
  20. loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", m.ROLE_EDITOR, func(sc *scenarioContext) {
  21. callGetFolderPermissions(sc)
  22. So(sc.resp.Code, ShouldEqual, 404)
  23. })
  24. cmd := dtos.UpdateDashboardAclCommand{
  25. Items: []dtos.DashboardAclUpdateItem{
  26. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  27. },
  28. }
  29. updateFolderPermissionScenario("When calling POST on", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", cmd, func(sc *scenarioContext) {
  30. callUpdateFolderPermissions(sc)
  31. So(sc.resp.Code, ShouldEqual, 404)
  32. })
  33. Reset(func() {
  34. dashboards.NewFolderService = origNewFolderService
  35. })
  36. })
  37. Convey("Given user has no admin permissions", func() {
  38. origNewGuardian := guardian.New
  39. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanAdminValue: false})
  40. mock := &fakeFolderService{
  41. GetFolderByUIDResult: &m.Folder{
  42. Id: 1,
  43. Uid: "uid",
  44. Title: "Folder",
  45. },
  46. }
  47. origNewFolderService := dashboards.NewFolderService
  48. mockFolderService(mock)
  49. loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", m.ROLE_EDITOR, func(sc *scenarioContext) {
  50. callGetFolderPermissions(sc)
  51. So(sc.resp.Code, ShouldEqual, 403)
  52. })
  53. cmd := dtos.UpdateDashboardAclCommand{
  54. Items: []dtos.DashboardAclUpdateItem{
  55. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  56. },
  57. }
  58. updateFolderPermissionScenario("When calling POST on", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", cmd, func(sc *scenarioContext) {
  59. callUpdateFolderPermissions(sc)
  60. So(sc.resp.Code, ShouldEqual, 403)
  61. })
  62. Reset(func() {
  63. guardian.New = origNewGuardian
  64. dashboards.NewFolderService = origNewFolderService
  65. })
  66. })
  67. Convey("Given user has admin permissions and permissions to update", func() {
  68. origNewGuardian := guardian.New
  69. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
  70. CanAdminValue: true,
  71. CheckPermissionBeforeUpdateValue: true,
  72. GetAclValue: []*m.DashboardAclInfoDTO{
  73. {OrgId: 1, DashboardId: 1, UserId: 2, Permission: m.PERMISSION_VIEW},
  74. {OrgId: 1, DashboardId: 1, UserId: 3, Permission: m.PERMISSION_EDIT},
  75. {OrgId: 1, DashboardId: 1, UserId: 4, Permission: m.PERMISSION_ADMIN},
  76. {OrgId: 1, DashboardId: 1, TeamId: 1, Permission: m.PERMISSION_VIEW},
  77. {OrgId: 1, DashboardId: 1, TeamId: 2, Permission: m.PERMISSION_ADMIN},
  78. },
  79. })
  80. mock := &fakeFolderService{
  81. GetFolderByUIDResult: &m.Folder{
  82. Id: 1,
  83. Uid: "uid",
  84. Title: "Folder",
  85. },
  86. }
  87. origNewFolderService := dashboards.NewFolderService
  88. mockFolderService(mock)
  89. loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", m.ROLE_ADMIN, func(sc *scenarioContext) {
  90. callGetFolderPermissions(sc)
  91. So(sc.resp.Code, ShouldEqual, 200)
  92. respJSON, err := simplejson.NewJson(sc.resp.Body.Bytes())
  93. So(err, ShouldBeNil)
  94. So(len(respJSON.MustArray()), ShouldEqual, 5)
  95. So(respJSON.GetIndex(0).Get("userId").MustInt(), ShouldEqual, 2)
  96. So(respJSON.GetIndex(0).Get("permission").MustInt(), ShouldEqual, m.PERMISSION_VIEW)
  97. })
  98. cmd := dtos.UpdateDashboardAclCommand{
  99. Items: []dtos.DashboardAclUpdateItem{
  100. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  101. },
  102. }
  103. updateFolderPermissionScenario("When calling POST on", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", cmd, func(sc *scenarioContext) {
  104. callUpdateFolderPermissions(sc)
  105. So(sc.resp.Code, ShouldEqual, 200)
  106. })
  107. Reset(func() {
  108. guardian.New = origNewGuardian
  109. dashboards.NewFolderService = origNewFolderService
  110. })
  111. })
  112. Convey("When trying to update permissions with duplicate permissions", func() {
  113. origNewGuardian := guardian.New
  114. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
  115. CanAdminValue: true,
  116. CheckPermissionBeforeUpdateValue: false,
  117. CheckPermissionBeforeUpdateError: guardian.ErrGuardianPermissionExists,
  118. })
  119. mock := &fakeFolderService{
  120. GetFolderByUIDResult: &m.Folder{
  121. Id: 1,
  122. Uid: "uid",
  123. Title: "Folder",
  124. },
  125. }
  126. origNewFolderService := dashboards.NewFolderService
  127. mockFolderService(mock)
  128. cmd := dtos.UpdateDashboardAclCommand{
  129. Items: []dtos.DashboardAclUpdateItem{
  130. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  131. },
  132. }
  133. updateFolderPermissionScenario("When calling POST on", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", cmd, func(sc *scenarioContext) {
  134. callUpdateFolderPermissions(sc)
  135. So(sc.resp.Code, ShouldEqual, 400)
  136. })
  137. Reset(func() {
  138. guardian.New = origNewGuardian
  139. dashboards.NewFolderService = origNewFolderService
  140. })
  141. })
  142. Convey("When trying to override inherited permissions with lower presedence", func() {
  143. origNewGuardian := guardian.New
  144. guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
  145. CanAdminValue: true,
  146. CheckPermissionBeforeUpdateValue: false,
  147. CheckPermissionBeforeUpdateError: guardian.ErrGuardianOverride},
  148. )
  149. mock := &fakeFolderService{
  150. GetFolderByUIDResult: &m.Folder{
  151. Id: 1,
  152. Uid: "uid",
  153. Title: "Folder",
  154. },
  155. }
  156. origNewFolderService := dashboards.NewFolderService
  157. mockFolderService(mock)
  158. cmd := dtos.UpdateDashboardAclCommand{
  159. Items: []dtos.DashboardAclUpdateItem{
  160. {UserId: 1000, Permission: m.PERMISSION_ADMIN},
  161. },
  162. }
  163. updateFolderPermissionScenario("When calling POST on", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", cmd, func(sc *scenarioContext) {
  164. callUpdateFolderPermissions(sc)
  165. So(sc.resp.Code, ShouldEqual, 400)
  166. })
  167. Reset(func() {
  168. guardian.New = origNewGuardian
  169. dashboards.NewFolderService = origNewFolderService
  170. })
  171. })
  172. })
  173. }
  174. func callGetFolderPermissions(sc *scenarioContext) {
  175. sc.handlerFunc = GetFolderPermissionList
  176. sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
  177. }
  178. func callUpdateFolderPermissions(sc *scenarioContext) {
  179. bus.AddHandler("test", func(cmd *m.UpdateDashboardAclCommand) error {
  180. return nil
  181. })
  182. sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
  183. }
  184. func updateFolderPermissionScenario(desc string, url string, routePattern string, cmd dtos.UpdateDashboardAclCommand, fn scenarioFunc) {
  185. Convey(desc+" "+url, func() {
  186. defer bus.ClearBusHandlers()
  187. sc := setupScenarioContext(url)
  188. sc.defaultHandler = wrap(func(c *m.ReqContext) Response {
  189. sc.context = c
  190. sc.context.OrgId = TestOrgID
  191. sc.context.UserId = TestUserID
  192. return UpdateFolderPermissions(c, cmd)
  193. })
  194. sc.m.Post(routePattern, sc.defaultHandler)
  195. fn(sc)
  196. })
  197. }