Browse Source

Merge pull request #10 from sharelatex/hof-history-apis

Add User and Project endpoints by overleaf ids
Hayden Faulds 9 years ago
parent
commit
a9b18e4435

+ 7 - 3
services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee

@@ -9,7 +9,7 @@ Errors = require("../Errors/Errors")
 
 
 module.exports = ProjectDetailsHandler =
 module.exports = ProjectDetailsHandler =
 	getDetails: (project_id, callback)->
 	getDetails: (project_id, callback)->
-		ProjectGetter.getProject project_id, {name:true, description:true, compiler:true, features:true, owner_ref:true}, (err, project)->
+		ProjectGetter.getProject project_id, {name:true, description:true, compiler:true, features:true, owner_ref:true, overleaf:true}, (err, project)->
 			if err?
 			if err?
 				logger.err err:err, project_id:project_id, "error getting project"
 				logger.err err:err, project_id:project_id, "error getting project"
 				return callback(err)
 				return callback(err)
@@ -21,7 +21,11 @@ module.exports = ProjectDetailsHandler =
 					description: project.description
 					description: project.description
 					compiler: project.compiler
 					compiler: project.compiler
 					features: user.features
 					features: user.features
-				logger.log project_id:project_id, details:details, "getting project details"
+
+				if project.overleaf?
+					details.overleaf = project.overleaf
+
+				logger.log project_id:project_id, details: details, "getting project details"
 				callback(err, details)
 				callback(err, details)
 
 
 	getProjectDescription: (project_id, callback)->
 	getProjectDescription: (project_id, callback)->
@@ -66,4 +70,4 @@ module.exports = ProjectDetailsHandler =
 		logger.log project_id: project_id, level: newAccessLevel, "set public access level"
 		logger.log project_id: project_id, level: newAccessLevel, "set public access level"
 		if project_id? && newAccessLevel? and _.include [PublicAccessLevels.READ_ONLY, PublicAccessLevels.READ_AND_WRITE, PublicAccessLevels.PRIVATE], newAccessLevel
 		if project_id? && newAccessLevel? and _.include [PublicAccessLevels.READ_ONLY, PublicAccessLevels.READ_AND_WRITE, PublicAccessLevels.PRIVATE], newAccessLevel
 			Project.update {_id:project_id},{publicAccesLevel:newAccessLevel}, (err)->
 			Project.update {_id:project_id},{publicAccesLevel:newAccessLevel}, (err)->
-				callback()
+				callback()

+ 12 - 2
services/web/app/coffee/Features/User/UserInfoController.coffee

@@ -4,6 +4,7 @@ UserDeleter = require("./UserDeleter")
 UserUpdater = require("./UserUpdater")
 UserUpdater = require("./UserUpdater")
 sanitize = require('sanitizer')
 sanitize = require('sanitizer')
 AuthenticationController = require('../Authentication/AuthenticationController')
 AuthenticationController = require('../Authentication/AuthenticationController')
+ObjectId = require("mongojs").ObjectId
 
 
 module.exports = UserController =
 module.exports = UserController =
 	getLoggedInUsersPersonalInfo: (req, res, next = (error) ->) ->
 	getLoggedInUsersPersonalInfo: (req, res, next = (error) ->) ->
@@ -19,8 +20,17 @@ module.exports = UserController =
 			UserController.sendFormattedPersonalInfo(user, res, next)
 			UserController.sendFormattedPersonalInfo(user, res, next)
 
 
 	getPersonalInfo: (req, res, next = (error) ->) ->
 	getPersonalInfo: (req, res, next = (error) ->) ->
-		UserGetter.getUser req.params.user_id, { _id: true, first_name: true, last_name: true, email: true}, (error, user) ->
-			logger.log user_id: req.params.user_id, "reciving request for getting users personal info"
+		{user_id} = req.params
+
+		if user_id.match(/^\d+$/)
+			query = { "overleaf.id": parseInt(user_id, 10) }
+		else if user_id.match(/^[a-f0-9]{24}$/)
+			query = { _id: ObjectId(user_id) }
+		else
+			return res.send(400)
+
+		UserGetter.getUser query, { _id: true, first_name: true, last_name: true, email: true}, (error, user) ->
+			logger.log user_id: req.params.user_id, "receiving request for getting users personal info"
 			return next(error) if error?
 			return next(error) if error?
 			return res.send(404) if !user?
 			return res.send(404) if !user?
 			UserController.sendFormattedPersonalInfo(user, res, next)
 			UserController.sendFormattedPersonalInfo(user, res, next)

+ 12 - 5
services/web/test/UnitTests/coffee/Project/ProjectDetailsHandlerTests.coffee

@@ -12,7 +12,7 @@ describe 'ProjectDetailsHandler', ->
 	beforeEach ->
 	beforeEach ->
 		@project_id = "321l3j1kjkjl"
 		@project_id = "321l3j1kjkjl"
 		@user_id = "user-id-123"
 		@user_id = "user-id-123"
-		@project = 
+		@project =
 			name: "project"
 			name: "project"
 			description: "this is a great project"
 			description: "this is a great project"
 			something:"should not exist"
 			something:"should not exist"
@@ -20,7 +20,7 @@ describe 'ProjectDetailsHandler', ->
 			owner_ref: @user_id
 			owner_ref: @user_id
 		@user =
 		@user =
 			features: "mock-features"
 			features: "mock-features"
-		@ProjectGetter = 
+		@ProjectGetter =
 			getProjectWithoutDocLines: sinon.stub().callsArgWith(1, null, @project)
 			getProjectWithoutDocLines: sinon.stub().callsArgWith(1, null, @project)
 			getProject: sinon.stub().callsArgWith(2, null, @project)
 			getProject: sinon.stub().callsArgWith(2, null, @project)
 		@ProjectModel =
 		@ProjectModel =
@@ -42,7 +42,7 @@ describe 'ProjectDetailsHandler', ->
 	describe "getDetails", ->
 	describe "getDetails", ->
 
 
 		it "should find the project and owner", (done)->
 		it "should find the project and owner", (done)->
-			@handler.getDetails @project_id, (err, details)=>				
+			@handler.getDetails @project_id, (err, details)=>
 				details.name.should.equal @project.name
 				details.name.should.equal @project.name
 				details.description.should.equal @project.description
 				details.description.should.equal @project.description
 				details.compiler.should.equal @project.compiler
 				details.compiler.should.equal @project.compiler
@@ -50,6 +50,13 @@ describe 'ProjectDetailsHandler', ->
 				assert.equal(details.something, undefined)
 				assert.equal(details.something, undefined)
 				done()
 				done()
 
 
+		it "should find overleaf metadata if it exists", (done)->
+			@project.overleaf = { id: 'id' }
+			@handler.getDetails @project_id, (err, details)=>
+				details.overleaf.should.equal @project.overleaf
+				assert.equal(details.something, undefined)
+				done()
+
 		it "should return an error for a non-existent project", (done)->
 		it "should return an error for a non-existent project", (done)->
 			@ProjectGetter.getProject.callsArg(2, null, null)
 			@ProjectGetter.getProject.callsArg(2, null, null)
 			err = new Errors.NotFoundError("project not found")
 			err = new Errors.NotFoundError("project not found")
@@ -79,7 +86,7 @@ describe 'ProjectDetailsHandler', ->
 			@handler.getProjectDescription @project_id, (returnedErr, returnedDescription)=>
 			@handler.getProjectDescription @project_id, (returnedErr, returnedDescription)=>
 				err.should.equal returnedErr
 				err.should.equal returnedErr
 				description.should.equal returnedDescription
 				description.should.equal returnedDescription
-				done()	
+				done()
 
 
 	describe "setProjectDescription", ->
 	describe "setProjectDescription", ->
 
 
@@ -110,7 +117,7 @@ describe 'ProjectDetailsHandler', ->
 			@handler.renameProject @project_id, @newName, =>
 			@handler.renameProject @project_id, @newName, =>
 				@tpdsUpdateSender.moveEntity.calledWith({project_id:@project_id, project_name:@project.name, newProjectName:@newName}).should.equal true
 				@tpdsUpdateSender.moveEntity.calledWith({project_id:@project_id, project_name:@project.name, newProjectName:@newName}).should.equal true
 				done()
 				done()
-		
+
 		it "should not do anything with an invalid name", (done) ->
 		it "should not do anything with an invalid name", (done) ->
 			@handler.validateProjectName = sinon.stub().yields(new Error("invalid name"))
 			@handler.validateProjectName = sinon.stub().yields(new Error("invalid name"))
 			@handler.renameProject @project_id, @newName, =>
 			@handler.renameProject @project_id, @newName, =>

+ 47 - 12
services/web/test/UnitTests/coffee/User/UserInfoControllerTests.coffee

@@ -12,9 +12,9 @@ ObjectId = require("mongojs").ObjectId
 
 
 describe "UserInfoController", ->
 describe "UserInfoController", ->
 	beforeEach ->
 	beforeEach ->
-		@UserDeleter = 
+		@UserDeleter =
 			deleteUser: sinon.stub().callsArgWith(1)
 			deleteUser: sinon.stub().callsArgWith(1)
-		@UserUpdater = 
+		@UserUpdater =
 			updatePersonalInfo: sinon.stub()
 			updatePersonalInfo: sinon.stub()
 		@sanitizer = escape:(v)->v
 		@sanitizer = escape:(v)->v
 		sinon.spy @sanitizer, "escape"
 		sinon.spy @sanitizer, "escape"
@@ -50,23 +50,47 @@ describe "UserInfoController", ->
 				.should.equal true
 				.should.equal true
 
 
 	describe "getPersonalInfo", ->
 	describe "getPersonalInfo", ->
-		beforeEach ->
-			@user_id = ObjectId().toString()
-			@user =
-				_id: ObjectId(@user_id)
-			@req.params = user_id: @user_id
-
-		describe "when the user exists", ->
+		describe "when the user exists with sharelatex id", ->
 			beforeEach ->
 			beforeEach ->
+				@user_id = ObjectId().toString()
+				@user =
+					_id: ObjectId(@user_id)
+				@req.params = user_id: @user_id
 				@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
 				@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
 				@UserInfoController.sendFormattedPersonalInfo = sinon.stub()
 				@UserInfoController.sendFormattedPersonalInfo = sinon.stub()
 				@UserInfoController.getPersonalInfo(@req, @res, @next)
 				@UserInfoController.getPersonalInfo(@req, @res, @next)
 
 
 			it "should look up the user in the database", ->
 			it "should look up the user in the database", ->
 				@UserGetter.getUser
 				@UserGetter.getUser
-					.calledWith(@user_id, { _id: true, first_name: true, last_name: true, email: true })
+					.calledWith(
+						{ _id: ObjectId(@user_id) },
+						{ _id: true, first_name: true, last_name: true, email: true }
+					).should.equal true
+
+			it "should send the formatted details back to the client", ->
+				@UserInfoController.sendFormattedPersonalInfo
+					.calledWith(@user, @res, @next)
 					.should.equal true
 					.should.equal true
-				
+
+		describe "when the user exists with overleaf id", ->
+			beforeEach ->
+				@user_id = 12345
+				@user =
+					_id: ObjectId()
+					overleaf:
+						id: @user_id
+				@req.params = user_id: @user_id.toString()
+				@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
+				@UserInfoController.sendFormattedPersonalInfo = sinon.stub()
+				@UserInfoController.getPersonalInfo(@req, @res, @next)
+
+			it "should look up the user in the database", ->
+				@UserGetter.getUser
+					.calledWith(
+						{ "overleaf.id": @user_id },
+						{ _id: true, first_name: true, last_name: true, email: true }
+					).should.equal true
+
 			it "should send the formatted details back to the client", ->
 			it "should send the formatted details back to the client", ->
 				@UserInfoController.sendFormattedPersonalInfo
 				@UserInfoController.sendFormattedPersonalInfo
 					.calledWith(@user, @res, @next)
 					.calledWith(@user, @res, @next)
@@ -74,13 +98,24 @@ describe "UserInfoController", ->
 
 
 		describe "when the user does not exist", ->
 		describe "when the user does not exist", ->
 			beforeEach ->
 			beforeEach ->
+				@user_id = ObjectId().toString()
+				@req.params = user_id: @user_id
 				@UserGetter.getUser = sinon.stub().callsArgWith(2, null, null)
 				@UserGetter.getUser = sinon.stub().callsArgWith(2, null, null)
-				@UserInfoController.sendFormattedPersonalInfo = sinon.stub()
 				@UserInfoController.getPersonalInfo(@req, @res, @next)
 				@UserInfoController.getPersonalInfo(@req, @res, @next)
 
 
 			it "should return 404 to the client", ->
 			it "should return 404 to the client", ->
 				@res.statusCode.should.equal 404
 				@res.statusCode.should.equal 404
 
 
+		describe "when the user id is invalid", ->
+			beforeEach ->
+				@user_id = "invalid"
+				@req.params = user_id: @user_id
+				@UserGetter.getUser = sinon.stub().callsArgWith(2, null, null)
+				@UserInfoController.getPersonalInfo(@req, @res, @next)
+
+			it "should return 400 to the client", ->
+				@res.statusCode.should.equal 400
+
 	describe "sendFormattedPersonalInfo", ->
 	describe "sendFormattedPersonalInfo", ->
 		beforeEach ->
 		beforeEach ->
 			@user =
 			@user =