frontend: public part now validate through blake2b.js flags and MCQs

This commit is contained in:
nemunaire 2018-11-28 04:15:14 +01:00
parent 8ac2776cca
commit 5c742834ea
5 changed files with 2675 additions and 37 deletions

View File

@ -138,5 +138,6 @@
<script src="/js/i18n/angular-locale_fr-fr.js"></script> <script src="/js/i18n/angular-locale_fr-fr.js"></script>
<script src="/js/challenge.js"></script> <script src="/js/challenge.js"></script>
<script src="/js/common.js"></script> <script src="/js/common.js"></script>
<script src="/js/blake2b.js" defer></script>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load Diff

View File

@ -266,23 +266,59 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
$scope.ssubmit = function() { $scope.ssubmit = function() {
var resp = {} var resp = {}
var check = undefined
if ($scope.my.exercices[$rootScope.current_exercice].flags && Object.keys($scope.my.exercices[$rootScope.current_exercice].flags).length) if ($scope.my.exercices[$rootScope.current_exercice].flags && Object.keys($scope.my.exercices[$rootScope.current_exercice].flags).length)
{ {
resp["flags"] = {}; resp["flags"] = {};
angular.forEach($scope.my.exercices[$rootScope.current_exercice].flags, function(flag,kid) { angular.forEach($scope.my.exercices[$rootScope.current_exercice].flags, function(flag,kid) {
if (flag.found == null) {
if (flag.soluce !== undefined) {
if (check === undefined) check = true;
if (flag.value && flag.soluce == b2sum(flag.value))
flag.found = new Date();
check &= flag.found;
} else {
resp["flags"][kid] = flag.value; resp["flags"][kid] = flag.value;
}
}
}); });
} }
if ($scope.my.exercices[$rootScope.current_exercice].mcqs && Object.keys($scope.my.exercices[$rootScope.current_exercice].mcqs).length) if ($scope.my.exercices[$rootScope.current_exercice].mcqs && Object.keys($scope.my.exercices[$rootScope.current_exercice].mcqs).length)
{ {
var soluce = "";
resp["mcqs"] = {}; resp["mcqs"] = {};
angular.forEach($scope.my.exercices[$rootScope.current_exercice].mcqs, function(mcq) { angular.forEach($scope.my.exercices[$rootScope.current_exercice].mcqs, function(mcq) {
if (mcq.solved == null) {
angular.forEach(mcq.choices, function(choice, cid) { angular.forEach(mcq.choices, function(choice, cid) {
if (mcq.soluce !== undefined) {
if (check === undefined) check = true;
soluce += choice.value ? "t" : "f";
} else {
if (choice.value) resp["mcqs"][cid] = choice.value; if (choice.value) resp["mcqs"][cid] = choice.value;
}) }
}); });
if (mcq.soluce !== undefined) {
if (mcq.soluce == b2sum(soluce))
mcq.solved = new Date();
check &= mcq.solved;
}
}
});
}
if (check !== undefined)
{
$scope.my.exercices[$rootScope.current_exercice].tries += 1;
$scope.my.exercices[$rootScope.current_exercice].solved_time = new Date();
if (check) {
$scope.my.exercices[$rootScope.current_exercice].solved = true;
}
return;
} }
$http({ url: "/submit/" + $rootScope.current_exercice, method: "POST", data: resp }).then(function(response, status, header, config) { $http({ url: "/submit/" + $rootScope.current_exercice, method: "POST", data: resp }).then(function(response, status, header, config) {

View File

@ -67,12 +67,12 @@
</div> </div>
<div class="col-xl mb-5"> <div class="col-xl mb-5">
<div class="card border-danger" ng-if="my.team_id && my.exercices[current_exercice] && !(my.exercices[current_exercice].solved)"> <div class="card border-danger" ng-if="my.exercices[current_exercice] && !(my.exercices[current_exercice].solved)">
<div class="card-header bg-danger text-white"> <div class="card-header bg-danger text-white">
<span class="glyphicon glyphicon-flag" aria-hidden="true"></span> Faire son rapport <span class="glyphicon glyphicon-flag" aria-hidden="true"></span> Faire son rapport
</div> </div>
<ul class="list-group" ng-if="(my.exercices[current_exercice].tries || my.exercices[current_exercice].submitted || sberr)"> <ul class="list-group" ng-if="(my.exercices[current_exercice].tries || my.exercices[current_exercice].submitted || sberr)">
<li class="list-group-item text-warning" ng-if="my.exercices[current_exercice].tries"><ng-pluralize count="my.exercices[current_exercice].tries" when="{'one': '{} tentative effectuée', 'other': '{} tentatives effectuées'}"></ng-pluralize>. Dernière solution envoyée à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}. <span ng-if="my.exercices[current_exercice].solve_dist"><ng-pluralize count="my.exercices[current_exercice].solve_dist" when="{'one': '{} réponse erronée', 'other': '{} réponses erronées'}"></ng-pluralize>.</span></li> <li class="list-group-item text-warning" ng-if="my.exercices[current_exercice].solved_time && my.exercices[current_exercice].tries"><ng-pluralize count="my.exercices[current_exercice].tries" when="{'one': '{} tentative effectuée', 'other': '{} tentatives effectuées'}"></ng-pluralize>. Dernière solution envoyée à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}. <span ng-if="my.exercices[current_exercice].solve_dist"><ng-pluralize count="my.exercices[current_exercice].solve_dist" when="{'one': '{} réponse erronée', 'other': '{} réponses erronées'}"></ng-pluralize>.</span></li>
<li class="list-group-item" ng-class="messageClass" ng-if="my.exercices[current_exercice].submitted || sberr"><strong ng-if="!sberr">Votre solution a bien été envoyée !</strong><strong ng-if="sberr">{{ sberr }}</strong> {{ message }}</li> <li class="list-group-item" ng-class="messageClass" ng-if="my.exercices[current_exercice].submitted || sberr"><strong ng-if="!sberr">Votre solution a bien été envoyée !</strong><strong ng-if="sberr">{{ sberr }}</strong> {{ message }}</li>
</ul> </ul>
<div class="card-body" ng-if="!my.exercices[current_exercice].submitted || sberr"> <div class="card-body" ng-if="!my.exercices[current_exercice].submitted || sberr">
@ -80,7 +80,7 @@
<div class="form-group" ng-repeat="(kid,key) in my.exercices[current_exercice].flags"> <div class="form-group" ng-repeat="(kid,key) in my.exercices[current_exercice].flags">
<label for="sol_{{ kid }}">{{ key.label }}&nbsp;:</label> <label for="sol_{{ kid }}">{{ key.label }}&nbsp;:</label>
<input type="text" class="form-control" id="sol_{{ kid }}" autocomplete="off" name="sol_{{ kid }}" ng-model="key.value" ng-if="!key.found"> <input type="text" class="form-control" id="sol_{{ kid }}" autocomplete="off" name="sol_{{ kid }}" ng-model="key.value" ng-if="!key.found">
<small class="form-text text-muted" ng-if="key.help.length > 0" ng-bind="key.help"></small> <small class="form-text text-muted" ng-if="!key.found && key.help.length > 0" ng-bind="key.help"></small>
<span class="glyphicon glyphicon-ok form-control-feedback text-success" aria-hidden="true" ng-if="key.found" title="Flag trouvé à {{ key.found | date:'mediumTime'}}"></span> <span class="glyphicon glyphicon-ok form-control-feedback text-success" aria-hidden="true" ng-if="key.found" title="Flag trouvé à {{ key.found | date:'mediumTime'}}"></span>
</div> </div>
@ -100,7 +100,7 @@
</div> </div>
</div> </div>
<div class="card border-success" ng-if="(my.team_id && my.exercices[current_exercice].solved)"> <div class="card border-success" ng-if="my.exercices[current_exercice].solved">
<div class="card-header bg-success text-white"> <div class="card-header bg-success text-white">
<span class="glyphicon glyphicon-flag" aria-hidden="true"></span> Challenge réussi ! <span class="glyphicon glyphicon-flag" aria-hidden="true"></span> Challenge réussi !
</div> </div>
@ -112,20 +112,13 @@
</div> </div>
</div> </div>
<div class="card border-success" ng-if="(!my.team_id && my.exercices[current_exercice].keys)"> <div class="card border-success mt-2" ng-if="my.exercices[current_exercice].video_uri">
<div class="card-header bg-success text-white"> <div class="card-header bg-success text-white">
<span class="glyphicon glyphicon-flag" aria-hidden="true"></span> Solution du challenge <span class="glyphicon glyphicon-blackboard" aria-hidden="true"></span> Solution du challenge
</div> </div>
<div class="card-body"> <div class="card-body">
<p>
Vérifiez les clefs que vous trouvez en comparant leur <a href="https://blake2.net/">BLAKE2b</a>&nbsp;:
</p>
<dl class="dl-horizontal" ng-repeat="key in my.exercices[current_exercice].keys">
<dt title="{{ key.slice(128) }}">{{ key.slice(128) }}</dt>
<dd><samp class="cksum">{{ key.slice(0, 128) }}</samp></dd>
</dl>
<div class="embed-responsive embed-responsive-16by9"> <div class="embed-responsive embed-responsive-16by9">
<iframe type="text/html" ng-if="my.exercices[current_exercice].video_uri" ng-src="{{ my.exercices[current_exercice].video_uri }}" class="embed-responsive-item"> <iframe type="text/html" ng-src="{{ my.exercices[current_exercice].video_uri }}" class="embed-responsive-item">
Regardez la vidéo de résolution de cet exercice&nbsp;: <a ng-href="{{ my.exercices[current_exercice].video_uri }}">{{ my.exercices[current_exercice].video_uri }}</a>. Regardez la vidéo de résolution de cet exercice&nbsp;: <a ng-href="{{ my.exercices[current_exercice].video_uri }}">{{ my.exercices[current_exercice].video_uri }}</a>.
</iframe> </iframe>
</div> </div>

View File

@ -26,23 +26,25 @@ type myTeamMCQ struct {
Justify bool `json:"justify,omitempty"` Justify bool `json:"justify,omitempty"`
Choices map[int64]string `json:"choices,omitempty"` Choices map[int64]string `json:"choices,omitempty"`
Solved *time.Time `json:"solved,omitempty"` Solved *time.Time `json:"solved,omitempty"`
Soluce string `json:"soluce,omitempty"`
} }
type myTeamFlag struct { type myTeamFlag struct {
Label string `json:"label"` Label string `json:"label"`
Help string `json:"help,omitempty"` Help string `json:"help,omitempty"`
Solved *time.Time `json:"found,omitempty"` Solved *time.Time `json:"found,omitempty"`
Soluce []byte `json:"soluce,omitempty"` Soluce string `json:"soluce,omitempty"`
} }
type myTeamExercice struct { type myTeamExercice struct {
ThemeId int `json:"theme_id"` ThemeId int `json:"theme_id"`
Statement string `json:"statement"` Statement string `json:"statement"`
Overview string `json:"overview,omitempty"`
Hints []myTeamHint `json:"hints,omitempty"` Hints []myTeamHint `json:"hints,omitempty"`
Gain int `json:"gain"` Gain int `json:"gain"`
Files []myTeamFile `json:"files,omitempty"` Files []myTeamFile `json:"files,omitempty"`
Flags map[int64]myTeamFlag `json:"flags,omitempty"` Flags map[int64]myTeamFlag `json:"flags,omitempty"`
MCQs map[int64]myTeamMCQ `json:"mcqs,omitempty"` MCQs map[int64]myTeamMCQ `json:"mcqs,omitempty"`
SolveDist int64 `json:"solve_dist,omitempty"` SolveDist int64 `json:"solve_dist,omitempty"`
SolvedTime time.Time `json:"solved_time,omitempty"` SolvedTime *time.Time `json:"solved_time,omitempty"`
SolvedRank int64 `json:"solved_rank,omitempty"` SolvedRank int64 `json:"solved_rank,omitempty"`
Tries int64 `json:"tries,omitempty"` Tries int64 `json:"tries,omitempty"`
VideoURI string `json:"video_uri,omitempty"` VideoURI string `json:"video_uri,omitempty"`
@ -94,22 +96,20 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
} }
if t == nil { if t == nil {
if e.Overview != "" { exercice.Overview = e.Overview
exercice.Statement = e.Overview
}
exercice.VideoURI = e.VideoURI exercice.VideoURI = e.VideoURI
exercice.SolvedRank = 1
exercice.Tries = e.TriedCount() exercice.Tries = e.TriedCount()
exercice.Gain = int(float64(e.Gain) * e.Coefficient) exercice.Gain = int(float64(e.Gain) * e.Coefficient)
} else { } else {
var solved bool solved, stime := t.HasSolved(e)
solved, exercice.SolvedTime = t.HasSolved(e) exercice.SolvedTime = &stime
exercice.SolvedRank, _ = t.GetSolvedRank(e) exercice.SolvedRank, _ = t.GetSolvedRank(e)
if solved { if solved {
exercice.Tries, _ = t.CountTries(e) exercice.Tries, _ = t.CountTries(e)
} else { } else {
exercice.Tries, exercice.SolvedTime = t.CountTries(e) exercice.Tries, stime = t.CountTries(e)
exercice.SolvedTime = &stime
if exercice.Tries > 0 { if exercice.Tries > 0 {
exercice.SolveDist = t.LastTryDist(e) exercice.SolveDist = t.LastTryDist(e)
} }
@ -154,7 +154,7 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
// Expose exercice flags // Expose exercice flags
var justifiedMCQ map[string]bool var justifiedMCQ map[string][]byte
exercice.Flags = map[int64]myTeamFlag{} exercice.Flags = map[int64]myTeamFlag{}
if flags, err := e.GetFlags(); err != nil { if flags, err := e.GetFlags(); err != nil {
@ -164,10 +164,10 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
var flag myTeamFlag var flag myTeamFlag
if k.Label[0] == '%' { if k.Label[0] == '%' {
justifiedMCQ[k.Label[1:]] = true justifiedMCQ[k.Label[1:]] = k.Checksum
continue continue
} else if t == nil { } else if t == nil {
flag.Soluce = k.Checksum flag.Soluce = hex.EncodeToString(k.Checksum)
} else if PartialValidation { } else if PartialValidation {
flag.Solved = t.HasPartiallySolved(k) flag.Solved = t.HasPartiallySolved(k)
} }
@ -187,19 +187,33 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
return nil, err return nil, err
} else { } else {
for _, mcq := range mcqs { for _, mcq := range mcqs {
choices := map[int64]string{} m := myTeamMCQ{
justified := false Title: mcq.Title,
for _, e := range mcq.Entries { Choices: map[int64]string{},
choices[e.Id] = e.Label
if _, ok := justifiedMCQ[m.Title + "%" + e.Label]; ok {
justified = true
}
} }
m := myTeamMCQ{mcq.Title, justified, choices, nil} soluce := ""
for _, e := range mcq.Entries {
m.Choices[e.Id] = e.Label
if e.Response {
soluce += "t"
} else {
soluce += "f"
}
if v, ok := justifiedMCQ[m.Title + "%" + e.Label]; ok {
m.Justify = true
if t == nil {
soluce += hex.EncodeToString(v)
}
}
}
if t != nil { if t != nil {
m.Solved = t.HasPartiallyRespond(mcq) m.Solved = t.HasPartiallyRespond(mcq)
} else {
h := getHashedFlag([]byte(soluce))
m.Soluce = hex.EncodeToString(h[:])
} }
exercice.MCQs[mcq.Id] = m exercice.MCQs[mcq.Id] = m