TpdsUpdateSender.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /* eslint-disable
  2. camelcase,
  3. handle-callback-err,
  4. max-len,
  5. no-irregular-whitespace,
  6. no-unused-vars,
  7. */
  8. // TODO: This file was created by bulk-decaffeinate.
  9. // Fix any style issues and re-enable lint.
  10. /*
  11. * decaffeinate suggestions:
  12. * DS102: Remove unnecessary code created because of implicit returns
  13. * DS207: Consider shorter variations of null checks
  14. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  15. */
  16. let tpdsUrl
  17. const settings = require('settings-sharelatex')
  18. const logger = require('logger-sharelatex')
  19. const path = require('path')
  20. const ProjectGetter = require('../Project/ProjectGetter')
  21. const keys = require('../../infrastructure/Keys')
  22. const metrics = require('metrics-sharelatex')
  23. const request = require('request')
  24. const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
  25. const { promisifyAll } = require('../../util/promises')
  26. const buildPath = function(user_id, project_name, filePath) {
  27. let projectPath = path.join(project_name, '/', filePath)
  28. projectPath = encodeURIComponent(projectPath)
  29. const fullPath = path.join('/user/', `${user_id}`, '/entity/', projectPath)
  30. return fullPath
  31. }
  32. const tpdsworkerEnabled = () =>
  33. (settings.apis.tpdsworker != null
  34. ? settings.apis.tpdsworker.url
  35. : undefined) != null
  36. if (!tpdsworkerEnabled()) {
  37. logger.log('tpdsworker is not enabled, request will not be sent to it')
  38. }
  39. if (settings.apis.thirdPartyDataStore.linode_url != null) {
  40. tpdsUrl = settings.apis.thirdPartyDataStore.linode_url
  41. } else {
  42. tpdsUrl = settings.apis.thirdPartyDataStore.url
  43. }
  44. const TpdsUpdateSender = {
  45. _enqueue(group, method, job, callback) {
  46. if (!tpdsworkerEnabled()) {
  47. return callback()
  48. }
  49. const opts = {
  50. uri: `${settings.apis.tpdsworker.url}/enqueue/web_to_tpds_http_requests`,
  51. json: {
  52. group,
  53. method,
  54. job
  55. },
  56. method: 'post',
  57. timeout: 5 * 1000
  58. }
  59. return request(opts, function(err) {
  60. if (err != null) {
  61. logger.err(
  62. { err },
  63. 'error queuing something in the tpdsworker, continuing anyway'
  64. )
  65. return callback()
  66. } else {
  67. return callback()
  68. }
  69. })
  70. },
  71. _addEntity(options, callback) {
  72. if (callback == null) {
  73. callback = function(err) {}
  74. }
  75. return getProjectsUsersIds(options.project_id, function(
  76. err,
  77. user_id,
  78. allUserIds
  79. ) {
  80. if (err != null) {
  81. logger.warn({ err, options }, 'error getting projects user ids')
  82. return callback(err)
  83. }
  84. logger.log(
  85. {
  86. project_id: options.project_id,
  87. user_id,
  88. path: options.path,
  89. uri: options.uri,
  90. rev: options.rev
  91. },
  92. 'sending file to third party data store'
  93. )
  94. const postOptions = {
  95. method: 'post',
  96. headers: {
  97. sl_entity_rev: options.rev,
  98. sl_project_id: options.project_id,
  99. sl_all_user_ids: JSON.stringify(allUserIds)
  100. },
  101. uri: `${tpdsUrl}${buildPath(
  102. user_id,
  103. options.project_name,
  104. options.path
  105. )}`,
  106. title: 'addFile',
  107. streamOrigin: options.streamOrigin
  108. }
  109. return TpdsUpdateSender._enqueue(
  110. options.project_id,
  111. 'pipeStreamFrom',
  112. postOptions,
  113. function(err) {
  114. if (err != null) {
  115. logger.warn(
  116. {
  117. err,
  118. project_id: options.project_id,
  119. user_id,
  120. path: options.path,
  121. uri: options.uri,
  122. rev: options.rev
  123. },
  124. 'error sending file to third party data store queued up for processing'
  125. )
  126. return callback(err)
  127. }
  128. logger.log(
  129. {
  130. project_id: options.project_id,
  131. user_id,
  132. path: options.path,
  133. uri: options.uri,
  134. rev: options.rev
  135. },
  136. 'sending file to third party data store queued up for processing'
  137. )
  138. return callback(err)
  139. }
  140. )
  141. })
  142. },
  143. addFile(options, callback) {
  144. if (callback == null) {
  145. callback = function(err) {}
  146. }
  147. metrics.inc('tpds.add-file')
  148. options.streamOrigin =
  149. (settings.apis.filestore.linode_url || settings.apis.filestore.url) +
  150. path.join(`/project/${options.project_id}/file/`, `${options.file_id}`)
  151. return this._addEntity(options, callback)
  152. },
  153. addDoc(options, callback) {
  154. if (callback == null) {
  155. callback = function(err) {}
  156. }
  157. metrics.inc('tpds.add-doc')
  158. options.streamOrigin =
  159. (settings.apis.docstore.linode_url || settings.apis.docstore.pubUrl) +
  160. path.join(`/project/${options.project_id}/doc/`, `${options.doc_id}/raw`)
  161. return this._addEntity(options, callback)
  162. },
  163. moveEntity(options, callback) {
  164. let endPath, startPath
  165. if (callback == null) {
  166. callback = function(err) {}
  167. }
  168. metrics.inc('tpds.move-entity')
  169. if (options.newProjectName != null) {
  170. startPath = path.join(`/${options.project_name}/`)
  171. endPath = path.join(`/${options.newProjectName}/`)
  172. } else {
  173. startPath = mergeProjectNameAndPath(
  174. options.project_name,
  175. options.startPath
  176. )
  177. endPath = mergeProjectNameAndPath(options.project_name, options.endPath)
  178. }
  179. return getProjectsUsersIds(options.project_id, function(
  180. err,
  181. user_id,
  182. allUserIds
  183. ) {
  184. const moveOptions = {
  185. method: 'put',
  186. title: 'moveEntity',
  187. uri: `${tpdsUrl}/user/${user_id}/entity`,
  188. headers: {
  189. sl_project_id: options.project_id,
  190. sl_entity_rev: options.rev,
  191. sl_all_user_ids: JSON.stringify(allUserIds)
  192. },
  193. json: {
  194. user_id,
  195. endPath,
  196. startPath
  197. }
  198. }
  199. return TpdsUpdateSender._enqueue(
  200. options.project_id,
  201. 'standardHttpRequest',
  202. moveOptions,
  203. callback
  204. )
  205. })
  206. },
  207. deleteEntity(options, callback) {
  208. if (callback == null) {
  209. callback = function(err) {}
  210. }
  211. metrics.inc('tpds.delete-entity')
  212. return getProjectsUsersIds(options.project_id, function(
  213. err,
  214. user_id,
  215. allUserIds
  216. ) {
  217. const deleteOptions = {
  218. method: 'DELETE',
  219. headers: {
  220. sl_project_id: options.project_id,
  221. sl_all_user_ids: JSON.stringify(allUserIds)
  222. },
  223. uri: `${tpdsUrl}${buildPath(
  224. user_id,
  225. options.project_name,
  226. options.path
  227. )}`,
  228. title: 'deleteEntity',
  229. sl_all_user_ids: JSON.stringify(allUserIds)
  230. }
  231. return TpdsUpdateSender._enqueue(
  232. options.project_id,
  233. 'standardHttpRequest',
  234. deleteOptions,
  235. callback
  236. )
  237. })
  238. },
  239. pollDropboxForUser(user_id, callback) {
  240. if (callback == null) {
  241. callback = function(err) {}
  242. }
  243. metrics.inc('tpds.poll-dropbox')
  244. const options = {
  245. method: 'POST',
  246. uri: `${tpdsUrl}/user/poll`,
  247. json: {
  248. user_ids: [user_id]
  249. }
  250. }
  251. return TpdsUpdateSender._enqueue(
  252. `poll-dropbox:${user_id}`,
  253. 'standardHttpRequest',
  254. options,
  255. callback
  256. )
  257. }
  258. }
  259. var getProjectsUsersIds = function(project_id, callback) {
  260. if (callback == null) {
  261. callback = function(err, owner_id, allUserIds) {}
  262. }
  263. return ProjectGetter.getProject(
  264. project_id,
  265. { _id: true, owner_ref: true },
  266. function(err, project) {
  267. if (err != null) {
  268. return callback(err)
  269. }
  270. return CollaboratorsGetter.getInvitedMemberIds(project_id, function(
  271. err,
  272. member_ids
  273. ) {
  274. if (err != null) {
  275. return callback(err)
  276. }
  277. return callback(
  278. err,
  279. project != null ? project.owner_ref : undefined,
  280. member_ids
  281. )
  282. })
  283. }
  284. )
  285. }
  286. var mergeProjectNameAndPath = function(project_name, path) {
  287. if (path.indexOf('/') === 0) {
  288. path = path.substring(1)
  289. }
  290. const fullPath = `/${project_name}/${path}`
  291. return fullPath
  292. }
  293. TpdsUpdateSender.promises = promisifyAll(TpdsUpdateSender)
  294. module.exports = TpdsUpdateSender