SecurityManager.coffee 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. logger = require('logger-sharelatex')
  2. crypto = require 'crypto'
  3. Assert = require 'assert'
  4. Settings = require 'settings-sharelatex'
  5. User = require('../models/User').User
  6. Project = require('../models/Project').Project
  7. ErrorController = require("../Features/Errors/ErrorController")
  8. AuthenticationController = require("../Features/Authentication/AuthenticationController")
  9. _ = require('underscore')
  10. metrics = require('../infrastructure/Metrics')
  11. querystring = require('querystring')
  12. async = require "async"
  13. module.exports = SecurityManager =
  14. restricted : (req, res, next)->
  15. if req.session.user?
  16. res.render 'user/restricted',
  17. title:'restricted'
  18. else
  19. logger.log "user not logged in and trying to access #{req.url}, being redirected to login"
  20. res.redirect '/register'
  21. getCurrentUser: (req, callback) ->
  22. if req.session.user?
  23. User.findById req.session.user._id, callback
  24. else
  25. callback null, null
  26. requestCanAccessMultipleProjects: (req, res, next) ->
  27. project_ids = req.query.project_ids?.split(",")
  28. jobs = []
  29. for project_id in project_ids or []
  30. do (project_id) ->
  31. jobs.push (callback) ->
  32. # This is a bit hacky - better to have an abstracted method
  33. # that we can pass project_id to, but this whole file needs
  34. # a serious refactor ATM.
  35. req.params.Project_id = project_id
  36. SecurityManager.requestCanAccessProject req, res, (error) ->
  37. delete req.params.Project_id
  38. callback(error)
  39. async.series jobs, next
  40. requestCanAccessProject : (req, res, next)->
  41. doRequest = (req, res, next) ->
  42. getRequestUserAndProject req, res, {allow_auth_token: options?.allow_auth_token}, (err, user, project)->
  43. if !project? or project.archived
  44. return ErrorController.notFound(req, res, next)
  45. userCanAccessProject user, project, (canAccess, permissionLevel)->
  46. if canAccess
  47. next()
  48. else if user?
  49. logger.log "user_id: #{user._id} email: #{user.email} trying to access restricted page #{req.path}"
  50. res.redirect('/restricted')
  51. else
  52. logger.log "user not logged in and trying to access #{req.url}, being redirected to login"
  53. AuthenticationController._redirectToLoginOrRegisterPage(req, res)
  54. if arguments.length > 1
  55. options =
  56. allow_auth_token: false
  57. doRequest.apply(this, arguments)
  58. else
  59. options = req
  60. return doRequest
  61. requestCanModifyProject : (req, res, next)->
  62. getRequestUserAndProject req, res, {}, (err, user, project)=>
  63. userCanModifyProject user, project, (canModify)->
  64. if canModify
  65. next()
  66. else
  67. logger.log "user_id: #{user?._id} email: #{user?.email} can not modify project redirecting to restricted page"
  68. res.redirect('/restricted')
  69. userCanModifyProject : userCanModifyProject = (user, project, callback)->
  70. if !user? or !project?
  71. callback false
  72. else if userIsOwner user, project
  73. callback true
  74. else if userIsCollaberator user, project
  75. callback true
  76. else if project.publicAccesLevel == "readAndWrite"
  77. callback true
  78. else if user.isAdmin
  79. callback true
  80. else
  81. callback false
  82. requestIsOwner : (req, res, next)->
  83. getRequestUserAndProject req, res, {}, (err, user, project)->
  84. if userIsOwner user, project || user.isAdmin
  85. next()
  86. else
  87. logger.log user_id: user?._id, email: user?.email, "user is not owner of project redirecting to restricted page"
  88. res.redirect('/restricted')
  89. requestIsAdmin : isAdmin = (req, res, next)->
  90. logger.log "checking if user is admin"
  91. user = req.session.user
  92. if(user? && user.isAdmin)
  93. logger.log user: user, "User is admin"
  94. next()
  95. else
  96. res.redirect('/restricted')
  97. logger.log user:user, "is not admin redirecting to restricted page"
  98. userCanAccessProject : userCanAccessProject = (user, project, callback)=>
  99. if !user?
  100. user = {_id:'anonymous-user'}
  101. if !project?
  102. callback false
  103. logger.log user:user, project:project, "Checking if can access"
  104. if userIsOwner user, project
  105. callback true, "owner"
  106. else if userIsCollaberator user, project
  107. callback true, "readAndWrite"
  108. else if userIsReadOnly user, project
  109. callback true, "readOnly"
  110. else if user.isAdmin
  111. logger.log user:user, project:project, "user is admin and can access project"
  112. callback true, "owner"
  113. else if project.publicAccesLevel == "readAndWrite"
  114. logger.log user:user, project:project, "project is a public read and write project"
  115. callback true, "readAndWrite"
  116. else if project.publicAccesLevel == "readOnly"
  117. logger.log user:user, project:project, "project is a public read only project"
  118. callback true, "readOnly"
  119. else
  120. metrics.inc "security.denied"
  121. logger.log user:user, project:project, "Security denied - user can not enter project"
  122. callback false
  123. userIsOwner : userIsOwner = (user, project)->
  124. if !user?
  125. return false
  126. else
  127. userId = user._id+''
  128. ownerRef = getProjectIdFromRef(project.owner_ref)
  129. if userId == ownerRef
  130. true
  131. else
  132. false
  133. userIsCollaberator : userIsCollaberator = (user, project)->
  134. if !user?
  135. return false
  136. else
  137. userId = user._id+''
  138. result = false
  139. _.each project.collaberator_refs, (colabRef)->
  140. colabRef = getProjectIdFromRef(colabRef)
  141. if colabRef == userId
  142. result = true
  143. return result
  144. userIsReadOnly : userIsReadOnly = (user, project)->
  145. if !user?
  146. return false
  147. else
  148. userId = user._id+''
  149. result = false
  150. _.each project.readOnly_refs, (readOnlyRef)->
  151. readOnlyRef = getProjectIdFromRef(readOnlyRef)
  152. if readOnlyRef == userId
  153. result = true
  154. return result
  155. getRequestUserAndProject = (req, res, options, callback)->
  156. project_id = req.params.Project_id
  157. Project.findById project_id, 'name owner_ref readOnly_refs collaberator_refs publicAccesLevel archived', (err, project)=>
  158. if err?
  159. logger.err err:err, "error getting project for security check"
  160. return callback err
  161. AuthenticationController.getLoggedInUser req, options, (err, user)=>
  162. if err?
  163. logger.err err:err, "error getting last logged in user for security check"
  164. callback err, user, project
  165. getProjectIdFromRef = (ref)->
  166. if !ref?
  167. return null
  168. else if ref._id?
  169. return ref._id+''
  170. else
  171. return ref+''