2018-06-08 11:06:47 -04:00
|
|
|
AuthorizationManager = require('../Authorization/AuthorizationManager')
|
|
|
|
ProjectGetter = require('../Project/ProjectGetter')
|
|
|
|
Settings = require 'settings-sharelatex'
|
|
|
|
CompileManager = require '../Compile/CompileManager'
|
2018-06-15 11:20:55 -04:00
|
|
|
ClsiManager = require '../Compile/ClsiManager'
|
2018-06-14 07:27:20 -04:00
|
|
|
ProjectFileAgent = require './ProjectFileAgent'
|
2018-06-08 11:06:47 -04:00
|
|
|
_ = require "underscore"
|
2018-06-21 06:40:16 -04:00
|
|
|
{
|
|
|
|
BadDataError,
|
|
|
|
AccessDeniedError,
|
|
|
|
BadEntityTypeError,
|
|
|
|
OutputFileFetchFailedError
|
|
|
|
} = require './LinkedFilesErrors'
|
2018-06-20 05:01:03 -04:00
|
|
|
LinkedFilesHandler = require './LinkedFilesHandler'
|
|
|
|
logger = require 'logger-sharelatex'
|
2018-06-08 11:06:47 -04:00
|
|
|
|
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
module.exports = ProjectOutputFileAgent = {
|
2018-06-08 11:06:47 -04:00
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
_prepare: (project_id, linkedFileData, user_id, callback=(err, linkedFileData)->) ->
|
|
|
|
@_checkAuth project_id, linkedFileData, user_id, (err, allowed) =>
|
|
|
|
return callback(err) if err?
|
2018-06-21 06:40:16 -04:00
|
|
|
return callback(new AccessDeniedError()) if !allowed
|
2018-06-20 05:01:03 -04:00
|
|
|
@_decorateLinkedFileData linkedFileData, (err, newLinkedFileData) =>
|
|
|
|
return callback(err) if err?
|
|
|
|
if !@_validate(newLinkedFileData)
|
|
|
|
return callback(new BadDataError())
|
|
|
|
callback(null, newLinkedFileData)
|
2018-06-08 11:06:47 -04:00
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
createLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
|
|
|
|
if !@_canCreate(linkedFileData)
|
2018-06-21 06:40:16 -04:00
|
|
|
return callback(new AccessDeniedError())
|
2018-06-20 05:01:03 -04:00
|
|
|
linkedFileData = @_sanitizeData(linkedFileData)
|
|
|
|
@_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
|
|
|
|
return callback(err) if err?
|
|
|
|
@_getFileStream linkedFileData, user_id, (err, readStream) =>
|
|
|
|
return callback(err) if err?
|
|
|
|
readStream.on "error", callback
|
|
|
|
readStream.on "response", (response) =>
|
|
|
|
if 200 <= response.statusCode < 300
|
|
|
|
readStream.resume()
|
|
|
|
LinkedFilesHandler.importFromStream project_id,
|
|
|
|
readStream,
|
|
|
|
linkedFileData,
|
|
|
|
name,
|
|
|
|
parent_folder_id,
|
|
|
|
user_id,
|
|
|
|
(err, file) ->
|
|
|
|
return callback(err) if err?
|
|
|
|
callback(null, file._id) # Created
|
|
|
|
else
|
2018-06-21 06:40:16 -04:00
|
|
|
err = new OutputFileFetchFailedError(
|
2018-06-20 05:01:03 -04:00
|
|
|
"Output file fetch failed: #{linkedFileData.build_id}, #{linkedFileData.source_output_file_path}"
|
|
|
|
)
|
|
|
|
err.statusCode = response.statusCode
|
|
|
|
callback(err)
|
|
|
|
|
|
|
|
refreshLinkedFile: (project_id, linkedFileData, name, parent_folder_id, user_id, callback) ->
|
|
|
|
@_prepare project_id, linkedFileData, user_id, (err, linkedFileData) =>
|
|
|
|
return callback(err) if err?
|
|
|
|
@_compileAndGetFileStream linkedFileData, user_id, (err, readStream, new_build_id) =>
|
|
|
|
return callback(err) if err?
|
|
|
|
readStream.on "error", callback
|
|
|
|
readStream.on "response", (response) =>
|
|
|
|
if 200 <= response.statusCode < 300
|
|
|
|
readStream.resume()
|
|
|
|
linkedFileData.build_id = new_build_id
|
|
|
|
LinkedFilesHandler.importFromStream project_id,
|
|
|
|
readStream,
|
|
|
|
linkedFileData,
|
|
|
|
name,
|
|
|
|
parent_folder_id,
|
|
|
|
user_id,
|
|
|
|
(err, file) ->
|
|
|
|
return callback(err) if err?
|
|
|
|
callback(null, file._id) # Created
|
|
|
|
else
|
2018-06-21 06:40:16 -04:00
|
|
|
err = new OutputFileFetchFailedError(
|
2018-06-20 05:01:03 -04:00
|
|
|
"Output file fetch failed: #{linkedFileData.build_id}, #{linkedFileData.source_output_file_path}"
|
|
|
|
)
|
|
|
|
err.statusCode = response.statusCode
|
|
|
|
callback(err)
|
2018-06-08 11:06:47 -04:00
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
|
|
|
|
_sanitizeData: (data) ->
|
2018-06-08 11:06:47 -04:00
|
|
|
return {
|
2018-06-20 05:01:03 -04:00
|
|
|
provider: data.provider,
|
2018-06-08 11:06:47 -04:00
|
|
|
source_project_id: data.source_project_id,
|
2018-06-20 05:01:03 -04:00
|
|
|
source_output_file_path: data.source_output_file_path,
|
|
|
|
build_id: data.build_id
|
2018-06-08 11:06:47 -04:00
|
|
|
}
|
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
_canCreate: ProjectFileAgent._canCreate
|
2018-06-08 11:06:47 -04:00
|
|
|
|
2018-06-14 07:27:20 -04:00
|
|
|
_getSourceProject: ProjectFileAgent._getSourceProject
|
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
_decorateLinkedFileData: ProjectFileAgent._decorateLinkedFileData
|
2018-06-14 07:27:20 -04:00
|
|
|
|
|
|
|
_validate: (data) ->
|
|
|
|
return (
|
|
|
|
(data.source_project_id? || data.v1_source_doc_id?) &&
|
2018-06-20 05:01:03 -04:00
|
|
|
data.source_output_file_path? &&
|
|
|
|
data.build_id?
|
2018-06-14 07:27:20 -04:00
|
|
|
)
|
2018-06-08 11:06:47 -04:00
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
_checkAuth: (project_id, data, current_user_id, callback = (err, allowed)->) ->
|
2018-06-08 11:06:47 -04:00
|
|
|
callback = _.once(callback)
|
2018-06-20 05:01:03 -04:00
|
|
|
if !@_validate(data)
|
2018-06-21 06:40:16 -04:00
|
|
|
return callback(new BadDataError())
|
2018-06-14 07:27:20 -04:00
|
|
|
@_getSourceProject data, (err, project) ->
|
2018-06-08 11:06:47 -04:00
|
|
|
return callback(err) if err?
|
2018-06-20 05:01:03 -04:00
|
|
|
AuthorizationManager.canUserReadProject current_user_id,
|
|
|
|
project._id,
|
|
|
|
null,
|
|
|
|
(err, canRead) ->
|
|
|
|
return callback(err) if err?
|
|
|
|
callback(null, canRead)
|
2018-06-08 11:06:47 -04:00
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
_getFileStream: (linkedFileData, user_id, callback=(err, fileStream)->) ->
|
2018-06-08 11:06:47 -04:00
|
|
|
callback = _.once(callback)
|
2018-06-20 05:01:03 -04:00
|
|
|
{ source_output_file_path, build_id } = linkedFileData
|
|
|
|
@_getSourceProject linkedFileData, (err, project) ->
|
2018-06-08 11:06:47 -04:00
|
|
|
return callback(err) if err?
|
2018-06-14 07:27:20 -04:00
|
|
|
source_project_id = project._id
|
2018-06-20 05:01:03 -04:00
|
|
|
ClsiManager.getOutputFileStream source_project_id,
|
|
|
|
user_id,
|
|
|
|
build_id,
|
|
|
|
source_output_file_path,
|
|
|
|
(err, readStream) ->
|
2018-06-14 07:27:20 -04:00
|
|
|
return callback(err) if err?
|
2018-06-15 11:20:55 -04:00
|
|
|
readStream.pause()
|
2018-06-20 05:01:03 -04:00
|
|
|
callback(null, readStream)
|
2018-06-08 11:06:47 -04:00
|
|
|
|
2018-06-20 05:01:03 -04:00
|
|
|
_compileAndGetFileStream: (linkedFileData, user_id, callback=(err, stream, build_id)->) ->
|
|
|
|
callback = _.once(callback)
|
|
|
|
{ source_output_file_path } = linkedFileData
|
|
|
|
@_getSourceProject linkedFileData, (err, project) ->
|
|
|
|
return callback(err) if err?
|
|
|
|
source_project_id = project._id
|
|
|
|
CompileManager.compile source_project_id,
|
|
|
|
user_id,
|
|
|
|
{},
|
|
|
|
(err, status, outputFiles) ->
|
|
|
|
return callback(err) if err?
|
|
|
|
if status != 'success'
|
2018-06-21 06:40:16 -04:00
|
|
|
return callback(new OutputFileFetchFailedError())
|
2018-06-20 05:01:03 -04:00
|
|
|
outputFile = _.find(
|
|
|
|
outputFiles,
|
|
|
|
(o) => o.path == source_output_file_path
|
|
|
|
)
|
|
|
|
if !outputFile?
|
2018-06-21 06:40:16 -04:00
|
|
|
return callback(new OutputFileFetchFailedError())
|
2018-06-20 05:01:03 -04:00
|
|
|
build_id = outputFile.build
|
|
|
|
ClsiManager.getOutputFileStream source_project_id,
|
|
|
|
user_id,
|
|
|
|
build_id,
|
|
|
|
source_output_file_path,
|
|
|
|
(err, readStream) ->
|
|
|
|
return callback(err) if err?
|
|
|
|
readStream.pause()
|
|
|
|
callback(null, readStream, build_id)
|
2018-06-08 11:06:47 -04:00
|
|
|
}
|