Made the server resistant to req.user being undefined sometimes.
This commit is contained in:
parent
168f268d21
commit
e63763d539
10 changed files with 47 additions and 36 deletions
|
@ -77,7 +77,7 @@
|
||||||
"clean-css-brunch": "> 1.0 < 1.8",
|
"clean-css-brunch": "> 1.0 < 1.8",
|
||||||
"auto-reload-brunch": "> 1.0 < 1.8",
|
"auto-reload-brunch": "> 1.0 < 1.8",
|
||||||
"brunch": "~1.7.4",
|
"brunch": "~1.7.4",
|
||||||
"jasmine-node": "1.12.x",
|
"jasmine-node": "1.13.x",
|
||||||
"nodemon": "0.7.5",
|
"nodemon": "0.7.5",
|
||||||
"marked": "0.2.x",
|
"marked": "0.2.x",
|
||||||
"telepath-brunch": "https://github.com/nwinter/telepath-brunch/tarball/master",
|
"telepath-brunch": "https://github.com/nwinter/telepath-brunch/tarball/master",
|
||||||
|
|
|
@ -16,7 +16,7 @@ module.exports = class Handler
|
||||||
# subclasses should override these methods
|
# subclasses should override these methods
|
||||||
hasAccess: (req) -> true
|
hasAccess: (req) -> true
|
||||||
hasAccessToDocument: (req, document, method=null) ->
|
hasAccessToDocument: (req, document, method=null) ->
|
||||||
return true if req.user.isAdmin()
|
return true if req.user?.isAdmin()
|
||||||
if @modelClass.schema.uses_coco_permissions
|
if @modelClass.schema.uses_coco_permissions
|
||||||
return document.hasPermissionsForMethod(req.user, method or req.method)
|
return document.hasPermissionsForMethod(req.user, method or req.method)
|
||||||
return true
|
return true
|
||||||
|
@ -32,7 +32,7 @@ module.exports = class Handler
|
||||||
# can only edit permissions if this is a brand new property,
|
# can only edit permissions if this is a brand new property,
|
||||||
# or you are an owner of the old one
|
# or you are an owner of the old one
|
||||||
isOwner = document.getAccessForUserObjectId(req.user._id) is 'owner'
|
isOwner = document.getAccessForUserObjectId(req.user._id) is 'owner'
|
||||||
if isBrandNew or isOwner or req.user.isAdmin()
|
if isBrandNew or isOwner or req.user?.isAdmin()
|
||||||
props.push 'permissions'
|
props.push 'permissions'
|
||||||
|
|
||||||
if @modelClass.schema.uses_coco_versions
|
if @modelClass.schema.uses_coco_versions
|
||||||
|
@ -57,7 +57,7 @@ module.exports = class Handler
|
||||||
# generic handlers
|
# generic handlers
|
||||||
get: (req, res) ->
|
get: (req, res) ->
|
||||||
# by default, ordinary users never get unfettered access to the database
|
# by default, ordinary users never get unfettered access to the database
|
||||||
return @sendUnauthorizedError(res) unless req.user.isAdmin()
|
return @sendUnauthorizedError(res) unless req.user?.isAdmin()
|
||||||
|
|
||||||
# admins can send any sort of query down the wire, though
|
# admins can send any sort of query down the wire, though
|
||||||
conditions = JSON.parse(req.query.conditions || '[]')
|
conditions = JSON.parse(req.query.conditions || '[]')
|
||||||
|
@ -97,7 +97,7 @@ module.exports = class Handler
|
||||||
term = req.query.term
|
term = req.query.term
|
||||||
matchedObjects = []
|
matchedObjects = []
|
||||||
filters = [{filter: {index: true}}]
|
filters = [{filter: {index: true}}]
|
||||||
if @modelClass.schema.uses_coco_permissions
|
if @modelClass.schema.uses_coco_permissions and req.user
|
||||||
filters.push {filter: {index: req.user.get('id')}}
|
filters.push {filter: {index: req.user.get('id')}}
|
||||||
for filter in filters
|
for filter in filters
|
||||||
callback = (err, results) =>
|
callback = (err, results) =>
|
||||||
|
|
|
@ -39,6 +39,7 @@ LevelHandler = class LevelHandler extends Handler
|
||||||
callback err, level
|
callback err, level
|
||||||
|
|
||||||
getSession: (req, res, id) ->
|
getSession: (req, res, id) ->
|
||||||
|
return @sendNotFoundError(res) unless req.user
|
||||||
@fetchLevelByIDAndHandleErrors id, req, res, (err, level) =>
|
@fetchLevelByIDAndHandleErrors id, req, res, (err, level) =>
|
||||||
sessionQuery =
|
sessionQuery =
|
||||||
level:
|
level:
|
||||||
|
@ -150,6 +151,7 @@ LevelHandler = class LevelHandler extends Handler
|
||||||
req.query.limit = parseInt(req.query.limit) ? 20
|
req.query.limit = parseInt(req.query.limit) ? 20
|
||||||
|
|
||||||
getFeedback: (req, res, id) ->
|
getFeedback: (req, res, id) ->
|
||||||
|
return @sendNotFoundError(res) unless req.user
|
||||||
@fetchLevelByIDAndHandleErrors id, req, res, (err, level) =>
|
@fetchLevelByIDAndHandleErrors id, req, res, (err, level) =>
|
||||||
feedbackQuery =
|
feedbackQuery =
|
||||||
creator: mongoose.Types.ObjectId(req.user.id.toString())
|
creator: mongoose.Types.ObjectId(req.user.id.toString())
|
||||||
|
|
|
@ -4,6 +4,7 @@ mail = require '../commons/mail'
|
||||||
|
|
||||||
module.exports.setup = (app) ->
|
module.exports.setup = (app) ->
|
||||||
app.post '/contact', (req, res) ->
|
app.post '/contact', (req, res) ->
|
||||||
|
return res.end() unless req.user
|
||||||
log.info "Sending mail from #{req.body.email} saying #{req.body.message}"
|
log.info "Sending mail from #{req.body.email} saying #{req.body.message}"
|
||||||
if config.isProduction
|
if config.isProduction
|
||||||
options = createMailOptions req.body.email, req.body.message, req.user
|
options = createMailOptions req.body.email, req.body.message, req.user
|
||||||
|
|
|
@ -11,6 +11,7 @@ module.exports.setup = (app) ->
|
||||||
parts = module.split('/')
|
parts = module.split('/')
|
||||||
module = parts[0]
|
module = parts[0]
|
||||||
return getSchema(req, res, module) if parts[1] is 'schema'
|
return getSchema(req, res, module) if parts[1] is 'schema'
|
||||||
|
return errors.unauthorized(res, 'Must have an identity to do anything with the db.') unless req.user
|
||||||
|
|
||||||
try
|
try
|
||||||
moduleName = module.replace '.', '_'
|
moduleName = module.replace '.', '_'
|
||||||
|
|
|
@ -69,7 +69,7 @@ postFileSchema =
|
||||||
required: ['filename', 'mimetype', 'path']
|
required: ['filename', 'mimetype', 'path']
|
||||||
|
|
||||||
filePost = (req, res) ->
|
filePost = (req, res) ->
|
||||||
return errors.forbidden(res) unless req.user.isAdmin()
|
return errors.forbidden(res) unless req.user?.isAdmin()
|
||||||
options = req.body
|
options = req.body
|
||||||
tv4 = require('tv4').tv4
|
tv4 = require('tv4').tv4
|
||||||
valid = tv4.validate(options, postFileSchema)
|
valid = tv4.validate(options, postFileSchema)
|
||||||
|
|
|
@ -31,7 +31,7 @@ UserHandler = class UserHandler extends Handler
|
||||||
return null unless document?
|
return null unless document?
|
||||||
obj = document.toObject()
|
obj = document.toObject()
|
||||||
delete obj[prop] for prop in serverProperties
|
delete obj[prop] for prop in serverProperties
|
||||||
includePrivates = req.user and (req.user.isAdmin() or req.user._id.equals(document._id))
|
includePrivates = req.user and (req.user?.isAdmin() or req.user?._id.equals(document._id))
|
||||||
delete obj[prop] for prop in privateProperties unless includePrivates
|
delete obj[prop] for prop in privateProperties unless includePrivates
|
||||||
|
|
||||||
# emailHash is used by gravatar
|
# emailHash is used by gravatar
|
||||||
|
@ -105,7 +105,7 @@ UserHandler = class UserHandler extends Handler
|
||||||
]
|
]
|
||||||
|
|
||||||
getById: (req, res, id) ->
|
getById: (req, res, id) ->
|
||||||
if req.user and req.user._id.equals(id)
|
if req.user?._id.equals(id)
|
||||||
return @sendSuccess(res, @formatEntity(req, req.user))
|
return @sendSuccess(res, @formatEntity(req, req.user))
|
||||||
super(req, res, id)
|
super(req, res, id)
|
||||||
|
|
||||||
|
@ -132,14 +132,15 @@ UserHandler = class UserHandler extends Handler
|
||||||
|
|
||||||
post: (req, res) ->
|
post: (req, res) ->
|
||||||
return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body)
|
return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body)
|
||||||
|
return @sendBadInputError(res, 'Must have an anonymous user to post with.') unless req.user
|
||||||
return @sendBadInputError(res, 'Existing users cannot create new ones.') unless req.user.get('anonymous')
|
return @sendBadInputError(res, 'Existing users cannot create new ones.') unless req.user.get('anonymous')
|
||||||
req.body._id = req.user._id if req.user.get('anonymous')
|
req.body._id = req.user._id if req.user.get('anonymous')
|
||||||
@put(req, res)
|
@put(req, res)
|
||||||
|
|
||||||
hasAccessToDocument: (req, document) ->
|
hasAccessToDocument: (req, document) ->
|
||||||
if req.route.method in ['put', 'post', 'patch']
|
if req.route.method in ['put', 'post', 'patch']
|
||||||
return true if req.user.isAdmin()
|
return true if req.user?.isAdmin()
|
||||||
return req.user._id.equals(document._id)
|
return req.user?._id.equals(document._id)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
getByRelationship: (req, res, args...) ->
|
getByRelationship: (req, res, args...) ->
|
||||||
|
@ -149,6 +150,7 @@ UserHandler = class UserHandler extends Handler
|
||||||
return @sendNotFoundError(res)
|
return @sendNotFoundError(res)
|
||||||
|
|
||||||
agreeToCLA: (req, res) ->
|
agreeToCLA: (req, res) ->
|
||||||
|
return @sendUnauthorizedError(res) unless req.user
|
||||||
doc =
|
doc =
|
||||||
user: req.user._id+''
|
user: req.user._id+''
|
||||||
email: req.user.get 'email'
|
email: req.user.get 'email'
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# import this at the top of every file so we're not juggling connections
|
# import this at the top of every file so we're not juggling connections
|
||||||
# and common libraries are available
|
# and common libraries are available
|
||||||
|
|
||||||
|
console.log 'IT BEGINS'
|
||||||
|
|
||||||
|
|
||||||
GLOBAL._ = require('lodash')
|
GLOBAL._ = require('lodash')
|
||||||
_.str = require('underscore.string')
|
_.str = require('underscore.string')
|
||||||
_.mixin(_.str.exports())
|
_.mixin(_.str.exports())
|
||||||
|
@ -71,20 +74,22 @@ unittest.getUser = (email, password, done, force) ->
|
||||||
return done(unittest.users[email]) if unittest.users[email] and not force
|
return done(unittest.users[email]) if unittest.users[email] and not force
|
||||||
request = require 'request'
|
request = require 'request'
|
||||||
request.post getURL('/auth/logout'), ->
|
request.post getURL('/auth/logout'), ->
|
||||||
req = request.post(getURL('/db/user'), (err, response, body) ->
|
request.get getURL('/auth/whoami'), ->
|
||||||
throw err if err
|
req = request.post(getURL('/db/user'), (err, response, body) ->
|
||||||
User.findOne({email:email}).exec((err, user) ->
|
throw err if err
|
||||||
if password is '80yqxpb38j'
|
User.findOne({email:email}).exec((err, user) ->
|
||||||
user.set('permissions', [ 'admin' ])
|
if password is '80yqxpb38j'
|
||||||
user.save (err) ->
|
user.set('permissions', [ 'admin' ])
|
||||||
|
user.save (err) ->
|
||||||
|
wrapUpGetUser(email, user, done)
|
||||||
|
else
|
||||||
wrapUpGetUser(email, user, done)
|
wrapUpGetUser(email, user, done)
|
||||||
else
|
)
|
||||||
wrapUpGetUser(email, user, done)
|
|
||||||
)
|
)
|
||||||
)
|
form = req.form()
|
||||||
form = req.form()
|
form.append('email', email)
|
||||||
form.append('email', email)
|
form.append('password', password)
|
||||||
form.append('password', password)
|
|
||||||
|
|
||||||
wrapUpGetUser = (email, user, done) ->
|
wrapUpGetUser = (email, user, done) ->
|
||||||
unittest.users[email] = user
|
unittest.users[email] = user
|
||||||
|
|
|
@ -17,8 +17,9 @@ describe '/auth/login', ->
|
||||||
|
|
||||||
it 'clears Users first', (done) ->
|
it 'clears Users first', (done) ->
|
||||||
User.remove {}, (err) ->
|
User.remove {}, (err) ->
|
||||||
throw err if err
|
request.get getURL('/auth/whoami'), ->
|
||||||
done()
|
throw err if err
|
||||||
|
done()
|
||||||
|
|
||||||
it 'finds no user', (done) ->
|
it 'finds no user', (done) ->
|
||||||
req = request.post(urlLogin, (error, response) ->
|
req = request.post(urlLogin, (error, response) ->
|
||||||
|
@ -92,9 +93,10 @@ describe '/auth/reset', ->
|
||||||
form = req.form()
|
form = req.form()
|
||||||
form.append('email', 'unknow')
|
form.append('email', 'unknow')
|
||||||
|
|
||||||
it 'reset user password', (done) ->
|
it 'resets user password', (done) ->
|
||||||
req = request.post(urlReset, (error, response) ->
|
req = request.post(urlReset, (error, response) ->
|
||||||
expect(response).toBeDefined()
|
expect(response).toBeDefined()
|
||||||
|
console.log 'status code is', response.statusCode
|
||||||
expect(response.statusCode).toBe(200)
|
expect(response.statusCode).toBe(200)
|
||||||
expect(response.body).toBeDefined()
|
expect(response.body).toBeDefined()
|
||||||
passwordReset = response.body
|
passwordReset = response.body
|
||||||
|
|
|
@ -54,18 +54,16 @@ describe 'POST /db/user', ->
|
||||||
|
|
||||||
describe 'PUT /db/user', ->
|
describe 'PUT /db/user', ->
|
||||||
|
|
||||||
it 'denies requests without any data', (done) ->
|
|
||||||
req = request.post getURL('/auth/logout'),
|
|
||||||
(err, res) ->
|
|
||||||
expect(res.statusCode).toBe(200)
|
|
||||||
req = request.put getURL(urlUser),
|
|
||||||
(err, res) ->
|
|
||||||
expect(res.statusCode).toBe(422)
|
|
||||||
expect(res.body).toBe('No input.')
|
|
||||||
done()
|
|
||||||
|
|
||||||
it 'logs in as normal joe', (done) ->
|
it 'logs in as normal joe', (done) ->
|
||||||
loginJoe -> done()
|
request.post getURL('/auth/logout'),
|
||||||
|
loginJoe -> done()
|
||||||
|
|
||||||
|
it 'denies requests without any data', (done) ->
|
||||||
|
request.put getURL(urlUser),
|
||||||
|
(err, res) ->
|
||||||
|
expect(res.statusCode).toBe(422)
|
||||||
|
expect(res.body).toBe('No input.')
|
||||||
|
done()
|
||||||
|
|
||||||
it 'denies requests to edit someone who is not joe', (done) ->
|
it 'denies requests to edit someone who is not joe', (done) ->
|
||||||
unittest.getAdmin (admin) ->
|
unittest.getAdmin (admin) ->
|
||||||
|
|
Reference in a new issue