2015-11-02 20:07:23 -05:00
|
|
|
async = require 'async'
|
|
|
|
mongoose = require 'mongoose'
|
|
|
|
Handler = require '../commons/Handler'
|
|
|
|
Classroom = require './Classroom'
|
|
|
|
User = require '../users/User'
|
2015-11-03 17:46:13 -05:00
|
|
|
sendwithus = require '../sendwithus'
|
2015-11-04 15:41:13 -05:00
|
|
|
utils = require '../lib/utils'
|
2015-11-05 15:55:51 -05:00
|
|
|
UserHandler = require '../users/user_handler'
|
2015-11-02 20:07:23 -05:00
|
|
|
|
|
|
|
ClassroomHandler = class ClassroomHandler extends Handler
|
|
|
|
modelClass: Classroom
|
|
|
|
jsonSchema: require '../../app/schemas/models/classroom.schema'
|
|
|
|
allowedMethods: ['GET', 'POST', 'PUT', 'DELETE']
|
|
|
|
|
|
|
|
hasAccess: (req) ->
|
|
|
|
return false unless req.user
|
|
|
|
return true if req.method is 'GET'
|
|
|
|
req.method in @allowedMethods or req.user?.isAdmin()
|
|
|
|
|
|
|
|
hasAccessToDocument: (req, document, method=null) ->
|
|
|
|
return false unless document?
|
|
|
|
return true if req.user?.isAdmin()
|
|
|
|
return true if document.get('ownerID')?.equals req.user?._id
|
|
|
|
isGet = (method or req.method).toLowerCase() is 'get'
|
|
|
|
isMember = _.any(document.get('members') or [], (memberID) -> memberID.equals(req.user.get('_id')))
|
|
|
|
return true if isGet and isMember
|
|
|
|
false
|
|
|
|
|
|
|
|
makeNewInstance: (req) ->
|
|
|
|
instance = super(req)
|
|
|
|
instance.set 'ownerID', req.user._id
|
|
|
|
instance.set 'members', []
|
|
|
|
instance
|
|
|
|
|
|
|
|
getByRelationship: (req, res, args...) ->
|
|
|
|
method = req.method.toLowerCase()
|
2015-11-03 17:46:13 -05:00
|
|
|
return @inviteStudents(req, res, args[0]) if args[1] is 'invite-members'
|
2015-11-02 20:07:23 -05:00
|
|
|
return @joinClassroomAPI(req, res, args[0]) if method is 'post' and args[1] is 'members'
|
2015-12-02 14:56:38 -05:00
|
|
|
return @removeMember(req, res, args[0]) if req.method is 'DELETE' and args[1] is 'members'
|
2015-11-05 15:55:51 -05:00
|
|
|
return @getMembersAPI(req, res, args[0]) if args[1] is 'members'
|
2015-11-02 20:07:23 -05:00
|
|
|
super(arguments...)
|
|
|
|
|
2015-11-05 15:55:51 -05:00
|
|
|
getMembersAPI: (req, res, classroomID) ->
|
|
|
|
Classroom.findById classroomID, (err, classroom) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res) unless classroom
|
|
|
|
memberIDs = classroom.get('members') ? []
|
|
|
|
User.find {_id: {$in: memberIDs}}, (err, users) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
cleandocs = (UserHandler.formatEntity(req, doc) for doc in users)
|
|
|
|
@sendSuccess(res, cleandocs)
|
|
|
|
|
2015-11-02 20:07:23 -05:00
|
|
|
joinClassroomAPI: (req, res, classroomID) ->
|
|
|
|
return @sendBadInputError(res, 'Need an object with a code') unless req.body?.code
|
2015-11-22 10:47:28 -05:00
|
|
|
code = req.body.code.toLowerCase()
|
|
|
|
Classroom.findOne {code: code}, (err, classroom) =>
|
2015-11-02 20:07:23 -05:00
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res) if not classroom
|
|
|
|
members = _.clone(classroom.get('members'))
|
|
|
|
if _.any(members, (memberID) -> memberID.equals(req.user.get('_id')))
|
|
|
|
return @sendSuccess(res, @formatEntity(req, classroom))
|
2015-11-05 16:07:36 -05:00
|
|
|
update = { $push: { members : req.user.get('_id')}}
|
|
|
|
classroom.update update, (err) =>
|
2015-11-02 20:07:23 -05:00
|
|
|
return @sendDatabaseError(res, err) if err
|
2015-11-05 16:07:36 -05:00
|
|
|
members.push req.user.get('_id')
|
|
|
|
classroom.set('members', members)
|
2015-11-02 20:07:23 -05:00
|
|
|
return @sendSuccess(res, @formatEntity(req, classroom))
|
2015-11-22 10:47:28 -05:00
|
|
|
|
2015-12-02 14:56:38 -05:00
|
|
|
removeMember: (req, res, classroomID) ->
|
|
|
|
userID = req.body.userID
|
|
|
|
return @sendBadInputError(res, 'Input must be a MongoDB ID') unless utils.isID(userID)
|
|
|
|
Classroom.findById classroomID, (err, classroom) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res, 'Classroom referenced by course instance not found') unless classroom
|
|
|
|
return @sendForbiddenError(res) unless _.any(classroom.get('members'), (memberID) -> memberID.toString() is userID)
|
|
|
|
ownsClassroom = classroom.get('ownerID').equals(req.user.get('_id'))
|
|
|
|
removingSelf = userID is req.user.id
|
|
|
|
return @sendForbiddenError(res) unless ownsClassroom or removingSelf
|
|
|
|
alreadyNotInClassroom = not _.any classroom.get('members') or [], (memberID) -> memberID.toString() is userID
|
|
|
|
return @sendSuccess(res, @formatEntity(req, classroom)) if alreadyNotInClassroom
|
|
|
|
members = _.clone(classroom.get('members'))
|
|
|
|
members.splice(members.indexOf(userID), 1)
|
|
|
|
classroom.set('members', members)
|
|
|
|
classroom.save (err, classroom) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
@sendSuccess(res, @formatEntity(req, classroom))
|
|
|
|
|
2015-11-02 20:07:23 -05:00
|
|
|
formatEntity: (req, doc) ->
|
|
|
|
if req.user?.isAdmin() or req.user?.get('_id').equals(doc.get('ownerID'))
|
|
|
|
return doc.toObject()
|
2015-11-22 10:47:28 -05:00
|
|
|
return _.omit(doc.toObject(), 'code', 'codeCamel')
|
2015-11-02 20:07:23 -05:00
|
|
|
|
2015-11-03 17:46:13 -05:00
|
|
|
inviteStudents: (req, res, classroomID) ->
|
|
|
|
if not req.body.emails
|
|
|
|
return @sendBadInputError(res, 'Emails not included')
|
2015-11-22 10:47:28 -05:00
|
|
|
|
2015-11-03 17:46:13 -05:00
|
|
|
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'))
|
|
|
|
|
|
|
|
for email in req.body.emails
|
|
|
|
context =
|
|
|
|
email_id: sendwithus.templates.course_invite_email
|
|
|
|
recipient:
|
|
|
|
address: email
|
|
|
|
email_data:
|
|
|
|
class_name: classroom.get('name')
|
|
|
|
# TODO: join_link
|
2015-11-22 10:47:28 -05:00
|
|
|
join_link: "https://codecombat.com/courses/students?_cc=" + (classroom.get('codeCamel') or classroom.get('code'))
|
2015-11-03 17:46:13 -05:00
|
|
|
sendwithus.api.send context, _.noop
|
|
|
|
return @sendSuccess(res, {})
|
2015-11-22 10:47:28 -05:00
|
|
|
|
2015-11-04 15:41:13 -05:00
|
|
|
get: (req, res) ->
|
|
|
|
if ownerID = req.query.ownerID
|
|
|
|
return @sendForbiddenError(res) unless req.user and (req.user.isAdmin() or ownerID is req.user.id)
|
|
|
|
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))
|
2015-11-05 15:55:51 -05:00
|
|
|
else if memberID = req.query.memberID
|
|
|
|
return @sendForbiddenError(res) unless req.user and (req.user.isAdmin() or memberID is req.user.id)
|
|
|
|
return @sendBadInputError(res, 'Bad memberID') unless utils.isID memberID
|
|
|
|
Classroom.find {members: mongoose.Types.ObjectId(memberID)}, (err, classrooms) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendSuccess(res, (@formatEntity(req, classroom) for classroom in classrooms))
|
2015-12-01 17:12:27 -05:00
|
|
|
else if code = req.query.code.toLowerCase()
|
2015-11-20 21:02:02 -05:00
|
|
|
Classroom.findOne {code: code}, (err, classroom) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res) unless classroom
|
|
|
|
return @sendSuccess(res, @formatEntity(req, classroom))
|
2015-11-04 15:41:13 -05:00
|
|
|
else
|
|
|
|
super(arguments...)
|
2015-11-03 17:46:13 -05:00
|
|
|
|
2015-11-02 20:07:23 -05:00
|
|
|
|
|
|
|
module.exports = new ClassroomHandler()
|