ProjectFileAgent.coffee 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. FileWriter = require('../../infrastructure/FileWriter')
  2. AuthorizationManager = require('../Authorization/AuthorizationManager')
  3. ProjectLocator = require('../Project/ProjectLocator')
  4. ProjectGetter = require('../Project/ProjectGetter')
  5. DocstoreManager = require('../Docstore/DocstoreManager')
  6. FileStoreHandler = require('../FileStore/FileStoreHandler')
  7. FileWriter = require('../../infrastructure/FileWriter')
  8. _ = require "underscore"
  9. Settings = require 'settings-sharelatex'
  10. AccessDeniedError = (message) ->
  11. error = new Error(message)
  12. error.name = 'AccessDenied'
  13. error.__proto__ = AccessDeniedError.prototype
  14. return error
  15. AccessDeniedError.prototype.__proto__ = Error.prototype
  16. BadEntityTypeError = (message) ->
  17. error = new Error(message)
  18. error.name = 'BadEntityType'
  19. error.__proto__ = BadEntityTypeError.prototype
  20. return error
  21. BadEntityTypeError.prototype.__proto__ = Error.prototype
  22. BadDataError = (message) ->
  23. error = new Error(message)
  24. error.name = 'BadData'
  25. error.__proto__ = BadDataError.prototype
  26. return error
  27. BadDataError.prototype.__proto__ = Error.prototype
  28. ProjectNotFoundError = (message) ->
  29. error = new Error(message)
  30. error.name = 'ProjectNotFound'
  31. error.__proto__ = ProjectNotFoundError.prototype
  32. return error
  33. ProjectNotFoundError.prototype.__proto__ = Error.prototype
  34. SourceFileNotFoundError = (message) ->
  35. error = new Error(message)
  36. error.name = 'BadData'
  37. error.__proto__ = SourceFileNotFoundError.prototype
  38. return error
  39. SourceFileNotFoundError.prototype.__proto__ = Error.prototype
  40. module.exports = ProjectFileAgent =
  41. sanitizeData: (data) ->
  42. return _.pick(
  43. data,
  44. 'source_project_id',
  45. 'source_entity_path'
  46. )
  47. _validate: (data) ->
  48. return (
  49. data.source_project_id? &&
  50. data.source_entity_path?
  51. )
  52. decorateLinkedFileData: (data, callback = (err, newData) ->) ->
  53. callback = _.once(callback)
  54. { source_project_id } = data
  55. return callback(new BadDataError()) if !source_project_id?
  56. ProjectGetter.getProject source_project_id, (err, project) ->
  57. return callback(err) if err?
  58. return callback(new ProjectNotFoundError()) if !project?
  59. callback(err, _.extend(data, {source_project_display_name: project.name}))
  60. checkAuth: (project_id, data, current_user_id, callback = (error, allowed)->) ->
  61. callback = _.once(callback)
  62. if !ProjectFileAgent._validate(data)
  63. return callback(new BadDataError())
  64. {source_project_id, source_entity_path} = data
  65. AuthorizationManager.canUserReadProject current_user_id, source_project_id, null, (err, canRead) ->
  66. return callback(err) if err?
  67. callback(null, canRead)
  68. writeIncomingFileToDisk:
  69. (project_id, data, current_user_id, callback = (error, fsPath) ->) ->
  70. callback = _.once(callback)
  71. if !ProjectFileAgent._validate(data)
  72. return callback(new BadDataError())
  73. {source_project_id, source_entity_path} = data
  74. ProjectLocator.findElementByPath {
  75. project_id: source_project_id,
  76. path: source_entity_path
  77. }, (err, entity, type) ->
  78. if err?
  79. if err.toString().match(/^not found.*/)
  80. err = new SourceFileNotFoundError()
  81. return callback(err)
  82. ProjectFileAgent._writeEntityToDisk source_project_id, entity._id, type, callback
  83. _writeEntityToDisk: (project_id, entity_id, type, callback=(err, location)->) ->
  84. callback = _.once(callback)
  85. if type == 'doc'
  86. DocstoreManager.getDoc project_id, entity_id, (err, lines) ->
  87. return callback(err) if err?
  88. FileWriter.writeLinesToDisk entity_id, lines, callback
  89. else if type == 'file'
  90. FileStoreHandler.getFileStream project_id, entity_id, null, (err, fileStream) ->
  91. return callback(err) if err?
  92. FileWriter.writeStreamToDisk entity_id, fileStream, callback
  93. else
  94. callback(new BadEntityTypeError())
  95. handleError: (error, req, res, next) ->
  96. if error instanceof AccessDeniedError
  97. res.status(403).send("You do not have access to this project")
  98. else if error instanceof BadDataError
  99. res.status(400).send("The submitted data is not valid")
  100. else if error instanceof BadEntityTypeError
  101. res.status(400).send("The file is the wrong type")
  102. else if error instanceof SourceFileNotFoundError
  103. res.status(404).send("Source file not found")
  104. else if error instanceof ProjectNotFoundError
  105. res.status(404).send("Project not found")
  106. else
  107. next(error)
  108. next()