TpdsController.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* eslint-disable
  2. camelcase,
  3. handle-callback-err,
  4. max-len,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * DS207: Consider shorter variations of null checks
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. let parseParams
  15. const tpdsUpdateHandler = require('./TpdsUpdateHandler')
  16. const UpdateMerger = require('./UpdateMerger')
  17. const logger = require('logger-sharelatex')
  18. const Path = require('path')
  19. const metrics = require('metrics-sharelatex')
  20. const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
  21. const AuthenticationController = require('../Authentication/AuthenticationController')
  22. const TpdsQueueManager = require('./TpdsQueueManager').promises
  23. module.exports = {
  24. // mergeUpdate and deleteUpdate are used by Dropbox, where the project is only passed as the name, as the
  25. // first part of the file path. They have to check the project exists, find it, and create it if not.
  26. // They also ignore 'noisy' files like .DS_Store, .gitignore, etc.
  27. mergeUpdate(req, res) {
  28. metrics.inc('tpds.merge-update')
  29. const { filePath, user_id, projectName } = parseParams(req)
  30. const source = req.headers['x-sl-update-source'] || 'unknown'
  31. return tpdsUpdateHandler.newUpdate(
  32. user_id,
  33. projectName,
  34. filePath,
  35. req,
  36. source,
  37. function(err) {
  38. if (err != null) {
  39. if (err.name === 'TooManyRequestsError') {
  40. logger.warn(
  41. { err, user_id, filePath },
  42. 'tpds update failed to be processed, too many requests'
  43. )
  44. return res.sendStatus(429)
  45. } else if (err.name === 'ProjectIsArchivedOrTrashedError') {
  46. logger.info(
  47. { err, user_id, filePath, projectName },
  48. 'tpds project is archived'
  49. )
  50. return res.sendStatus(409)
  51. } else if (err.message === 'project_has_too_many_files') {
  52. logger.warn(
  53. { err, user_id, filePath },
  54. 'tpds trying to append to project over file limit'
  55. )
  56. NotificationsBuilder.tpdsFileLimit(user_id).create(projectName)
  57. return res.sendStatus(400)
  58. } else {
  59. logger.err(
  60. { err, user_id, filePath },
  61. 'error reciving update from tpds'
  62. )
  63. return res.sendStatus(500)
  64. }
  65. } else {
  66. return res.sendStatus(200)
  67. }
  68. }
  69. )
  70. },
  71. deleteUpdate(req, res) {
  72. metrics.inc('tpds.delete-update')
  73. const { filePath, user_id, projectName } = parseParams(req)
  74. const source = req.headers['x-sl-update-source'] || 'unknown'
  75. return tpdsUpdateHandler.deleteUpdate(
  76. user_id,
  77. projectName,
  78. filePath,
  79. source,
  80. function(err) {
  81. if (err != null) {
  82. logger.err(
  83. { err, user_id, filePath },
  84. 'error reciving update from tpds'
  85. )
  86. return res.sendStatus(500)
  87. } else {
  88. return res.sendStatus(200)
  89. }
  90. }
  91. )
  92. },
  93. // updateProjectContents and deleteProjectContents are used by GitHub. The project_id is known so we
  94. // can skip right ahead to creating/updating/deleting the file. These methods will not ignore noisy
  95. // files like .DS_Store, .gitignore, etc because people are generally more explicit with the files they
  96. // want in git.
  97. updateProjectContents(req, res, next) {
  98. if (next == null) {
  99. next = function(error) {}
  100. }
  101. const { project_id } = req.params
  102. const path = `/${req.params[0]}` // UpdateMerger expects leading slash
  103. const source = req.headers['x-sl-update-source'] || 'unknown'
  104. return UpdateMerger.mergeUpdate(
  105. null,
  106. project_id,
  107. path,
  108. req,
  109. source,
  110. function(error) {
  111. if (error != null) {
  112. return next(error)
  113. }
  114. return res.sendStatus(200)
  115. }
  116. )
  117. },
  118. deleteProjectContents(req, res, next) {
  119. if (next == null) {
  120. next = function(error) {}
  121. }
  122. const { project_id } = req.params
  123. const path = `/${req.params[0]}` // UpdateMerger expects leading slash
  124. const source = req.headers['x-sl-update-source'] || 'unknown'
  125. return UpdateMerger.deleteUpdate(null, project_id, path, source, function(
  126. error
  127. ) {
  128. if (error != null) {
  129. return next(error)
  130. }
  131. return res.sendStatus(200)
  132. })
  133. },
  134. async getQueues(req, res, next) {
  135. const userId = AuthenticationController.getLoggedInUserId(req)
  136. try {
  137. res.json(await TpdsQueueManager.getQueues(userId))
  138. } catch (err) {
  139. next(err)
  140. }
  141. },
  142. parseParams: (parseParams = function(req) {
  143. let filePath, projectName
  144. let path = req.params[0]
  145. const { user_id } = req.params
  146. path = Path.join('/', path)
  147. if (path.substring(1).indexOf('/') === -1) {
  148. filePath = '/'
  149. projectName = path.substring(1)
  150. } else {
  151. filePath = path.substring(path.indexOf('/', 1))
  152. projectName = path.substring(0, path.indexOf('/', 1))
  153. projectName = projectName.replace('/', '')
  154. }
  155. return { filePath, user_id, projectName }
  156. })
  157. }