Przeglądaj źródła

made ProjectGetter.getProject more robust

it can deal with multiple types of query better, including mongoose ids which are not being matched like mongojs ids.
Henry Oswald 10 lat temu
rodzic
commit
76591ebb23

+ 1 - 0
services/web/app/coffee/Features/Editor/EditorHttpController.coffee

@@ -67,6 +67,7 @@ module.exports = EditorHttpController =
 		project_id = req.params.Project_id
 		project_id = req.params.Project_id
 		name = req.body.name
 		name = req.body.name
 		parent_folder_id = req.body.parent_folder_id
 		parent_folder_id = req.body.parent_folder_id
+		logger.log project_id:project_id, name:name, parent_folder_id:parent_folder_id, "getting request to add doc to project"
 		if !EditorHttpController._nameIsAcceptableLength(name)
 		if !EditorHttpController._nameIsAcceptableLength(name)
 			return res.sendStatus 400
 			return res.sendStatus 400
 		EditorController.addDoc project_id, parent_folder_id, name, [], "editor", (error, doc) ->
 		EditorController.addDoc project_id, parent_folder_id, name, [], "editor", (error, doc) ->

+ 22 - 17
services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee

@@ -110,21 +110,22 @@ module.exports = ProjectEntityHandler =
 		DocstoreManager.getDoc project_id, doc_id, options, callback
 		DocstoreManager.getDoc project_id, doc_id, options, callback
 
 
 	addDoc: (project_or_id, folder_id, docName, docLines, callback = (error, doc, folder_id) ->)=>
 	addDoc: (project_or_id, folder_id, docName, docLines, callback = (error, doc, folder_id) ->)=>
-		ProjectGetter.getProjectWithOnlyFolders project_or_id, (err, project) ->
-			logger.log project: project._id, folder_id: folder_id, doc_name: docName, "adding doc"
+		ProjectGetter.getProjectWithoutDocLines project_or_id, (err, project) ->
 			return callback(err) if err?
 			return callback(err) if err?
+			logger.log project_id: project._id, folder_id: folder_id, doc_name: docName, "adding doc to project"
 			confirmFolder project, folder_id, (folder_id)=>
 			confirmFolder project, folder_id, (folder_id)=>
 				doc = new Doc name: docName
 				doc = new Doc name: docName
 				# Put doc in docstore first, so that if it errors, we don't have a doc_id in the project
 				# Put doc in docstore first, so that if it errors, we don't have a doc_id in the project
 				# which hasn't been created in docstore.
 				# which hasn't been created in docstore.
 				DocstoreManager.updateDoc project._id.toString(), doc._id.toString(), docLines, (err, modified, rev) ->
 				DocstoreManager.updateDoc project._id.toString(), doc._id.toString(), docLines, (err, modified, rev) ->
 					return callback(err) if err? 
 					return callback(err) if err? 
+
 					ProjectEntityHandler._putElement project._id, folder_id, doc, "doc", (err, result)=>
 					ProjectEntityHandler._putElement project._id, folder_id, doc, "doc", (err, result)=>
 						return callback(err) if err?
 						return callback(err) if err?
 						tpdsUpdateSender.addDoc {
 						tpdsUpdateSender.addDoc {
-							project_id:   project._id,
-							doc_id:		  doc._id	
-							path:         result.path.fileSystem,
+							project_id:   project?._id,
+							doc_id:		  doc?._id	
+							path:         result?.path?.fileSystem,
 							project_name: project.name,
 							project_name: project.name,
 							rev:          0
 							rev:          0
 						}, (err) ->
 						}, (err) ->
@@ -182,7 +183,7 @@ module.exports = ProjectEntityHandler =
 							callback()
 							callback()
 
 
 	copyFileFromExistingProject: (project_or_id, folder_id, originalProject_id, origonalFileRef, callback = (error, fileRef, folder_id) ->)->
 	copyFileFromExistingProject: (project_or_id, folder_id, originalProject_id, origonalFileRef, callback = (error, fileRef, folder_id) ->)->
-		ProjectGetter.getProjectWithOnlyFolders project_or_id, {name:true}, (err, project) ->
+		ProjectGetter.getProject project_or_id, {name:true}, (err, project) ->
 			logger.log project_id:project._id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "copying file in s3"
 			logger.log project_id:project._id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "copying file in s3"
 			return callback(err) if err?
 			return callback(err) if err?
 			confirmFolder project, folder_id, (folder_id)=>
 			confirmFolder project, folder_id, (folder_id)=>
@@ -194,7 +195,10 @@ module.exports = ProjectEntityHandler =
 					if err?
 					if err?
 						logger.err err:err, project_id:project._id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "error coping file in s3"
 						logger.err err:err, project_id:project._id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "error coping file in s3"
 					ProjectEntityHandler._putElement project._id, folder_id, fileRef, "file", (err, result)=>
 					ProjectEntityHandler._putElement project._id, folder_id, fileRef, "file", (err, result)=>
-						tpdsUpdateSender.addFile {project_id:project._id, file_id:fileRef._id, path:result.path.fileSystem, rev:fileRef.rev, project_name:project.name}, (error) ->
+						if err?
+							logger.err err:err, project_id:project._id, folder_id:folder_id, "error putting element as part of copy"
+							return callback()
+						tpdsUpdateSender.addFile {project_id:project._id, file_id:fileRef._id, path:result?.path?.fileSystem, rev:fileRef.rev, project_name:project.name}, (error) ->
 							callback(error, fileRef, folder_id)
 							callback(error, fileRef, folder_id)
 
 
 	mkdirp: (project_id, path, callback = (err, newlyCreatedFolders, lastFolderInPath)->)->
 	mkdirp: (project_id, path, callback = (err, newlyCreatedFolders, lastFolderInPath)->)->
@@ -240,7 +244,7 @@ module.exports = ProjectEntityHandler =
 		ProjectGetter.getProjectWithOnlyFolders project_or_id, (err, project)=>
 		ProjectGetter.getProjectWithOnlyFolders project_or_id, (err, project)=>
 			return callback(err) if err?
 			return callback(err) if err?
 			confirmFolder project, parentFolder_id, (parentFolder_id)=>
 			confirmFolder project, parentFolder_id, (parentFolder_id)=>
-				logger.log project: project_id, parentFolder_id:parentFolder_id, folderName:folderName, "new folder added"
+				logger.log project: project._id, parentFolder_id:parentFolder_id, folderName:folderName, "new folder added"
 				ProjectEntityHandler._putElement project._id, parentFolder_id, folder, "folder", (err, result)=>
 				ProjectEntityHandler._putElement project._id, parentFolder_id, folder, "folder", (err, result)=>
 					if callback?
 					if callback?
 						callback(err, folder, parentFolder_id)
 						callback(err, folder, parentFolder_id)
@@ -447,7 +451,8 @@ module.exports = ProjectEntityHandler =
 
 
 		countFolder project.rootFolder[0], callback
 		countFolder project.rootFolder[0], callback
 
 
-	_putElement: (project_id, folder_id, element, type, callback = (err, path)->)->
+	_putElement: (project_or_id, folder_id, element, type, callback = (err, path)->)->
+
 		sanitizeTypeOfElement = (elementType)->
 		sanitizeTypeOfElement = (elementType)->
 			lastChar = elementType.slice -1
 			lastChar = elementType.slice -1
 			if lastChar != "s"
 			if lastChar != "s"
@@ -461,32 +466,32 @@ module.exports = ProjectEntityHandler =
 			logger.err project_id:project_id, folder_id:folder_id, element:element, type:type, "failed trying to insert element as it was null"
 			logger.err project_id:project_id, folder_id:folder_id, element:element, type:type, "failed trying to insert element as it was null"
 			return callback(e)
 			return callback(e)
 		type = sanitizeTypeOfElement type
 		type = sanitizeTypeOfElement type
-		ProjectGetter.getProject project_id, {rootFolder:true}, (err, project)=>
+		ProjectGetter.getProject project_or_id, {rootFolder:true}, (err, project)=>
 			if err?
 			if err?
 				return callback(err)
 				return callback(err)
 			if !folder_id?
 			if !folder_id?
 				folder_id = project.rootFolder[0]._id
 				folder_id = project.rootFolder[0]._id
 			ProjectEntityHandler._countElements project, (err, count)->
 			ProjectEntityHandler._countElements project, (err, count)->
 				if count > settings.maxFilesPerProject
 				if count > settings.maxFilesPerProject
-					logger.warn project_id:project_id, "project too big, stopping insertions"
+					logger.warn project_id:project._id, "project too big, stopping insertions"
 					return callback("project_has_to_many_files")
 					return callback("project_has_to_many_files")
 				projectLocator.findElement {project:project, element_id:folder_id, type:"folders"}, (err, folder, path)=>
 				projectLocator.findElement {project:project, element_id:folder_id, type:"folders"}, (err, folder, path)=>
+					if err?
+						logger.err err:err, project_id:project._id, folder_id:folder_id, type:type, element:element, "error finding folder for _putElement"
+						return callback(err)
 					newPath =
 					newPath =
 						fileSystem: "#{path.fileSystem}/#{element.name}"
 						fileSystem: "#{path.fileSystem}/#{element.name}"
 						mongo: path.mongo
 						mongo: path.mongo
-					if err?
-						logger.err err:err, project_id:project_id, folder_id:folder_id, type:type, element:element, "error finding folder for _putElement"
-						return callback(err)
-					logger.log project_id: project_id, element_id: element._id, fileType: type, folder_id: folder_id, "adding element to project"
+					logger.log project_id: project._id, element_id: element._id, fileType: type, folder_id: folder_id, "adding element to project"
 					id = element._id+''
 					id = element._id+''
 					element._id = require('mongoose').Types.ObjectId(id)
 					element._id = require('mongoose').Types.ObjectId(id)
-					conditions = _id:project_id
+					conditions = _id:project._id
 					mongopath = "#{path.mongo}.#{type}"
 					mongopath = "#{path.mongo}.#{type}"
 					update = "$push":{}
 					update = "$push":{}
 					update["$push"][mongopath] = element
 					update["$push"][mongopath] = element
 					Project.update conditions, update, {}, (err)->
 					Project.update conditions, update, {}, (err)->
 						if err?
 						if err?
-							logger.err err: err, project_id: project_id, 'error saving in putElement project'
+							logger.err err: err, project_id: project._id, 'error saving in putElement project'
 							return callback(err)
 							return callback(err)
 						callback(err, {path:newPath})
 						callback(err, {path:newPath})
 
 

+ 22 - 5
services/web/app/coffee/Features/Project/ProjectGetter.coffee

@@ -3,6 +3,9 @@ db = mongojs.db
 ObjectId = mongojs.ObjectId
 ObjectId = mongojs.ObjectId
 async = require "async"
 async = require "async"
 Errors = require("../../errors")
 Errors = require("../../errors")
+logger = require("logger-sharelatex")
+
+
 
 
 module.exports = ProjectGetter =
 module.exports = ProjectGetter =
 	EXCLUDE_DEPTH: 8
 	EXCLUDE_DEPTH: 8
@@ -39,12 +42,26 @@ module.exports = ProjectGetter =
 			db.projects.find _id: ObjectId(project_id.toString()), excludes, (error, projects = []) ->
 			db.projects.find _id: ObjectId(project_id.toString()), excludes, (error, projects = []) ->
 				callback error, projects[0]
 				callback error, projects[0]
 
 
-	getProject: (query, projection, callback = (error, project) ->) ->
+	getProject: (project_or_id, projection, callback = (error, project) ->) ->
+		if !project_or_id?
+			return callback("no id or project provided")
+
+		if typeof(projection) == "function"
+			callback = projection
+
 		ProjectGetter._returnProjectIfPassed project_or_id, callback, (err)->
 		ProjectGetter._returnProjectIfPassed project_or_id, callback, (err)->
-			if typeof query == "string"
-				query = _id: ObjectId(query)
-			else if query instanceof ObjectId
-				query = _id: query
+
+			if typeof project_or_id == "string"
+				query = _id: ObjectId(project_or_id)
+			else if project_or_id instanceof ObjectId
+				query = _id: project_or_id
+			else if project_or_id?.toString().length == 24 # sometimes mongoose ids are hard to identify, this will catch them
+				query = _id:  ObjectId(project_or_id.toString())
+			else
+				err = new Error("malformed get request")
+				logger.log project_or_id:project_or_id, err:err, type:typeof(project_or_id), "malformed get request"
+				return callback(err)
+
 			db.projects.find query, projection, (err, project)->
 			db.projects.find query, projection, (err, project)->
 				if err?
 				if err?
 					logger.err err:err, query:query, projection:projection, "error getting project"
 					logger.err err:err, query:query, projection:projection, "error getting project"

+ 0 - 1
services/web/app/coffee/Features/Spelling/SpellingController.coffee

@@ -12,5 +12,4 @@ module.exports = SpellingController =
 		request(url: Settings.apis.spelling.url + url, method: req.method, headers: req.headers, json: req.body, timeout:TEN_SECONDS)
 		request(url: Settings.apis.spelling.url + url, method: req.method, headers: req.headers, json: req.body, timeout:TEN_SECONDS)
 		.on "error", (error) ->
 		.on "error", (error) ->
 			logger.error err: error, "Spelling API error"
 			logger.error err: error, "Spelling API error"
-			res.sendStatus 500
 		.pipe(res)
 		.pipe(res)

+ 26 - 16
services/web/test/UnitTests/coffee/Project/ProjectGetterTests.coffee

@@ -16,6 +16,9 @@ describe "ProjectGetter", ->
 					projects: {}
 					projects: {}
 					users: {}
 					users: {}
 				ObjectId: ObjectId
 				ObjectId: ObjectId
+			"logger-sharelatex":
+				err:->
+				log:->
 
 
 	describe "getProjectWithoutDocLines", ->
 	describe "getProjectWithoutDocLines", ->
 		beforeEach ->
 		beforeEach ->
@@ -106,30 +109,37 @@ describe "ProjectGetter", ->
 
 
 
 
 
 
-	describe "getProject", ->
+	describe "getProjectaaaaa", ->
 		beforeEach ()->
 		beforeEach ()->
 			@project =
 			@project =
 				_id: @project_id = "56d46b0a1d3422b87c5ebcb1"
 				_id: @project_id = "56d46b0a1d3422b87c5ebcb1"
 			@db.projects.find = sinon.stub().callsArgWith(2, null, [@project])
 			@db.projects.find = sinon.stub().callsArgWith(2, null, [@project])
 
 
 
 
-			it "should call find with the project id when string id is passed", (done)->
-				@ProjectGetter.getProject @project_id, (err, project)=>
-					@db.projects.find.calledWith(_id: ObjectId(@project_id)).should.equal true
-					assert.deepEqual @project, project
-					done()
+		it "should call find with the project id when string id is passed", (done)->
+			@ProjectGetter.getProject @project_id, (err, project)=>
+				@db.projects.find.calledWith(_id: ObjectId(@project_id)).should.equal true
+				assert.deepEqual @project, project
+				done()
 
 
-			it "should call find with the project id when object id is passed", (done)->
-				@ProjectGetter.getProject ObjectId(@project_id), (err, project)=>
-					@db.projects.find.calledWith(_id: ObjectId(@project_id)).should.equal true
-					assert.deepEqual @project, project
-					done()
+		it "should call find with the project id when object id is passed", (done)->
+			@ProjectGetter.getProject ObjectId(@project_id), (err, project)=>
+				@db.projects.find.calledWith(_id: ObjectId(@project_id)).should.equal true
+				assert.deepEqual @project, project
+				done()
 
 
-			it "should not call db when project is passed", (done)->
-				@ProjectGetter.getProject ObjectId(@project_id), (err, project)=>
-					@db.projects.find.called.should.equal false
-					assert.deepEqual @project, project
-					done()
+		it "should not call db when project is passed", (done)->
+			@ProjectGetter.getProject @project, (err, project)=>
+				@db.projects.find.called.should.equal false
+				assert.deepEqual @project, project
+				done()
+
+		it "should call the db when a mongoose objectid is used", (done)->
+			mongooseID = require('mongoose').Types.ObjectId(@project_id)
+			@ProjectGetter.getProject mongooseID, (err, project)=>
+				@db.projects.find.calledWith(_id: ObjectId(@project_id)).should.equal true
+				assert.deepEqual @project, project
+				done()
 
 
 	describe "populateProjectWithUsers", ->
 	describe "populateProjectWithUsers", ->
 		beforeEach ->
 		beforeEach ->