frontend: public part now validate through blake2b.js flags and MCQs
This commit is contained in:
parent
8ac2776cca
commit
5c742834ea
@ -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>
|
||||||
|
2594
frontend/static/js/blake2b.js
Normal file
2594
frontend/static/js/blake2b.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -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) {
|
||||||
|
@ -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 }} :</label>
|
<label for="sol_{{ kid }}">{{ key.label }} :</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> :
|
|
||||||
</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 : <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 : <a ng-href="{{ my.exercices[current_exercice].video_uri }}">{{ my.exercices[current_exercice].video_uri }}</a>.
|
||||||
</iframe>
|
</iframe>
|
||||||
</div>
|
</div>
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user