Accept invitations.

This commit is contained in:
Michael Zhang 2016-02-29 12:35:40 -06:00
parent f99a47cb2c
commit 9f8e7ee95f
7 changed files with 121 additions and 85 deletions

View file

@ -0,0 +1,5 @@
{
"title": "Survey",
"description": "Take our survey.",
}

View file

@ -30,6 +30,16 @@ class Users(db.Model):
self.admin = False
self.registertime = int(time.time())
def get_invitations(self):
invitations = db.session.query(TeamInvitations).filter_by(rtype=0, toid=self.uid).all()
result = [ ]
for inv in invitations:
team = db.session.query(Teams).filter_by(tid=inv.frid).first()
result.append({
"team": team.teamname
})
return result
class Teams(db.Model):
tid = db.Column(db.Integer, primary_key=True)
teamname = db.Column(db.String(64), unique=True)

View file

@ -162,6 +162,34 @@ def team_invite_request():
return { "success": 1, "message": "Success!" }
@blueprint.route("/invite/accept", methods=["POST"])
@api_wrapper
def team_accept_invite():
params = utils.flat_multi(request.form)
_user = user.get_user().first()
if user.in_team(_user):
raise WebException("You're already in a team!")
tid = params.get("tid")
_team = get_team(tid=tid).first()
if _team is None:
raise WebException("Team not found.")
invitation = TeamInvitations.query.filter_by(rtype=0, frid=tid, toid=_user.uid).first()
if invitation is None:
raise WebException("Invitation doesn't exist.")
with app.app_context():
_user = Users.query.filter_by(uid=_user.uid).first()
_user.tid = tid
db.session.delete(invitation)
invitation2 = TeamInvitations.query.filter_by(rtype=1, frid=_user.uid, toid=tid).first()
if invitation2 is not None:
db.session.delete(invitation2)
db.session.commit()
return { "success": 1, "message": "Success!" }
@blueprint.route("/info", methods=["GET"])
@api_wrapper
def team_info():
@ -196,6 +224,9 @@ def team_info():
if logged_in:
teamdata["invited"] = team.get_pending_invitations(toid=_user.uid) is not None
teamdata["requested"] = team.get_invitation_requests(frid=_user.uid) is not None
else:
if logged_in:
teamdata["invitations"] = _user.get_invitations()
return { "success": 1, "team": teamdata }
##################

View file

@ -166,6 +166,9 @@ def user_info():
userdata["email"] = user.email
if user_in_team:
userdata["team"] = team.get_team_info(tid=user.tid)
if me and not(user_in_team):
invitations = user.get_invitations()
userdata["invitations"] = invitations
return { "success": 1, "user": userdata }
##################

View file

@ -317,7 +317,6 @@ var login_form = function() {
// team page
var create_team = function() {
<<<<<<< HEAD
var input = "#create_team input";
var data = $("#create_team").serializeObject();
$(input).attr("disabled", "disabled");
@ -353,43 +352,6 @@ var add_member = function() {
$(input).removeAttr("disabled");
});
});
=======
var input = "#create_team input";
var data = $("#create_team").serializeObject();
$(input).attr("disabled", "disabled");
api_call("POST", "/api/team/create", data, function(result) {
if (result["success"] == 1) {
location.reload(true);
} else {
display_message("create_team_msg", "danger", result["message"], function() {
$(input).removeAttr("disabled");
});
}
}, function(jqXHR, status, error) {
var result = jqXHR["responseText"];
display_message("create_team_msg", "danger", "Error " + jqXHR["status"] + ": " + result["message"], function() {
$(input).removeAttr("disabled");
});
});
};
var add_member = function() {
var input = "#add_member input";
var data = $("#add_member").serializeObject();
$(input).attr("disabled", "disabled");
api_call("POST", "/api/team/invite", data, function(result) {
if (result["success"] == 1) {
location.reload(true);
} else {
$(input).removeAttr("disabled");
}
}, function(jqXHR, status, error) {
var result = JSON.parse(jqXHR["responseText"]);
display_message("create_team_msg", "danger", "Error " + jqXHR["status"] + ": " + result["message"], function() {
$(input).removeAttr("disabled");
});
});
>>>>>>> d6564d17efae214a3284d1afe243952d90d0b752
};
var rescind_invitation = function(uid) {
@ -411,3 +373,12 @@ var request_invitation = function(tid) {
}
});
};
var accept_invitation = function(tid) {
var data = { "tid": tid };
api_call("POST", "/api/team/invite/accept", data, function(result) {
if (result["success"] == 1) {
location.reload(true);
}
});
};

View file

@ -59,6 +59,7 @@
</table>
</div>
<div class="panel-body" ng-show="user['in_team']!=true">
<div class="alert alert-success" ng-show="user['me']==true && user['invitations'].length>0">You have {{ user['invitations'].length }} invitation{{ user['invitations'].length==1 ? "" : "s" }}! <a href="/team">View &raquo;</a></div>
<p>{{ user['me']==true ? "You're" : "This user is" }} not a part of a team.</p>
<a href="/team" class="btn btn-primary" ng-show="user['me']==true">Join or create one now &raquo;</a>
</div>

View file

@ -41,7 +41,8 @@
</div>
<div class="list-group">
<div class="list-group-item" ng-repeat="member in team['members']">
<h4 class="list-group-item-heading">{{ member['name'] }}</h4>
<h4 class="list-group-item-heading" style="display:inline-block;">{{ member['name'] }}</h4>
<div class="label label-info" ng-show="member['captain']==true">Owner</div>
<p class="list-group-item-text">@{{ member['username'] }}</p>
</div>
</div>
@ -102,59 +103,73 @@
<div class="page-header">
<h1>Team</h1>
</div>
<p>To participate in EasyCTF, you must be on a <b>team</b>. If you'd like to go solo, just create a team by yourself. Read about team eligibility in the <a href="/rules">rules</a>.</p>
<div class="row">
<div class="col-md-6">
<div class="page-header">
<h3>New Team</h3>
</div>
<p>To participate in EasyCTF, you must be on a <b>team</b>. If you'd like to go solo, just create a team by yourself. Read about team eligibility in the <a href="/rules">rules</a>.</p>
<form class="form-horizontal" onsubmit="create_team(); return false;" id="create_team">
<fieldset>
<div id="create_team_msg"></div>
</fieldset>
<fieldset class="container-fluid">
<div class="col-md-6 col-md-offset-3 col-sm-10 col-sm-offset-1">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Create a Team</h2>
</div>
<div class="panel-body">
<form class="form-horizontal" onsubmit="login_form(); return false;" id="login_form">
<fieldset>
<div id="login_msg"></div>
</fieldset>
<fieldset class="container-fluid">
<div class="row">
<div class="col-sm-12 form-group">
<label class="col-sm-12" for="teamname"><small>Team Name</small></label>
<div class="col-sm-12">
<input class="form-control" type="text" required name="teamname" id="teamname" placeholder="Create a team name..." autocomplete="off" />
<form class="form-horizontal" onsubmit="create_team(); return false;" id="create_team">
<fieldset>
<div id="create_team_msg"></div>
</fieldset>
<fieldset class="container-fluid">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Create a Team</h2>
</div>
<div class="panel-body">
<form class="form-horizontal" onsubmit="login_form(); return false;" id="login_form">
<fieldset>
<div id="login_msg"></div>
</fieldset>
<fieldset class="container-fluid">
<div class="row">
<div class="col-sm-12 form-group">
<label class="col-sm-12" for="teamname"><small>Team Name</small></label>
<div class="col-sm-12">
<input class="form-control" type="text" required name="teamname" id="teamname" placeholder="Create a team name..." autocomplete="off" />
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 form-group">
<label class="col-sm-12" for="school"><small>School Name</small></label>
<div class="col-sm-12">
<input class="form-control" type="text" required name="school" id="school" placeholder="School Name" autocomplete="off" />
<div class="row">
<div class="col-sm-12 form-group">
<label class="col-sm-12" for="school"><small>School Name</small></label>
<div class="col-sm-12">
<input class="form-control" type="text" required name="school" id="school" placeholder="School Name" autocomplete="off" />
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 form-group">
<center>
<input type="submit" class="btn btn-success btn-lg" value="Create Team" />
</center>
</div>
</div>
</fieldset>
</form>
<div class="row">
<div class="col-sm-12 form-group">
<center>
<input type="submit" class="btn btn-success btn-lg" value="Create Team" />
</center>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</fieldset>
</form>
</div>
<div class="col-md-6">
<div class="page-header">
<h3>Invitations</h3>
</div>
<p ng-show="team['invitations'].length==0">You need an invitation to join another team. If you'd like to request to be a member of their team, go to their team page and click the Request button.</p>
<div ng-show="team['invitations'].length>0" class="list-group">
<div class="list-group-item" ng-repeat="invitation in team['invitations']">
<a href="/team/{{ invitation['team'] }}">{{ invitation['team'] }}</a>
<a href="javascript:accept_invitation();" class="badge">Accept &raquo;</a>
</div>
</div>
</fieldset>
</form>
<div class="page-header">
<h3>Invitations</h3>
</div>
</div>
<p>You need an invitation to join another team. If you'd like to request to be a member of their team, go to their team page and click the Request button.</p>
</div>
<div ng-show="!(team['tid'] >= 0) && config.navbar['logged_in']!=true">
<div class="page-header">