FileSystemImportManager.coffee 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. async = require "async"
  2. fs = require "fs"
  3. _ = require "underscore"
  4. FileTypeManager = require "./FileTypeManager"
  5. EditorController = require "../Editor/EditorController"
  6. ProjectLocator = require "../Project/ProjectLocator"
  7. logger = require("logger-sharelatex")
  8. module.exports = FileSystemImportManager =
  9. addDoc: (user_id, project_id, folder_id, name, path, replace, callback = (error, doc)-> )->
  10. FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
  11. if !isSafe
  12. logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, name:name, path:path, "add doc is from symlink, stopping process"
  13. return callback("path is symlink")
  14. fs.readFile path, "utf8", (error, content = "") ->
  15. return callback(error) if error?
  16. content = content.replace(/\r/g, "")
  17. lines = content.split("\n")
  18. if replace
  19. ProjectLocator.findElement project_id: project_id, element_id: folder_id, type: "folder", (error, folder) ->
  20. return callback(error) if error?
  21. return callback(new Error("Couldn't find folder")) if !folder?
  22. existingDoc = null
  23. for doc in folder.docs
  24. if doc.name == name
  25. existingDoc = doc
  26. break
  27. if existingDoc?
  28. EditorController.setDoc project_id, existingDoc._id, user_id, lines, "upload", callback
  29. else
  30. EditorController.addDocWithoutLock project_id, folder_id, name, lines, "upload", user_id, callback
  31. else
  32. EditorController.addDocWithoutLock project_id, folder_id, name, lines, "upload", user_id, callback
  33. addFile: (user_id, project_id, folder_id, name, path, replace, callback = (error, file)-> )->
  34. FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
  35. if !isSafe
  36. logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, name:name, path:path, "add file is from symlink, stopping insert"
  37. return callback("path is symlink")
  38. if !replace
  39. EditorController.addFileWithoutLock project_id, folder_id, name, path, "upload", user_id, callback
  40. else
  41. ProjectLocator.findElement project_id: project_id, element_id: folder_id, type: "folder", (error, folder) ->
  42. return callback(error) if error?
  43. return callback(new Error("Couldn't find folder")) if !folder?
  44. existingFile = null
  45. for fileRef in folder.fileRefs
  46. if fileRef.name == name
  47. existingFile = fileRef
  48. break
  49. if existingFile?
  50. EditorController.replaceFile project_id, existingFile._id, path, "upload", user_id, callback
  51. else
  52. EditorController.addFileWithoutLock project_id, folder_id, name, path, "upload", user_id, callback
  53. addFolder: (user_id, project_id, folder_id, name, path, replace, callback = (error)-> ) ->
  54. FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
  55. if !isSafe
  56. logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, path:path, "add folder is from symlink, stopping insert"
  57. return callback("path is symlink")
  58. EditorController.addFolderWithoutLock project_id, folder_id, name, "upload", (error, new_folder) =>
  59. return callback(error) if error?
  60. FileSystemImportManager.addFolderContents user_id, project_id, new_folder._id, path, replace, (error) ->
  61. return callback(error) if error?
  62. callback null, new_folder
  63. addFolderContents: (user_id, project_id, parent_folder_id, folderPath, replace, callback = (error)-> ) ->
  64. FileSystemImportManager._isSafeOnFileSystem folderPath, (err, isSafe)->
  65. if !isSafe
  66. logger.log user_id:user_id, project_id:project_id, parent_folder_id:parent_folder_id, folderPath:folderPath, "add folder contents is from symlink, stopping insert"
  67. return callback("path is symlink")
  68. fs.readdir folderPath, (error, entries = []) =>
  69. return callback(error) if error?
  70. jobs = _.map entries, (entry) =>
  71. (callback) =>
  72. FileTypeManager.shouldIgnore entry, (error, ignore) =>
  73. return callback(error) if error?
  74. if !ignore
  75. FileSystemImportManager.addEntity user_id, project_id, parent_folder_id, entry, "#{folderPath}/#{entry}", replace, callback
  76. else
  77. callback()
  78. async.parallelLimit jobs, 5, callback
  79. addEntity: (user_id, project_id, folder_id, name, path, replace, callback = (error, entity)-> ) ->
  80. FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
  81. if !isSafe
  82. logger.log user_id:user_id, project_id:project_id, folder_id:folder_id, path:path, "add entry is from symlink, stopping insert"
  83. return callback("path is symlink")
  84. FileTypeManager.isDirectory path, (error, isDirectory) =>
  85. return callback(error) if error?
  86. if isDirectory
  87. FileSystemImportManager.addFolder user_id, project_id, folder_id, name, path, replace, callback
  88. else
  89. FileTypeManager.isBinary name, path, (error, isBinary) =>
  90. return callback(error) if error?
  91. if isBinary
  92. FileSystemImportManager.addFile user_id, project_id, folder_id, name, path, replace, (err, entity) ->
  93. entity?.type = 'file'
  94. callback(err, entity)
  95. else
  96. FileSystemImportManager.addDoc user_id, project_id, folder_id, name, path, replace, (err, entity) ->
  97. entity?.type = 'doc'
  98. callback(err, entity)
  99. _isSafeOnFileSystem: (path, callback = (err, isSafe)->)->
  100. fs.lstat path, (err, stat)->
  101. if err?
  102. logger.err err:err, "error with path symlink check"
  103. return callback(err)
  104. isSafe = stat.isFile() or stat.isDirectory()
  105. callback(err, isSafe)