diff --git a/server/middleware/classrooms.coffee b/server/middleware/classrooms.coffee index c03523a3e..f44198ea7 100644 --- a/server/middleware/classrooms.coffee +++ b/server/middleware/classrooms.coffee @@ -205,7 +205,8 @@ module.exports = ownedStudentIDs = _.flatten ownedClassrooms.map (c) -> c.get('members').map (id) -> id.toString() - return next() unless memberID in ownedStudentIDs + unless memberID in ownedStudentIDs + throw new errors.Forbidden("Can't reset the password of a student that's not in one of your classrooms.") student = yield User.findById(memberID) if student.get('emailVerified') log.debug "classrooms.setStudentPassword: Can't reset password for a student (#{memberID}) that has verified their email address." diff --git a/spec/server/functional/classrooms.spec.coffee b/spec/server/functional/classrooms.spec.coffee index 4d7e814a3..94ad0f9df 100644 --- a/spec/server/functional/classrooms.spec.coffee +++ b/spec/server/functional/classrooms.spec.coffee @@ -447,3 +447,73 @@ describe 'GET /db/classroom/:handle/members', -> expect(user.email).toBeDefined() expect(user.passwordHash).toBeUndefined() done() + +describe 'POST /db/classroom/:classroomID/members/:memberID/reset-password', -> + it 'changes the password', utils.wrap (done) -> + yield utils.clearModels([User, Classroom]) + teacher = yield utils.initUser() + yield utils.loginUser(teacher) + student = yield utils.initUser({ name: "Firstname Lastname" }) + newPassword = "this is a new password" + classroom = yield new Classroom({name: 'Classroom', ownerID: teacher._id, members: [student._id] }).save() + expect(student.get('passwordHash')).not.toEqual(User.hashPassword(newPassword)) + [res, body] = yield request.postAsync({ + uri: getURL("/db/classroom/#{classroom.id}/members/#{student.id}/reset-password") + json: { password: newPassword } + }) + expect(res.statusCode).toBe(200) + changedStudent = yield User.findById(student.id) + expect(changedStudent.get('passwordHash')).toEqual(User.hashPassword(newPassword)) + done() + + it "doesn't change the password if you're not their teacher", utils.wrap (done) -> + yield utils.clearModels([User, Classroom]) + teacher = yield utils.initUser() + yield utils.loginUser(teacher) + student = yield utils.initUser({ name: "Firstname Lastname" }) + student2 = yield utils.initUser({ name: "Firstname Lastname 2" }) + newPassword = "this is a new password" + classroom = yield new Classroom({name: 'Classroom', ownerID: teacher._id, members: [student2._id] }).save() + expect(student.get('passwordHash')).not.toEqual(User.hashPassword(newPassword)) + [res, body] = yield request.postAsync({ + uri: getURL("/db/classroom/#{classroom.id}/members/#{student.id}/reset-password") + json: { password: newPassword } + }) + expect(res.statusCode).toBe(403) + changedStudent = yield User.findById(student.id) + expect(changedStudent.get('passwordHash')).toEqual(student.get('passwordHash')) + done() + + it "doesn't change the password if their email is verified", utils.wrap (done) -> + yield utils.clearModels([User, Classroom]) + teacher = yield utils.initUser() + yield utils.loginUser(teacher) + student = yield utils.initUser({ name: "Firstname Lastname", emailVerified: true }) + newPassword = "this is a new password" + classroom = yield new Classroom({name: 'Classroom', ownerID: teacher._id, members: [student._id] }).save() + expect(student.get('passwordHash')).not.toEqual(User.hashPassword(newPassword)) + [res, body] = yield request.postAsync({ + uri: getURL("/db/classroom/#{classroom.id}/members/#{student.id}/reset-password") + json: { password: newPassword } + }) + expect(res.statusCode).toBe(403) + changedStudent = yield User.findById(student.id) + expect(changedStudent.get('passwordHash')).toEqual(student.get('passwordHash')) + done() + + it "doesn't let you set a 1-character password", utils.wrap (done) -> + yield utils.clearModels([User, Classroom]) + teacher = yield utils.initUser() + yield utils.loginUser(teacher) + student = yield utils.initUser({ name: "Firstname Lastname" }) + newPassword = "e" + classroom = yield new Classroom({name: 'Classroom', ownerID: teacher._id, members: [student._id] }).save() + expect(student.get('passwordHash')).not.toEqual(User.hashPassword(newPassword)) + [res, body] = yield request.postAsync({ + uri: getURL("/db/classroom/#{classroom.id}/members/#{student.id}/reset-password") + json: { password: newPassword } + }) + expect(res.statusCode).toBe(422) + changedStudent = yield User.findById(student.id) + expect(changedStudent.get('passwordHash')).toEqual(student.get('passwordHash')) + done()