UserMembershipAuthorizationTests.coffee 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. sinon = require('sinon')
  2. chai = require('chai')
  3. expect = require('chai').expect
  4. modulePath = "../../../../app/js/Features/UserMembership/UserMembershipAuthorization.js"
  5. SandboxedModule = require('sandboxed-module')
  6. MockRequest = require "../helpers/MockRequest"
  7. EntityConfigs = require("../../../../app/js/Features/UserMembership/UserMembershipEntityConfigs")
  8. Errors = require("../../../../app/js/Features/Errors/Errors")
  9. describe "UserMembershipAuthorization", ->
  10. beforeEach ->
  11. @req = new MockRequest()
  12. @req.params.id = 'mock-entity-id'
  13. @user = _id: 'mock-user-id'
  14. @subscription = { _id: 'mock-subscription-id'}
  15. @AuthenticationController =
  16. getSessionUser: sinon.stub().returns(@user)
  17. @UserMembershipHandler =
  18. getEntity: sinon.stub().yields(null, @subscription)
  19. getEntityWithoutAuthorizationCheck: sinon.stub().yields(null, @subscription)
  20. @AuthorizationMiddleware =
  21. redirectToRestricted: sinon.stub().yields()
  22. ensureUserIsSiteAdmin: sinon.stub().yields()
  23. @UserMembershipAuthorization = SandboxedModule.require modulePath, requires:
  24. '../Authentication/AuthenticationController': @AuthenticationController
  25. '../Authorization/AuthorizationMiddleware': @AuthorizationMiddleware
  26. './UserMembershipHandler': @UserMembershipHandler
  27. './EntityConfigs': EntityConfigs
  28. '../Errors/Errors': Errors
  29. 'request': @request = sinon.stub().yields(null, null, {})
  30. "logger-sharelatex":
  31. log: ->
  32. err: ->
  33. describe 'requireAccessToEntity', ->
  34. it 'get entity', (done) ->
  35. @UserMembershipAuthorization.requireGroupMetricsAccess @req, null, (error) =>
  36. expect(error).to.not.extist
  37. sinon.assert.calledWithMatch(
  38. @UserMembershipHandler.getEntity,
  39. @req.params.id,
  40. modelName: 'Subscription',
  41. @user
  42. )
  43. expect(@req.entity).to.equal @subscription
  44. expect(@req.entityConfig).to.exist
  45. done()
  46. it 'handle entity not found as non-admin', (done) ->
  47. @UserMembershipHandler.getEntity.yields(null, null)
  48. @UserMembershipHandler.getEntityWithoutAuthorizationCheck.yields(null, null)
  49. @UserMembershipAuthorization.requireGroupMetricsAccess @req, null, (error) =>
  50. expect(error).to.extist
  51. expect(error).to.be.instanceof(Error)
  52. expect(error.constructor.name).to.equal('NotFoundError')
  53. sinon.assert.called(@UserMembershipHandler.getEntity)
  54. expect(@req.entity).to.not.exist
  55. done()
  56. it 'handle entity not found an admin can create', (done) ->
  57. @user.isAdmin = true
  58. @UserMembershipHandler.getEntity.yields(null, null)
  59. @UserMembershipHandler.getEntityWithoutAuthorizationCheck.yields(null, null)
  60. @UserMembershipAuthorization.requirePublisherMetricsAccess @req, redirect: (path) =>
  61. expect(path).to.extist
  62. expect(path).to.match /create/
  63. done()
  64. it 'handle entity not found a non-admin can create', (done) ->
  65. @user.staffAccess = { institutionManagement: true }
  66. @UserMembershipHandler.getEntity.yields(null, null)
  67. @UserMembershipHandler.getEntityWithoutAuthorizationCheck.yields(null, null)
  68. @UserMembershipAuthorization.requirePublisherMetricsAccess @req, redirect: (path) =>
  69. expect(path).to.extist
  70. expect(path).to.match /create/
  71. done()
  72. it 'handle entity not found an admin cannot create', (done) ->
  73. @user.isAdmin = true
  74. @UserMembershipHandler.getEntity.yields(null, null)
  75. @UserMembershipHandler.getEntityWithoutAuthorizationCheck.yields(null, null)
  76. @UserMembershipAuthorization.requireGroupMetricsAccess @req, null, (error) =>
  77. expect(error).to.extist
  78. expect(error).to.be.instanceof(Error)
  79. expect(error.constructor.name).to.equal('NotFoundError')
  80. done()
  81. it 'handle entity no access', (done) ->
  82. @UserMembershipHandler.getEntity.yields(null, null)
  83. @UserMembershipAuthorization.requireGroupMetricsAccess @req, null, (error) =>
  84. sinon.assert.called(@AuthorizationMiddleware.redirectToRestricted)
  85. done()
  86. it 'handle anonymous user', (done) ->
  87. @AuthenticationController.getSessionUser.returns(null)
  88. @UserMembershipAuthorization.requireGroupMetricsAccess @req, null, (error) =>
  89. expect(error).to.extist
  90. sinon.assert.called(@AuthorizationMiddleware.redirectToRestricted)
  91. sinon.assert.notCalled(@UserMembershipHandler.getEntity)
  92. expect(@req.entity).to.not.exist
  93. done()
  94. describe 'requireEntityAccess', ->
  95. it 'handle team access', (done) ->
  96. @UserMembershipAuthorization.requireTeamMetricsAccess @req, null, (error) =>
  97. expect(error).to.not.extist
  98. sinon.assert.calledWithMatch(
  99. @UserMembershipHandler.getEntity,
  100. @req.params.id,
  101. fields: primaryKey: 'overleaf.id'
  102. )
  103. done()
  104. it 'handle group access', (done) ->
  105. @UserMembershipAuthorization.requireGroupMetricsAccess @req, null, (error) =>
  106. expect(error).to.not.extist
  107. sinon.assert.calledWithMatch(
  108. @UserMembershipHandler.getEntity,
  109. @req.params.id,
  110. translations: title: 'group_account'
  111. )
  112. done()
  113. it 'handle group managers access', (done) ->
  114. @UserMembershipAuthorization.requireGroupManagersManagementAccess @req, null, (error) =>
  115. expect(error).to.not.extist
  116. sinon.assert.calledWithMatch(
  117. @UserMembershipHandler.getEntity,
  118. @req.params.id,
  119. translations: subtitle: 'managers_management'
  120. )
  121. done()
  122. it 'handle institution access', (done) ->
  123. @UserMembershipAuthorization.requireInstitutionMetricsAccess @req, null, (error) =>
  124. expect(error).to.not.extist
  125. sinon.assert.calledWithMatch(
  126. @UserMembershipHandler.getEntity,
  127. @req.params.id,
  128. modelName: 'Institution',
  129. )
  130. done()
  131. it 'handle template with brand access', (done) ->
  132. templateData =
  133. id: 123
  134. title: 'Template Title'
  135. brand: { slug: 'brand-slug' }
  136. @request.yields(null, { statusCode: 200 }, JSON.stringify(templateData))
  137. @UserMembershipAuthorization.requireTemplateMetricsAccess @req, null, (error) =>
  138. expect(error).to.not.extist
  139. sinon.assert.calledWithMatch(
  140. @UserMembershipHandler.getEntity,
  141. 'brand-slug',
  142. modelName: 'Publisher',
  143. )
  144. done()
  145. it 'handle template without brand access', (done) ->
  146. templateData =
  147. id: 123
  148. title: 'Template Title'
  149. brand: null
  150. @request.yields(null, { statusCode: 200 }, JSON.stringify(templateData))
  151. @UserMembershipAuthorization.requireTemplateMetricsAccess @req, null, (error) =>
  152. expect(error).to.not.extist
  153. sinon.assert.notCalled(@UserMembershipHandler.getEntity)
  154. sinon.assert.calledOnce(@AuthorizationMiddleware.ensureUserIsSiteAdmin)
  155. done()
  156. it 'handle graph access', (done) ->
  157. @req.query.resource_id = 'mock-resource-id'
  158. @req.query.resource_type = 'institution'
  159. middleware = @UserMembershipAuthorization.requireGraphAccess
  160. middleware @req, null, (error) =>
  161. expect(error).to.not.extist
  162. sinon.assert.calledWithMatch(
  163. @UserMembershipHandler.getEntity,
  164. @req.query.resource_id,
  165. modelName: 'Institution',
  166. )
  167. done()