mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 18:15:52 -05:00
39990ee151
Clan lists sorted by member count, then created date. Public clans lists limited to 100. Member lists sorted by slug.
132 lines
5.6 KiB
CoffeeScript
132 lines
5.6 KiB
CoffeeScript
async = require 'async'
|
|
mongoose = require 'mongoose'
|
|
Handler = require '../commons/Handler'
|
|
Clan = require './Clan'
|
|
EarnedAchievement = require '../achievements/EarnedAchievement'
|
|
User = require '../users/User'
|
|
UserHandler = require '../users/user_handler'
|
|
|
|
ClanHandler = class ClanHandler extends Handler
|
|
modelClass: Clan
|
|
jsonSchema: require '../../app/schemas/models/Clan.schema'
|
|
allowedMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
|
|
|
|
hasAccess: (req) ->
|
|
return true if req.method in ['GET']
|
|
return true if req.user? and not req.user.isAnonymous()
|
|
false
|
|
|
|
hasAccessToDocument: (req, document, method=null) ->
|
|
method = (method or req.method).toLowerCase()
|
|
return true if req.user?.isAdmin()
|
|
return true if method is 'get'
|
|
return true if document.get('ownerID')?.equals req.user._id
|
|
false
|
|
|
|
makeNewInstance: (req) ->
|
|
userName = req.user.get('name') ? 'Anoner'
|
|
instance = super(req)
|
|
instance.set 'ownerID', req.user._id
|
|
instance.set 'members', [req.user._id]
|
|
instance
|
|
|
|
delete: (req, res, clanID) ->
|
|
@getDocumentForIdOrSlug clanID, (err, clan) =>
|
|
return @sendDatabaseError res, err if err
|
|
return @sendNotFoundError res unless clan
|
|
return @sendForbiddenError res unless @hasAccessToDocument(req, clan)
|
|
memberIDs = clan.get('members')
|
|
Clan.remove {_id: clan.get('_id')}, (err) =>
|
|
return @sendDatabaseError res, err if err
|
|
User.update {_id: {$in: memberIDs}}, {$pull: {clans: clan.get('_id')}}, {multi: true}, (err) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
@sendNoContent(res)
|
|
|
|
getByRelationship: (req, res, args...) ->
|
|
return @joinClan(req, res, args[0]) if args[1] is 'join'
|
|
return @leaveClan(req, res, args[0]) if args[1] is 'leave'
|
|
return @getMemberAchievements(req, res, args[0]) if args[1] is 'member_achievements'
|
|
return @getMembers(req, res, args[0]) if args[1] is 'members'
|
|
return @getPublicClans(req, res) if args[1] is 'public'
|
|
return @removeMember(req, res, args[0], args[2]) if args.length is 3 and args[1] is 'remove'
|
|
super(arguments...)
|
|
|
|
joinClan: (req, res, clanID) ->
|
|
return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous()
|
|
try
|
|
clanID = mongoose.Types.ObjectId(clanID)
|
|
catch err
|
|
return @sendNotFoundError(res, err)
|
|
Clan.findById clanID, (err, clan) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
Clan.update {_id: clanID}, {$addToSet: {members: req.user._id}}, (err) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
User.update {_id: req.user._id}, {$addToSet: {clans: clanID}}, (err) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
@sendSuccess(res)
|
|
|
|
leaveClan: (req, res, clanID) ->
|
|
return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous()
|
|
try
|
|
clanID = mongoose.Types.ObjectId(clanID)
|
|
catch err
|
|
return @sendNotFoundError(res, err)
|
|
Clan.findById clanID, (err, clan) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
return @sendForbiddenError(res) if clan.get('ownerID')?.equals req.user._id
|
|
Clan.update {_id: clanID}, {$pull: {members: req.user._id}}, (err) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
User.update {_id: req.user._id}, {$pull: {clans: clanID}}, (err) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
@sendSuccess(res)
|
|
|
|
getMemberAchievements: (req, res, clanID) ->
|
|
# TODO: add tests
|
|
Clan.findById clanID, (err, clans) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
memberIDs = _.map clans.get('members') ? [], (memberID) -> memberID.toHexString()
|
|
EarnedAchievement.find {user: {$in: memberIDs}}, (err, documents) =>
|
|
return @sendDatabaseError(res, err) if err?
|
|
cleandocs = (@formatEntity(req, doc) for doc in documents)
|
|
@sendSuccess(res, cleandocs)
|
|
|
|
getMembers: (req, res, clanID) ->
|
|
# TODO: add tests
|
|
return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous()
|
|
clanIDs = req.user.get('clans') ? []
|
|
Clan.findById clanID, (err, clans) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
memberIDs = clans.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)
|
|
|
|
getPublicClans: (req, res) ->
|
|
# Return 100 public clans, sorted by member count, created date
|
|
query = [{ $match : {type : 'public'} }]
|
|
query.push {$project : {_id: 1, name: 1, slug: 1, type: 1, members: 1, memberCount: {$size: "$members"}, ownerID: 1}}
|
|
query.push {$sort: { memberCount: -1, _id: -1 }}
|
|
query.push {$limit: 100}
|
|
Clan.aggregate(query).exec (err, documents) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
@sendSuccess(res, documents)
|
|
|
|
removeMember: (req, res, clanID, memberID) ->
|
|
return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous()
|
|
try
|
|
clanID = mongoose.Types.ObjectId(clanID)
|
|
memberID = mongoose.Types.ObjectId(memberID)
|
|
catch err
|
|
return @sendNotFoundError(res, err)
|
|
Clan.findById clanID, (err, clan) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
return @sendForbiddenError res unless @hasAccessToDocument(req, clan)
|
|
return @sendForbiddenError(res) if clan.get('ownerID').equals memberID
|
|
Clan.update {_id: clanID}, {$pull: {members: memberID}}, (err) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
User.update {_id: memberID}, {$pull: {clans: clanID}}, (err) =>
|
|
return @sendDatabaseError(res, err) if err
|
|
@sendSuccess(res)
|
|
|
|
module.exports = new ClanHandler()
|