codecombat/server/middleware/auth.coffee
2016-03-04 10:43:17 -08:00

66 lines
No EOL
2.5 KiB
CoffeeScript

# Middleware for both authentication and authorization
errors = require '../commons/errors'
utils = require '../lib/utils'
wrap = require 'co-express'
Promise = require 'bluebird'
mongoose = require 'mongoose'
User = require '../models/User'
module.exports = {
checkDocumentPermissions: (req, res, next) ->
return next() if req.user?.isAdmin()
if not req.doc.hasPermissionsForMethod(req.user, req.method)
if req.user
return next new errors.Forbidden('You do not have permissions necessary.')
return next new errors.Unauthorized('You must be logged in.')
next()
checkLoggedIn: ->
return (req, res, next) ->
if not req.user
return next new errors.Unauthorized('You must be logged in.')
next()
checkHasPermission: (permissions) ->
if _.isString(permissions)
permissions = [permissions]
return (req, res, next) ->
if not req.user
return next new errors.Unauthorized('You must be logged in.')
if not _.size(_.intersection(req.user.get('permissions'), permissions))
return next new errors.Forbidden('You do not have permissions necessary.')
next()
spy: wrap (req, res) ->
throw new errors.Unauthorized('You must be logged in to enter espionage mode') unless req.user
throw new errors.Forbidden('You must be an admin to enter espionage mode') unless req.user.isAdmin()
user = req.body.user
throw new errors.UnprocessableEntity('Specify an id, username or email to espionage.') unless user
if utils.isID(user)
query = {_id: mongoose.Types.ObjectId(user)}
else
user = user.toLowerCase()
query = $or: [{nameLower: user}, {emailLower: user}]
user = yield User.findOne(query)
amActually = req.user
throw new errors.NotFound() unless user
req.loginAsync = Promise.promisify(req.login)
yield req.loginAsync user
req.session.amActually = amActually.id
res.status(200).send(user.toObject({req: req}))
stopSpying: wrap (req, res) ->
throw new errors.Unauthorized('You must be logged in to leave espionage mode') unless req.user
throw new errors.Forbidden('You must be in espionage mode to leave it') unless req.session.amActually
user = yield User.findById(req.session.amActually)
delete req.session.amActually
throw new errors.NotFound() unless user
req.loginAsync = Promise.promisify(req.login)
yield req.loginAsync user
res.status(200).send(user.toObject({req: req}))
}