Shane Kilkelly 9 лет назад
Родитель
Сommit
81170d472d

+ 61 - 0
services/web/app/coffee/Features/TokenAccess/TokenAccessController.coffee

@@ -0,0 +1,61 @@
+ProjectGetter = require "../Project/ProjectGetter"
+ProjectEditorHandler = require "../Project/ProjectEditorHandler"
+UserGetter = require "../User/UserGetter"
+AuthenticationController = require '../Authentication/AuthenticationController'
+logger = require 'logger-sharelatex'
+TokenAccessHandler = require './TokenAccessHandler'
+
+
+module.exports = TokenAccessController =
+
+	readAndWriteToken: (req, res, next) ->
+		userId = AuthenticationController.getLoggedInUserId(req)
+		token = req.params['read_and_write_token']
+		logger.log {userId, token}, "requesting read-and-write token access"
+		TokenAccessHandler.findProjectWithReadAndWriteToken token, (err, project) ->
+			if err?
+				logger.err {err, token, userId},
+					"error getting project by readAndWrite token"
+				return next(err)
+			if !project?
+				logger.log {token, userId},
+					"no project found for readAndWrite token"
+				return res.sendStatus(404)
+			logger.log {userId, projectId: project._id},
+				"adding user to project with readAndWrite token"
+			TokenAccessHandler.addReadAndWriteUserToProject userId, project._id, (err) ->
+				if err?
+					logger.err {err, token, userId, projectId: project._id},
+						"error adding user to project with readAndWrite token"
+					return next(err)
+				return res.redirect("/project/#{project._id}")
+
+	readOnlyToken: (req, res, next) ->
+		userId = AuthenticationController.getLoggedInUserId(req)
+		token = req.params['read_only_token']
+		logger.log {userId, token}, "requesting read-only token access"
+		TokenAccessHandler.findProjectWithReadOnlyToken token, (err, project) ->
+			if err?
+				logger.err {err, token, user_id: currentUserId},
+					"error getting project by readOnly token"
+				return next(err)
+			if !project?
+				logger.log {token, userId},
+					"no project found for readAndWrite token"
+				return res.sendStatus(404)
+			if !userId?
+				logger.log {userId, projectId: project._id},
+					"adding anonymous user to project with readOnly token"
+				TokenAccessHandler.grantAnonymousUserTokenAccessViaSession(req, project._id)
+				return res.redirect("/project/#{project._id}")
+			else
+				logger.log {userId, projectId: project._id},
+					"adding user to project with readOnly token"
+				TokenAccessHandler.addReadOnlyUserToProject userId, project._id, (err) ->
+					if err?
+						logger.err {err, token, userId, projectId: project._id},
+							"error adding user to project with readAndWrite token"
+						return next(err)
+					res.redirect("/project/#{project._id}")
+
+

+ 54 - 0
services/web/app/coffee/Features/TokenAccess/TokenAccessHandler.coffee

@@ -0,0 +1,54 @@
+ProjectGetter = require '../Project/ProjectGetter'
+Project = require('../../models/Project').Project
+AuthenticationController = require '../Authentication/AuthenticationController'
+PublicAccessLevels = require '../Authorization/PublicAccessLevels'
+ObjectId = require("mongojs").ObjectId
+
+module.exports = TokenAccessHandler =
+
+	findProjectWithReadOnlyToken: (token, callback=(err, project)->) ->
+		Project.findOne {
+			'tokens.readOnly': token,
+			'publicAccesLevel': PublicAccessLevels.TOKEN_BASED
+		}, {_id: 1}, (err, project) ->
+			return callback(err) if err?
+			callback(null, project)
+
+	findProjectWithReadAndWriteToken: (token, callback=(err, project)->) ->
+		Project.findOne {
+			'tokens.readAndWrite': token,
+			'publicAccesLevel': PublicAccessLevels.TOKEN_BASED
+		}, {_id: 1}, (err, project) ->
+			return callback(err) if err?
+			callback(null, project)
+
+	addReadOnlyUserToProject: (userId, projectId, callback=(err)->) ->
+		userId = ObjectId(userId.toString())
+		projectId = ObjectId(projectId.toString())
+		Project.update {
+			_id: projectId
+		}, {
+			$addToSet: {tokenAccessReadOnly_refs: userId}
+		}, (err) ->
+			callback(err)
+
+	addReadAndWriteUserToProject: (userId, projectId, callback=(err)->) ->
+		userId = ObjectId(userId.toString())
+		projectId = ObjectId(projectId.toString())
+		Project.update {
+			_id: projectId
+		}, {
+			$addToSet: {tokenAccessReadAndWrite_refs: userId}
+		}, (err) ->
+			callback(err)
+
+	grantAnonymousUserTokenAccessViaSession: (req, projectId) ->
+		if req.session?
+			if !req.session.anonReadOnlyTokenAccess?
+				req.session.anonReadOnlyTokenAccess = {}
+			req.session.anonReadOnlyTokenAccess[projectId.toString()] = true
+
+	anonymousUserHasTokenAccessViaSession: (req, projectId) ->
+		req?.session?.anonReadOnlyTokenAccess?[projectId.toString()] == true
+
+

+ 9 - 0
services/web/app/coffee/router.coffee

@@ -44,6 +44,7 @@ SudoModeMiddlewear = require('./Features/SudoMode/SudoModeMiddlewear')
 AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
 AnnouncementsController = require("./Features/Announcements/AnnouncementsController")
 LabelsController = require('./Features/Labels/LabelsController')
+TokenAccessController = require('./Features/TokenAccess/TokenAccessController')
 
 logger = require("logger-sharelatex")
 _ = require("underscore")
@@ -337,4 +338,12 @@ module.exports = class Router
 			metrics.inc("client-side-error")
 			res.sendStatus(204)
 
+
+		webRouter.get '/read/:read_only_token([a-z]+)',
+			TokenAccessController.readOnlyToken
+
+		webRouter.get '/:read_and_write_token([0-9]+[a-z]+)',
+			AuthenticationController.requireLogin(),
+			TokenAccessController.readAndWriteToken
+
 		webRouter.get '*', ErrorController.notFound