ProjectFileAgent.coffee 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. AuthorizationManager = require('../Authorization/AuthorizationManager')
  2. ProjectLocator = require('../Project/ProjectLocator')
  3. ProjectGetter = require('../Project/ProjectGetter')
  4. Project = require("../../models/Project").Project
  5. DocstoreManager = require('../Docstore/DocstoreManager')
  6. FileStoreHandler = require('../FileStore/FileStoreHandler')
  7. _ = require "underscore"
  8. Settings = require 'settings-sharelatex'
  9. LinkedFilesHandler = require './LinkedFilesHandler'
  10. {
  11. BadDataError,
  12. AccessDeniedError,
  13. BadEntityTypeError,
  14. SourceFileNotFoundError,
  15. ProjectNotFoundError,
  16. V1ProjectNotFoundError
  17. } = require './LinkedFilesErrors'
  18. module.exports = ProjectFileAgent = {
  19. createLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
  20. if !@_canCreate(linkedFileData)
  21. return callback(new AccessDeniedError())
  22. @_go(project_id, linkedFileData, name, parent_folder_id, user_id, callback)
  23. refreshLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
  24. @_go project_id, linkedFileData, name, parent_folder_id, user_id, callback
  25. _prepare: (project_id, linkedFileData, user_id, callback=(err, linkedFileData)->) ->
  26. @_checkAuth project_id, linkedFileData, user_id, (err, allowed) =>
  27. return callback(err) if err?
  28. return callback(new AccessDeniedError()) if !allowed
  29. @_decorateLinkedFileData linkedFileData, (err, newLinkedFileData) =>
  30. return callback(err) if err?
  31. if !@_validate(newLinkedFileData)
  32. return callback(new BadDataError())
  33. callback(null, newLinkedFileData)
  34. _go: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
  35. linkedFileData = @_sanitizeData(linkedFileData)
  36. @_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
  37. return callback(err) if err?
  38. if !@_validate(linkedFileData)
  39. return callback(new BadDataError())
  40. @_getEntity linkedFileData, user_id, (err, source_project, entity, type) =>
  41. return callback(err) if err?
  42. if type == 'doc'
  43. DocstoreManager.getDoc source_project._id, entity._id, (err, lines) ->
  44. return callback(err) if err?
  45. LinkedFilesHandler.importContent project_id,
  46. lines.join('\n'),
  47. linkedFileData,
  48. name,
  49. parent_folder_id,
  50. user_id,
  51. (err, file) ->
  52. return callback(err) if err?
  53. callback(null, file._id) # Created
  54. else if type == 'file'
  55. FileStoreHandler.getFileStream source_project._id, entity._id, null, (err, fileStream) ->
  56. return callback(err) if err?
  57. LinkedFilesHandler.importFromStream project_id,
  58. fileStream,
  59. linkedFileData,
  60. name,
  61. parent_folder_id,
  62. user_id,
  63. (err, file) ->
  64. return callback(err) if err?
  65. callback(null, file._id) # Created
  66. else
  67. callback(new BadEntityTypeError())
  68. _getEntity:
  69. (linkedFileData, current_user_id, callback = (err, entity, type) ->) ->
  70. callback = _.once(callback)
  71. { source_entity_path } = linkedFileData
  72. @_getSourceProject linkedFileData, (err, project) ->
  73. return callback(err) if err?
  74. source_project_id = project._id
  75. ProjectLocator.findElementByPath {
  76. project_id: source_project_id,
  77. path: source_entity_path
  78. }, (err, entity, type) ->
  79. if err?
  80. if err.toString().match(/^not found.*/)
  81. err = new SourceFileNotFoundError()
  82. return callback(err)
  83. callback(null, project, entity, type)
  84. _sanitizeData: (data) ->
  85. return _.pick(
  86. data,
  87. 'provider',
  88. 'source_project_id',
  89. 'v1_source_doc_id',
  90. 'source_entity_path'
  91. )
  92. _validate: (data) ->
  93. return (
  94. (data.source_project_id? || data.v1_source_doc_id?) &&
  95. data.source_entity_path?
  96. )
  97. _canCreate: (data) ->
  98. # Don't allow creation of linked-files with v1 doc ids
  99. !data.v1_source_doc_id?
  100. _getSourceProject: (data, callback=(err, project)->) ->
  101. projection = {_id: 1, name: 1}
  102. if data.v1_source_doc_id?
  103. Project.findOne {'overleaf.id': data.v1_source_doc_id}, projection, (err, project) ->
  104. return callback(err) if err?
  105. if !project?
  106. return callback(new V1ProjectNotFoundError())
  107. callback(null, project)
  108. else if data.source_project_id?
  109. ProjectGetter.getProject data.source_project_id, projection, (err, project) ->
  110. return callback(err) if err?
  111. if !project?
  112. return callback(new ProjectNotFoundError())
  113. callback(null, project)
  114. else
  115. callback(new BadDataError('neither v1 nor v2 id present'))
  116. _decorateLinkedFileData: (data, callback = (err, newData) ->) ->
  117. callback = _.once(callback)
  118. @_getSourceProject data, (err, project) ->
  119. return callback(err) if err?
  120. callback(err, _.extend(data, {source_project_display_name: project.name}))
  121. _checkAuth: (project_id, data, current_user_id, callback = (error, allowed)->) ->
  122. callback = _.once(callback)
  123. if !ProjectFileAgent._validate(data)
  124. return callback(new BadDataError())
  125. @_getSourceProject data, (err, project) ->
  126. return callback(err) if err?
  127. AuthorizationManager.canUserReadProject current_user_id, project._id, null, (err, canRead) ->
  128. return callback(err) if err?
  129. callback(null, canRead)
  130. }