diff --git a/server/handlers/classroom_handler.coffee b/server/handlers/classroom_handler.coffee index 40dc82a59..a40ca08f1 100644 --- a/server/handlers/classroom_handler.coffee +++ b/server/handlers/classroom_handler.coffee @@ -5,6 +5,7 @@ Classroom = require './../models/Classroom' User = require '../models/User' sendwithus = require '../sendwithus' utils = require '../lib/utils' +log = require 'winston' UserHandler = require './user_handler' ClassroomHandler = class ClassroomHandler extends Handler @@ -74,7 +75,9 @@ ClassroomHandler = class ClassroomHandler extends Handler Classroom.findById classroomID, (err, classroom) => return @sendDatabaseError(res, err) if err return @sendNotFoundError(res) unless classroom - return @sendForbiddenError(res) unless classroom.get('ownerID').equals(req.user.get('_id')) + unless classroom.get('ownerID').equals(req.user.get('_id')) + log.debug "classroom_handler.inviteStudents: Can't invite to classroom (#{classroom.id}) you (#{req.user.get('_id')}) don't own" + return @sendForbiddenError(res) for email in req.body.emails joinCode = (classroom.get('codeCamel') or classroom.get('code')) @@ -91,13 +94,17 @@ ClassroomHandler = class ClassroomHandler extends Handler get: (req, res) -> if ownerID = req.query.ownerID - return @sendForbiddenError(res) unless req.user and (req.user.isAdmin() or ownerID is req.user.id) + unless req.user and (req.user.isAdmin() or ownerID is req.user.id) + log.debug "classroom_handler.get: ownerID (#{ownerID}) must be yourself (#{req.user.id})" + return @sendForbiddenError(res) return @sendBadInputError(res, 'Bad ownerID') unless utils.isID ownerID Classroom.find {ownerID: mongoose.Types.ObjectId(ownerID)}, (err, classrooms) => return @sendDatabaseError(res, err) if err return @sendSuccess(res, (@formatEntity(req, classroom) for classroom in classrooms)) else if memberID = req.query.memberID - return @sendForbiddenError(res) unless req.user and (req.user.isAdmin() or memberID is req.user.id) + unless req.user and (req.user.isAdmin() or memberID is req.user.id) + log.debug "classroom_handler.get: memberID (#{memberID}) must be yourself (#{req.user.id})" + return @sendForbiddenError(res) return @sendBadInputError(res, 'Bad memberID') unless utils.isID memberID Classroom.find {members: mongoose.Types.ObjectId(memberID)}, (err, classrooms) => return @sendDatabaseError(res, err) if err diff --git a/server/middleware/classrooms.coffee b/server/middleware/classrooms.coffee index ece79cf6c..c03523a3e 100644 --- a/server/middleware/classrooms.coffee +++ b/server/middleware/classrooms.coffee @@ -3,6 +3,7 @@ utils = require '../lib/utils' errors = require '../commons/errors' schemas = require '../../app/schemas/schemas' wrap = require 'co-express' +log = require 'winston' Promise = require 'bluebird' database = require '../commons/database' mongoose = require 'mongoose' @@ -21,6 +22,7 @@ module.exports = return next() unless code classroom = yield Classroom.findOne({ code: code.toLowerCase() }).select('name ownerID aceConfig') if not classroom + log.debug("classrooms.fetchByCode: Couldn't find Classroom with code: #{code}") throw new errors.NotFound('Classroom not found.') classroom = classroom.toObject() # Tack on the teacher's name for display to the user @@ -33,7 +35,9 @@ module.exports = return next() unless ownerID throw new errors.UnprocessableEntity('Bad ownerID') unless utils.isID ownerID throw new errors.Unauthorized() unless req.user - throw new errors.Forbidden('"ownerID" must be yourself') unless req.user.isAdmin() or ownerID is req.user.id + unless req.user.isAdmin() or ownerID is req.user.id + log.debug("classrooms.getByOwner: Can't fetch classroom you don't own. User: #{req.user.id} Owner: #{ownerID}") + throw new errors.Forbidden('"ownerID" must be yourself') sanitizedOptions = {} unless _.isUndefined(options.archived) # Handles when .archived is true, vs false-or-null @@ -114,6 +118,7 @@ module.exports = isOwner = classroom.get('ownerID').equals(req.user._id) isMember = req.user.id in (m.toString() for m in classroom.get('members')) unless req.user.isAdmin() or isOwner or isMember + log.debug "classrooms.fetchMembers: Can't fetch members for class (#{classroom.id}) you (#{req.user.id}) don't own and aren't a member of." throw new errors.Forbidden('You do not own this classroom.') memberIDs = classroom.get('members') or [] memberIDs = memberIDs.slice(memberSkip, memberSkip + memberLimit) @@ -126,7 +131,9 @@ module.exports = post: wrap (req, res) -> throw new errors.Unauthorized() unless req.user and not req.user.isAnonymous() - throw new errors.Forbidden() unless req.user?.isTeacher() + unless req.user?.isTeacher() + console.log "classrooms.post: Can't create classroom if you (#{req.user?.id}) aren't a teacher." + throw new errors.Forbidden() classroom = database.initDoc(req, Classroom) classroom.set 'ownerID', req.user._id classroom.set 'members', [] @@ -159,11 +166,13 @@ module.exports = unless req.body?.code throw new errors.UnprocessableEntity('Need a code') if req.user.isTeacher() + log.debug("classrooms.join: Cannot join a classroom as a teacher: #{req.user.id}") throw new errors.Forbidden('Cannot join a classroom as a teacher') code = req.body.code.toLowerCase() classroom = yield Classroom.findOne({code: code}) if not classroom - throw new errors.NotFound('Classroom not found.') + log.debug("classrooms.join: Classroom not found with code #{code}") + throw new errors.NotFound("Classroom not found with code #{code}") members = _.clone(classroom.get('members')) if _.any(members, (memberID) -> memberID.equals(req.user._id)) return res.send(classroom.toObject({req: req})) @@ -199,7 +208,8 @@ module.exports = return next() unless memberID in ownedStudentIDs student = yield User.findById(memberID) if student.get('emailVerified') - return next new errors.Forbidden("Can't reset password for a student that has verified their email address.") + log.debug "classrooms.setStudentPassword: Can't reset password for a student (#{memberID}) that has verified their email address." + throw new errors.Forbidden("Can't reset password for a student that has verified their email address.") { valid, error } = tv4.validateResult(newPassword, schemas.passwordString) unless valid throw new errors.UnprocessableEntity(error.message)