AuthorizationMiddlewearTests.coffee 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. sinon = require('sinon')
  2. chai = require('chai')
  3. should = chai.should()
  4. expect = chai.expect
  5. modulePath = "../../../../app/js/Features/Authorization/AuthorizationMiddlewear.js"
  6. SandboxedModule = require('sandboxed-module')
  7. Errors = require "../../../../app/js/Features/Errors/Errors.js"
  8. describe "AuthorizationMiddlewear", ->
  9. beforeEach ->
  10. @user_id = "user-id-123"
  11. @project_id = "project-id-123"
  12. @token = 'some-token'
  13. @AuthenticationController =
  14. getLoggedInUserId: sinon.stub().returns(@user_id)
  15. isUserLoggedIn: sinon.stub().returns(true)
  16. @AuthorizationMiddlewear = SandboxedModule.require modulePath, requires:
  17. "./AuthorizationManager": @AuthorizationManager = {}
  18. "logger-sharelatex": {log: () ->}
  19. "mongojs": ObjectId: @ObjectId = {}
  20. "../Errors/Errors": Errors
  21. '../Authentication/AuthenticationController': @AuthenticationController
  22. "../TokenAccess/TokenAccessHandler": @TokenAccessHandler =
  23. getRequestToken: sinon.stub().returns(@token)
  24. @req = {}
  25. @res = {}
  26. @ObjectId.isValid = sinon.stub()
  27. @ObjectId.isValid.withArgs(@project_id).returns true
  28. @next = sinon.stub()
  29. METHODS_TO_TEST = {
  30. "ensureUserCanReadProject": "canUserReadProject"
  31. "ensureUserCanWriteProjectSettings": "canUserWriteProjectSettings"
  32. "ensureUserCanWriteProjectContent": "canUserWriteProjectContent"
  33. "ensureUserCanAdminProject": "canUserAdminProject"
  34. }
  35. for middlewearMethod, managerMethod of METHODS_TO_TEST
  36. do (middlewearMethod, managerMethod) ->
  37. describe middlewearMethod, ->
  38. beforeEach ->
  39. @req.params =
  40. project_id: @project_id
  41. @AuthorizationManager[managerMethod] = sinon.stub()
  42. @AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
  43. describe "with missing project_id", ->
  44. beforeEach ->
  45. @req.params = {}
  46. it "should return an error to next", ->
  47. @AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
  48. @next.calledWith(new Error()).should.equal true
  49. describe "with logged in user", ->
  50. beforeEach ->
  51. @AuthenticationController.getLoggedInUserId.returns(@user_id)
  52. describe "when user has permission", ->
  53. beforeEach ->
  54. @AuthorizationManager[managerMethod]
  55. .withArgs(@user_id, @project_id, @token)
  56. .yields(null, true)
  57. it "should return next", ->
  58. @AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
  59. @next.called.should.equal true
  60. describe "when user doesn't have permission", ->
  61. beforeEach ->
  62. @AuthorizationManager[managerMethod]
  63. .withArgs(@user_id, @project_id, @token)
  64. .yields(null, false)
  65. it "should redirect to redirectToRestricted", ->
  66. @AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
  67. @next.called.should.equal false
  68. @AuthorizationMiddlewear.redirectToRestricted
  69. .calledWith(@req, @res, @next)
  70. .should.equal true
  71. describe "with anonymous user", ->
  72. describe "when user has permission", ->
  73. beforeEach ->
  74. @AuthenticationController.getLoggedInUserId.returns(null)
  75. @AuthorizationManager[managerMethod]
  76. .withArgs(null, @project_id, @token)
  77. .yields(null, true)
  78. it "should return next", ->
  79. @AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
  80. @next.called.should.equal true
  81. describe "when user doesn't have permission", ->
  82. beforeEach ->
  83. @AuthenticationController.getLoggedInUserId.returns(null)
  84. @AuthorizationManager[managerMethod]
  85. .withArgs(null, @project_id, @token)
  86. .yields(null, false)
  87. it "should redirect to redirectToRestricted", ->
  88. @AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
  89. @next.called.should.equal false
  90. @AuthorizationMiddlewear.redirectToRestricted
  91. .calledWith(@req, @res, @next)
  92. .should.equal true
  93. describe "with malformed project id", ->
  94. beforeEach ->
  95. @req.params =
  96. project_id: "blah"
  97. @ObjectId.isValid = sinon.stub().returns false
  98. it "should return a not found error", (done) ->
  99. @AuthorizationMiddlewear[middlewearMethod] @req, @res, (error) ->
  100. error.should.be.instanceof Errors.NotFoundError
  101. done()
  102. describe "ensureUserIsSiteAdmin", ->
  103. beforeEach ->
  104. @AuthorizationManager.isUserSiteAdmin = sinon.stub()
  105. @AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
  106. describe "with logged in user", ->
  107. beforeEach ->
  108. @AuthenticationController.getLoggedInUserId.returns(@user_id)
  109. describe "when user has permission", ->
  110. beforeEach ->
  111. @AuthorizationManager.isUserSiteAdmin
  112. .withArgs(@user_id)
  113. .yields(null, true)
  114. it "should return next", ->
  115. @AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
  116. @next.called.should.equal true
  117. describe "when user doesn't have permission", ->
  118. beforeEach ->
  119. @AuthorizationManager.isUserSiteAdmin
  120. .withArgs(@user_id)
  121. .yields(null, false)
  122. it "should redirect to redirectToRestricted", ->
  123. @AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
  124. @next.called.should.equal false
  125. @AuthorizationMiddlewear.redirectToRestricted
  126. .calledWith(@req, @res, @next)
  127. .should.equal true
  128. describe "with anonymous user", ->
  129. describe "when user has permission", ->
  130. beforeEach ->
  131. @AuthenticationController.getLoggedInUserId.returns(null)
  132. @AuthorizationManager.isUserSiteAdmin
  133. .withArgs(null)
  134. .yields(null, true)
  135. it "should return next", ->
  136. @AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
  137. @next.called.should.equal true
  138. describe "when user doesn't have permission", ->
  139. beforeEach ->
  140. @AuthenticationController.getLoggedInUserId.returns(null)
  141. @AuthorizationManager.isUserSiteAdmin
  142. .withArgs(null)
  143. .yields(null, false)
  144. it "should redirect to redirectToRestricted", ->
  145. @AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
  146. @next.called.should.equal false
  147. @AuthorizationMiddlewear.redirectToRestricted
  148. .calledWith(@req, @res, @next)
  149. .should.equal true
  150. describe "ensureUserCanReadMultipleProjects", ->
  151. beforeEach ->
  152. @AuthorizationManager.canUserReadProject = sinon.stub()
  153. @AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
  154. @req.query =
  155. project_ids: "project1,project2"
  156. describe "with logged in user", ->
  157. beforeEach ->
  158. @AuthenticationController.getLoggedInUserId.returns(@user_id)
  159. describe "when user has permission to access all projects", ->
  160. beforeEach ->
  161. @AuthorizationManager.canUserReadProject
  162. .withArgs(@user_id, "project1", @token)
  163. .yields(null, true)
  164. @AuthorizationManager.canUserReadProject
  165. .withArgs(@user_id, "project2", @token)
  166. .yields(null, true)
  167. it "should return next", ->
  168. @AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
  169. @next.called.should.equal true
  170. describe "when user doesn't have permission to access one of the projects", ->
  171. beforeEach ->
  172. @AuthorizationManager.canUserReadProject
  173. .withArgs(@user_id, "project1", @token)
  174. .yields(null, true)
  175. @AuthorizationManager.canUserReadProject
  176. .withArgs(@user_id, "project2", @token)
  177. .yields(null, false)
  178. it "should redirect to redirectToRestricted", ->
  179. @AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
  180. @next.called.should.equal false
  181. @AuthorizationMiddlewear.redirectToRestricted
  182. .calledWith(@req, @res, @next)
  183. .should.equal true
  184. describe "with anonymous user", ->
  185. describe "when user has permission", ->
  186. describe "when user has permission to access all projects", ->
  187. beforeEach ->
  188. @AuthenticationController.getLoggedInUserId.returns(null)
  189. @AuthorizationManager.canUserReadProject
  190. .withArgs(null, "project1", @token)
  191. .yields(null, true)
  192. @AuthorizationManager.canUserReadProject
  193. .withArgs(null, "project2", @token)
  194. .yields(null, true)
  195. it "should return next", ->
  196. @AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
  197. @next.called.should.equal true
  198. describe "when user doesn't have permission to access one of the projects", ->
  199. beforeEach ->
  200. @AuthenticationController.getLoggedInUserId.returns(null)
  201. @AuthorizationManager.canUserReadProject
  202. .withArgs(null, "project1", @token)
  203. .yields(null, true)
  204. @AuthorizationManager.canUserReadProject
  205. .withArgs(null, "project2", @token)
  206. .yields(null, false)
  207. it "should redirect to redirectToRestricted", ->
  208. @AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
  209. @next.called.should.equal false
  210. @AuthorizationMiddlewear.redirectToRestricted
  211. .calledWith(@req, @res, @next)
  212. .should.equal true