Shane Kilkelly 10 лет назад
Родитель
Сommit
e4f4325150

+ 48 - 0
services/web/app/coffee/Features/Authentication/AuthenticationController.coffee

@@ -16,6 +16,54 @@ module.exports = AuthenticationController =
 	login: (req, res, next = (error) ->) ->
 		AuthenticationController.doLogin req.body, req, res, next
 
+	serializeUser: (user, callback) ->
+		console.log ">> serialize", user._id
+		lightUser =
+			_id: user._id
+			first_name: user.first_name
+			last_name: user.last_name
+			isAdmin: user.isAdmin
+			email: user.email
+			referal_id: user.referal_id
+			session_created: (new Date()).toISOString()
+			ip_address: user._login_req_ip
+		callback(null, lightUser)
+
+	deserializeUser: (user, cb) ->
+		console.log ">> de-serialize", user._id
+		cb(null, user)
+
+	doPassportLogin: (req, username, password, done) ->
+		email = username.toLowerCase()
+		redir = Url.parse(req?.body?.redir or "/project").path
+		console.log ">> doing passport login", username, password, redir
+		LoginRateLimiter.processLoginRequest email, (err, isAllowed)->
+			return done(err) if err?
+			if !isAllowed
+				logger.log email:email, "too many login requests"
+				return done(null, null, {message: req.i18n.translate("to_many_login_requests_2_mins"), type: 'error'})
+			AuthenticationManager.authenticate email: email, password, (error, user) ->
+				return done(error) if error?
+				if user?
+					# async actions
+					UserHandler.setupLoginData(user, ()->)
+					LoginRateLimiter.recordSuccessfulLogin(email)
+					AuthenticationController._recordSuccessfulLogin(user._id)
+					Analytics.recordEvent(user._id, "user-logged-in")
+					UserSessionsManager.trackSession(user, req.sessionID, () ->)
+					req.session.justLoggedIn = true
+					logger.log email: email, user_id: user._id.toString(), "successful log in"
+					# capture the request ip for use when creating the session
+					user._login_req_ip = req.ip
+					req._redir = redir
+					console.log ">> done, returning user"
+					return done(null, user)
+				else
+					AuthenticationController._recordFailedLogin()
+					logger.log email: email, "failed log in"
+					return done(null, false, {message: req.i18n.translate("email_or_password_wrong_try_again"), type: 'error'})
+
+
 	doLogin: (options, req, res, next) ->
 		email = options.email?.toLowerCase()
 		password = options.password

+ 4 - 4
services/web/app/coffee/Features/Project/ProjectController.coffee

@@ -45,10 +45,10 @@ module.exports = ProjectController =
 		async.series jobs, (error) ->
 			return next(error) if error?
 			res.sendStatus(204)
-			
+
 	updateProjectAdminSettings: (req, res, next) ->
 		project_id = req.params.Project_id
-		
+
 		jobs = []
 		if req.body.publicAccessLevel?
 			jobs.push (callback) ->
@@ -149,7 +149,7 @@ module.exports = ProjectController =
 					return next(err)
 				logger.log results:results, user_id:user_id, "rendering project list"
 				tags = results.tags[0]
-				notifications = require("underscore").map results.notifications, (notification)-> 
+				notifications = require("underscore").map results.notifications, (notification)->
 					notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
 					return notification
 				projects = ProjectController._buildProjectList results.projects[0], results.projects[1], results.projects[2]
@@ -332,4 +332,4 @@ do generateThemeList = () ->
 	for file in files
 		if file.slice(-2) == "js" and file.match(/^theme-/)
 			cleanName = file.slice(0,-3).slice(6)
-			THEME_LIST.push cleanName
+			THEME_LIST.push cleanName

+ 1 - 0
services/web/app/coffee/Features/User/UserController.coffee

@@ -84,6 +84,7 @@ module.exports = UserController =
 		logger.log user: req?.session?.user, "logging out"
 		sessionId = req.sessionID
 		user = req?.session?.user
+		req.logout?()  # passport logout
 		req.session.destroy (err)->
 			if err
 				logger.err err: err, 'error destorying session'

+ 20 - 0
services/web/app/coffee/infrastructure/Server.coffee

@@ -21,6 +21,9 @@ cookieParser = require('cookie-parser')
 
 sessionStore = new RedisStore(client:rclient)
 
+passport = require('passport')
+LocalStrategy = require('passport-local').Strategy
+
 Mongoose = require("./Mongoose")
 
 oneDayInMilliseconds = 86400000
@@ -32,6 +35,7 @@ Modules = require "./Modules"
 
 ErrorController = require "../Features/Errors/ErrorController"
 UserSessionsManager = require "../Features/User/UserSessionsManager"
+AuthenticationController = require "../Features/Authentication/AuthenticationController"
 
 metrics.mongodb.monitor(Path.resolve(__dirname + "/../../../node_modules/mongojs/node_modules/mongodb"), logger)
 metrics.mongodb.monitor(Path.resolve(__dirname + "/../../../node_modules/mongoose/node_modules/mongodb"), logger)
@@ -87,6 +91,22 @@ webRouter.use csrfProtection
 webRouter.use translations.expressMiddlewear
 webRouter.use translations.setLangBasedOnDomainMiddlewear
 
+# passport
+webRouter.use passport.initialize()
+webRouter.use passport.session()
+
+passport.use(new LocalStrategy(
+	{
+		passReqToCallback: true,
+		usernameField: 'email',
+		passwordField: 'password'
+	},
+	AuthenticationController.doPassportLogin
+))
+passport.serializeUser(AuthenticationController.serializeUser)
+passport.deserializeUser(AuthenticationController.deserializeUser)
+
+
 # Measure expiry from last request, not last login
 webRouter.use (req, res, next) ->
 	req.session.touch()

+ 7 - 3
services/web/app/coffee/router.coffee

@@ -43,6 +43,7 @@ AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
 
 logger = require("logger-sharelatex")
 _ = require("underscore")
+passport = require('passport')
 
 module.exports = class Router
 	constructor: (webRouter, apiRouter)->
@@ -53,7 +54,10 @@ module.exports = class Router
 		webRouter.get  '/login', UserPagesController.loginPage
 		AuthenticationController.addEndpointToLoginWhitelist '/login'
 
-		webRouter.post '/login', AuthenticationController.login
+		# webRouter.post '/login', AuthenticationController.login
+		webRouter.post '/login', passport.authenticate('local'), AuthenticationController.login, (req, res) ->
+			console.log ">> login done", req._redir
+			res.json {redir: req._redir}
 		webRouter.get  '/logout', UserController.logout
 		webRouter.get  '/restricted', AuthorizationMiddlewear.restricted
 
@@ -71,7 +75,7 @@ module.exports = class Router
 		RealTimeProxyRouter.apply(webRouter, apiRouter)
 		ContactRouter.apply(webRouter, apiRouter)
 		AnalyticsRouter.apply(webRouter, apiRouter)
-		
+
 		Modules.applyRouter(webRouter, apiRouter)
 
 
@@ -182,7 +186,7 @@ module.exports = class Router
 		webRouter.delete '/tag/:tag_id/project/:project_id', AuthenticationController.requireLogin(), TagsController.removeProjectFromTag
 
 		webRouter.get '/notifications', AuthenticationController.requireLogin(), NotificationsController.getAllUnreadNotifications
-		webRouter.delete '/notifications/:notification_id', AuthenticationController.requireLogin(), NotificationsController.markNotificationAsRead	
+		webRouter.delete '/notifications/:notification_id', AuthenticationController.requireLogin(), NotificationsController.markNotificationAsRead
 
 		# Deprecated in favour of /internal/project/:project_id but still used by versioning
 		apiRouter.get  '/project/:project_id/details', AuthenticationController.httpAuth, ProjectApiController.getProjectDetails

+ 2 - 0
services/web/package.json

@@ -46,6 +46,8 @@
     "nodemailer-sendgrid-transport": "^0.2.0",
     "nodemailer-ses-transport": "^1.3.0",
     "optimist": "0.6.1",
+    "passport": "^0.3.2",
+    "passport-local": "^1.0.0",
     "pg": "^6.0.3",
     "pg-hstore": "^2.3.2",
     "redback": "0.4.0",