UserMembershipAuthorizationTests.coffee 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. @AuthorizationMiddlewear =
  21. redirectToRestricted: sinon.stub().yields()
  22. ensureUserIsSiteAdmin: sinon.stub().yields()
  23. @UserMembershipAuthorization = SandboxedModule.require modulePath, requires:
  24. '../Authentication/AuthenticationController': @AuthenticationController
  25. '../Authorization/AuthorizationMiddlewear': @AuthorizationMiddlewear
  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.requireGroupAccess @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.requireGroupAccess @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.requirePublisherAccess @req, redirect: (path) =>
  61. expect(path).to.extist
  62. expect(path).to.match /create/
  63. done()
  64. it 'handle entity not found an admin cannot create', (done) ->
  65. @user.isAdmin = true
  66. @UserMembershipHandler.getEntity.yields(null, null)
  67. @UserMembershipHandler.getEntityWithoutAuthorizationCheck.yields(null, null)
  68. @UserMembershipAuthorization.requireGroupAccess @req, null, (error) =>
  69. expect(error).to.extist
  70. expect(error).to.be.instanceof(Error)
  71. expect(error.constructor.name).to.equal('NotFoundError')
  72. done()
  73. it 'handle entity no access', (done) ->
  74. @UserMembershipHandler.getEntity.yields(null, null)
  75. @UserMembershipAuthorization.requireGroupAccess @req, null, (error) =>
  76. sinon.assert.called(@AuthorizationMiddlewear.redirectToRestricted)
  77. done()
  78. it 'handle anonymous user', (done) ->
  79. @AuthenticationController.getSessionUser.returns(null)
  80. @UserMembershipAuthorization.requireGroupAccess @req, null, (error) =>
  81. expect(error).to.extist
  82. sinon.assert.called(@AuthorizationMiddlewear.redirectToRestricted)
  83. sinon.assert.notCalled(@UserMembershipHandler.getEntity)
  84. expect(@req.entity).to.not.exist
  85. done()
  86. describe 'requireEntityAccess', ->
  87. it 'handle team access', (done) ->
  88. @UserMembershipAuthorization.requireTeamAccess @req, null, (error) =>
  89. expect(error).to.not.extist
  90. sinon.assert.calledWithMatch(
  91. @UserMembershipHandler.getEntity,
  92. @req.params.id,
  93. fields: primaryKey: 'overleaf.id'
  94. )
  95. done()
  96. it 'handle group access', (done) ->
  97. @UserMembershipAuthorization.requireGroupAccess @req, null, (error) =>
  98. expect(error).to.not.extist
  99. sinon.assert.calledWithMatch(
  100. @UserMembershipHandler.getEntity,
  101. @req.params.id,
  102. translations: title: 'group_account'
  103. )
  104. done()
  105. it 'handle group managers access', (done) ->
  106. @UserMembershipAuthorization.requireGroupManagersAccess @req, null, (error) =>
  107. expect(error).to.not.extist
  108. sinon.assert.calledWithMatch(
  109. @UserMembershipHandler.getEntity,
  110. @req.params.id,
  111. translations: subtitle: 'managers_management'
  112. )
  113. done()
  114. it 'handle institution access', (done) ->
  115. @UserMembershipAuthorization.requireInstitutionAccess @req, null, (error) =>
  116. expect(error).to.not.extist
  117. sinon.assert.calledWithMatch(
  118. @UserMembershipHandler.getEntity,
  119. @req.params.id,
  120. modelName: 'Institution',
  121. )
  122. done()
  123. it 'handle template with brand access', (done) ->
  124. templateData =
  125. id: 123
  126. title: 'Template Title'
  127. brand: { slug: 'brand-slug' }
  128. @request.yields(null, { statusCode: 200 }, JSON.stringify(templateData))
  129. @UserMembershipAuthorization.requireTemplateAccess @req, null, (error) =>
  130. expect(error).to.not.extist
  131. sinon.assert.calledWithMatch(
  132. @UserMembershipHandler.getEntity,
  133. 'brand-slug',
  134. modelName: 'Publisher',
  135. )
  136. done()
  137. it 'handle template without brand access', (done) ->
  138. templateData =
  139. id: 123
  140. title: 'Template Title'
  141. brand: null
  142. @request.yields(null, { statusCode: 200 }, JSON.stringify(templateData))
  143. @UserMembershipAuthorization.requireTemplateAccess @req, null, (error) =>
  144. expect(error).to.not.extist
  145. sinon.assert.notCalled(@UserMembershipHandler.getEntity)
  146. sinon.assert.calledOnce(@AuthorizationMiddlewear.ensureUserIsSiteAdmin)
  147. done()
  148. it 'handle graph access', (done) ->
  149. @req.query.resource_id = 'mock-resource-id'
  150. @req.query.resource_type = 'institution'
  151. middlewear = @UserMembershipAuthorization.requireGraphAccess
  152. middlewear @req, null, (error) =>
  153. expect(error).to.not.extist
  154. sinon.assert.calledWithMatch(
  155. @UserMembershipHandler.getEntity,
  156. @req.query.resource_id,
  157. modelName: 'Institution',
  158. )
  159. done()