TpdsUpdateSender.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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 TpdsUpdateSender, 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 CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
  25. const buildPath = function(user_id, project_name, filePath) {
  26. let projectPath = path.join(project_name, '/', filePath)
  27. projectPath = encodeURIComponent(projectPath)
  28. const fullPath = path.join('/user/', `${user_id}`, '/entity/', projectPath)
  29. return fullPath
  30. }
  31. const tpdsworkerEnabled = () =>
  32. (settings.apis.tpdsworker != null
  33. ? settings.apis.tpdsworker.url
  34. : undefined) != null
  35. if (!tpdsworkerEnabled()) {
  36. logger.log('tpdsworker is not enabled, request will not be sent to it')
  37. }
  38. if (settings.apis.thirdPartyDataStore.linode_url != null) {
  39. tpdsUrl = settings.apis.thirdPartyDataStore.linode_url
  40. } else {
  41. tpdsUrl = settings.apis.thirdPartyDataStore.url
  42. }
  43. module.exports = TpdsUpdateSender = {
  44. _enqueue(group, method, job, callback) {
  45. if (!tpdsworkerEnabled()) {
  46. return callback()
  47. }
  48. const opts = {
  49. uri: `${settings.apis.tpdsworker.url}/enqueue/web_to_tpds_http_requests`,
  50. json: {
  51. group,
  52. method,
  53. job
  54. },
  55. method: 'post',
  56. timeout: 5 * 1000
  57. }
  58. return request(opts, function(err) {
  59. if (err != null) {
  60. logger.err(
  61. { err },
  62. 'error queuing something in the tpdsworker, continuing anyway'
  63. )
  64. return callback()
  65. } else {
  66. logger.log({ group, job }, 'successfully queued up job for tpdsworker')
  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. logger.log(
  185. {
  186. project_id: options.project_id,
  187. user_id,
  188. startPath,
  189. endPath,
  190. uri: options.uri
  191. },
  192. 'moving entity in third party data store'
  193. )
  194. const moveOptions = {
  195. method: 'put',
  196. title: 'moveEntity',
  197. uri: `${tpdsUrl}/user/${user_id}/entity`,
  198. headers: {
  199. sl_project_id: options.project_id,
  200. sl_entity_rev: options.rev,
  201. sl_all_user_ids: JSON.stringify(allUserIds)
  202. },
  203. json: {
  204. user_id,
  205. endPath,
  206. startPath
  207. }
  208. }
  209. return TpdsUpdateSender._enqueue(
  210. options.project_id,
  211. 'standardHttpRequest',
  212. moveOptions,
  213. callback
  214. )
  215. })
  216. },
  217. deleteEntity(options, callback) {
  218. if (callback == null) {
  219. callback = function(err) {}
  220. }
  221. metrics.inc('tpds.delete-entity')
  222. return getProjectsUsersIds(options.project_id, function(
  223. err,
  224. user_id,
  225. allUserIds
  226. ) {
  227. logger.log(
  228. {
  229. project_id: options.project_id,
  230. user_id,
  231. path: options.path,
  232. uri: options.uri
  233. },
  234. 'deleting entity in third party data store'
  235. )
  236. const deleteOptions = {
  237. method: 'DELETE',
  238. headers: {
  239. sl_project_id: options.project_id,
  240. sl_all_user_ids: JSON.stringify(allUserIds)
  241. },
  242. uri: `${tpdsUrl}${buildPath(
  243. user_id,
  244. options.project_name,
  245. options.path
  246. )}`,
  247. title: 'deleteEntity',
  248. sl_all_user_ids: JSON.stringify(allUserIds)
  249. }
  250. return TpdsUpdateSender._enqueue(
  251. options.project_id,
  252. 'standardHttpRequest',
  253. deleteOptions,
  254. callback
  255. )
  256. })
  257. },
  258. pollDropboxForUser(user_id, callback) {
  259. if (callback == null) {
  260. callback = function(err) {}
  261. }
  262. metrics.inc('tpds.poll-dropbox')
  263. logger.log({ user_id }, 'polling dropbox for user')
  264. const options = {
  265. method: 'POST',
  266. uri: `${tpdsUrl}/user/poll`,
  267. json: {
  268. user_ids: [user_id]
  269. }
  270. }
  271. return TpdsUpdateSender._enqueue(
  272. `poll-dropbox:${user_id}`,
  273. 'standardHttpRequest',
  274. options,
  275. callback
  276. )
  277. }
  278. }
  279. var getProjectsUsersIds = function(project_id, callback) {
  280. if (callback == null) {
  281. callback = function(err, owner_id, allUserIds) {}
  282. }
  283. return ProjectGetter.getProject(
  284. project_id,
  285. { _id: true, owner_ref: true },
  286. function(err, project) {
  287. if (err != null) {
  288. return callback(err)
  289. }
  290. return CollaboratorsHandler.getInvitedMemberIds(project_id, function(
  291. err,
  292. member_ids
  293. ) {
  294. if (err != null) {
  295. return callback(err)
  296. }
  297. return callback(
  298. err,
  299. project != null ? project.owner_ref : undefined,
  300. member_ids
  301. )
  302. })
  303. }
  304. )
  305. }
  306. var mergeProjectNameAndPath = function(project_name, path) {
  307. if (path.indexOf('/') === 0) {
  308. path = path.substring(1)
  309. }
  310. const fullPath = `/${project_name}/${path}`
  311. return fullPath
  312. }