frontend: team registration

This commit is contained in:
nemunaire 2017-12-21 22:18:18 +01:00
parent bc135d00c5
commit 184714aeeb
10 changed files with 208 additions and 28 deletions

View file

@ -41,7 +41,7 @@ func main() {
// Register handlers
http.Handle(fmt.Sprintf("%s/chname/", *prefix), http.StripPrefix(fmt.Sprintf("%s/chname/", *prefix), submissionTeamChecker{"name change", ChNameHandler, *teamsDir}))
http.Handle(fmt.Sprintf("%s/openhint/", *prefix), http.StripPrefix(fmt.Sprintf("%s/openhint/", *prefix), submissionTeamChecker{"opening hint", HintHandler, *teamsDir}))
http.Handle(fmt.Sprintf("%s/registration", *prefix), http.StripPrefix(fmt.Sprintf("%s/registration", *prefix), submissionChecker{"registration", RegistrationHandler}))
http.Handle(fmt.Sprintf("%s/registration/", *prefix), http.StripPrefix(fmt.Sprintf("%s/registration/", *prefix), submissionChecker{"registration", RegistrationHandler}))
http.Handle(fmt.Sprintf("%s/resolution/", *prefix), http.StripPrefix(fmt.Sprintf("%s/resolution/", *prefix), ResolutionHandler{}))
http.Handle(fmt.Sprintf("%s/submission/", *prefix), http.StripPrefix(fmt.Sprintf("%s/submission/", *prefix), submissionTeamChecker{"submission", SubmissionHandler, *teamsDir}))
http.Handle(fmt.Sprintf("%s/time.json", *prefix), http.StripPrefix(*prefix, fronttime.TimeHandler{}))

View file

@ -1,7 +1,6 @@
package main
import (
"io/ioutil"
"log"
"net/http"
"path"
@ -16,28 +15,26 @@ func RegistrationHandler(w http.ResponseWriter, r *http.Request, sURL []string)
return
}
if len(sURL) < 1 || len(sURL[0]) == 0 {
http.Error(w, "{\"errmsg\":\"Arguments manquants.\"}", http.StatusBadRequest)
return
}
teamInitialName := sURL[0]
// Check request type and size
if r.Method != "POST" {
http.Error(w, "{\"errmsg\":\"Requête invalide.\"}", http.StatusBadRequest)
return
} else if r.ContentLength < 0 || r.ContentLength > 1023 {
} else if r.ContentLength < 0 || r.ContentLength > 4095 {
http.Error(w, "{\"errmsg\":\"Requête trop longue ou de taille inconnue\"}", http.StatusRequestEntityTooLarge)
return
}
if tmpfile, err := ioutil.TempFile(path.Join(SubmissionDir, "_registration"), ""); err != nil {
log.Println("Unable to generate registration file:", err)
if err := saveFile(path.Join(SubmissionDir, "_registration", teamInitialName), r); err != nil {
log.Println("Unable to open registration file:", err)
http.Error(w, "{\"errmsg\":\"Internal server error. Please retry in few seconds.\"}", http.StatusInternalServerError)
} else {
// The file will be reopened by saveFile
tmpfile.Close()
if err := saveFile(tmpfile.Name(), r); err != nil {
log.Println("Unable to open registration file:", err)
http.Error(w, "{\"errmsg\":\"Internal server error. Please retry in few seconds.\"}", http.StatusInternalServerError)
} else {
// File enqueued for backend treatment
http.Error(w, "{\"errmsg\":\"Demande d'enregistrement acceptée\"}", http.StatusAccepted)
}
// File enqueued for backend treatment
http.Error(w, "{\"errmsg\":\"Demande d'enregistrement acceptée\"}", http.StatusAccepted)
}
}

View file

@ -83,6 +83,11 @@
<span class="teamname">{{ my.name }}</span>
</a>
</span>
<span class="navbar-text text-light" ng-show="!my.team_id && time.start" ng-cloak>
<a ng-href="/register" class="badge badge-warning" role="button">
Inscription
</a>
</span>
</nav>
<div class="container">

View file

@ -13,6 +13,10 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
controller: "RankController",
templateUrl: "views/rank.html"
})
.when("/register", {
controller: "RegisterController",
templateUrl: "views/register.html"
})
.when("/videos", {
controller: "VideosController",
templateUrl: "views/videos.html"
@ -74,7 +78,7 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
updTime();
$interval(updTime, 1000);
})
.controller("DataController", function($sce, $scope, $http, $rootScope, $timeout) {
.controller("DataController", function($sce, $scope, $http, $rootScope, $timeout, $location) {
var actMenu = function() {
if ($scope.my && $scope.themes) {
angular.forEach($scope.themes, function(theme, key) {
@ -146,6 +150,10 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
});
});
}
}, function(response) {
if (!$scope.my && response.status == 404) {
$location.url("/register");
}
});
console.log("refresh!");
}
@ -358,6 +366,76 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
});
};
})
.controller("RegisterController", function($scope, $rootScope, $location, $http) {
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;
$rootScope.title = "Bienvenue au challenge forensic !";
$rootScope.authors = null;
$scope.members = [{}];
$scope.AddMember = function() {
$scope.members.push({});
}
$scope.RemoveMember = function(k) {
$scope.members.splice(k, 1);
}
$scope.Validate = function() {
if ($scope.teamName.length <= 3) {
$('#teamName').addClass("is-invalid")
return;
} else {
$('#vldBtn').removeClass("input-group-btn");
$('#vldBtn').css("display", "none");
$scope.part2 = true;
}
}
$scope.rsubmit = function() {
if (!$scope.part2)
return $scope.Validate();
// Remove empty members
$scope.members = $scope.members.filter(function(m) {
return ((m.lastname != undefined && m.lastname != "") || (m.firstname != undefined && m.firstname != "") || (m.nickname != undefined && m.nickname != ""));
});
if ($scope.members.length == 0) {
$scope.messageClass = {"text-danger": true};
$scope.message = "Veuillez ajouter au moins un membre dans votre équipe !";
$scope.members.push({});
return;
}
$http({
url: "/registration",
method: "POST",
data: {
teamName: $scope.teamName,
members: $scope.members,
}
}).then(function(response, status, header, config) {
$scope.messageClass = {"text-success": true};
$scope.message = response.data.errmsg;
$rootScope.refresh();
if ($scope.my)
$location.url("/");
}, function(response) {
$scope.messageClass = {"text-danger": true};
console.log(response);
if (response.data && response.data.errmsg)
$scope.message = response.data.errmsg;
else
$scope.message = "Une erreur est survenue lors de l'inscription de l'équipe. Veuillez réessayer dans quelques instants.";
});
}
if ($scope.my) {
$location.url("/");
}
})
.controller("RankController", function($scope, $rootScope) {
$rootScope.current_theme = 0;
$rootScope.current_exercice = 0;

View file

@ -0,0 +1,62 @@
<div class="jumbotron" style="text-indent: 1em">
<p>
Félicitations&nbsp;! vous êtes maintenant authentifié auprès de notre
serveur&nbsp;!
</p>
<p>
Votre équipe n'est pas encore enregistrée sur notre serveur. Afin de
pouvoir participer au challenge, nous vous remercions de bien vouloir
remplir le formulaire d'inscription suivant&nbsp;:
</p>
<form ng-submit="rsubmit()">
<div class="row">
<label for="teamName" class="col col-form-label">Nom d'équipe</label>
<div class="col-sm-10">
<div class="input-group">
<input type="text" class="form-control" id="teamName" ng-model="teamName" placeholder="" autofocus required>
<div class="invalid-feedback">
Veuillez indiquer un nom d'équipe valide.
</div>
<span class="input-group-btn" id="vldBtn">
<button class="btn btn-info" type="button" ng-click="Validate()">Valider</button>
</span>
</div>
</div>
</div>
<div ng-if="part2">
<h4 style="text-indent: 0; margin-top: 20px">
Membres d'équipe
<button class="btn btn-sm btn-success" type="button" ng-click="AddMember()">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter un membre
</button>
</h4>
<p ng-if="message" ng-class="messageClass" ng-bind="message"></p>
<div class="row form-group" ng-repeat="(mid, member) in members">
<div class="col-sm">
<input type="text" class="form-control" ng-model="member.lastname" placeholder="Nom" autofocus>
</div>
<div class="col-sm">
<input type="text" class="form-control" ng-model="member.firstname" placeholder="Prénom">
</div>
<div class="col-sm">
<input type="text" class="form-control" ng-model="member.nickname" placeholder="Pseudo">
</div>
<div class="col-sm">
<input type="text" class="form-control" ng-model="member.company" placeholder="Entreprise">
</div>
<div class="col-sm-auto">
<button class="btn btn-danger" type="button" ng-click="RemoveMember(mid)">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</div>
</div>
<button class="btn btn-info" style="margin-left: 40%;" type="submit">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
S'inscrire
</button>
</div>
</form>
</div>