diff --git a/backend/submission.go b/backend/submission.go
index 12f9c1fa..5d4b922a 100644
--- a/backend/submission.go
+++ b/backend/submission.go
@@ -19,6 +19,7 @@ import (
type ResponsesUpload struct {
Keys map[int64]string `json:"flags"`
MCQs map[int64]bool `json:"mcqs"`
+ MCQJ map[int64]string `json:"justifications"`
}
func treatSubmission(pathname string, team fic.Team, exercice_id string) {
@@ -78,6 +79,25 @@ func treatSubmission(pathname string, team fic.Team, exercice_id string) {
return
}
+ // Handle MCQ justifications: convert to expected keyid
+ for cid, j := range responses.MCQJ {
+ if mcq, choice, err := fic.GetMCQbyChoice(cid); err != nil {
+ log.Println(id, "[ERR] Unable to retrieve mcq from justification:", err)
+ return
+ } else if mcq.IdExercice != exercice.Id {
+ log.Println(id, "[ERR] We retrieve an invalid MCQ: from exercice", mcq.IdExercice, "whereas expected from exercice", exercice.Id)
+ return
+ } else if key, err := mcq.GetJustifiedFlag(exercice, choice); err != nil {
+ log.Println(id, "[ERR] Unable to retrieve mcq justification flag:", err)
+ return
+ } else {
+ if responses.Keys == nil {
+ responses.Keys = map[int64]string{}
+ }
+ responses.Keys[key.Id] = j
+ }
+ }
+
// Check given answers
solved, err := exercice.CheckResponse(cksum[:], responses.Keys, responses.MCQs, team)
if err != nil {
diff --git a/frontend/static/js/challenge.js b/frontend/static/js/challenge.js
index 11ba9d54..0d755ab2 100644
--- a/frontend/static/js/challenge.js
+++ b/frontend/static/js/challenge.js
@@ -268,11 +268,12 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
});
$scope.ssubmit = function() {
- var resp = {"flags":{}}
+ var resp = {}
var check = undefined
if ($scope.my.exercices[$rootScope.current_exercice].flags && Object.keys($scope.my.exercices[$rootScope.current_exercice].flags).length)
{
+ resp["flags"] = {};
angular.forEach($scope.my.exercices[$rootScope.current_exercice].flags, function(flag,kid) {
if (flag.found == null) {
if (flag.soluce !== undefined) {
@@ -293,7 +294,6 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
var soluce = "";
resp["mcqs"] = {};
angular.forEach($scope.my.exercices[$rootScope.current_exercice].mcqs, function(mcq) {
- var nid = 0;
if (mcq.solved == null) {
angular.forEach(mcq.choices, function(choice, cid) {
if (mcq.soluce !== undefined) {
@@ -304,10 +304,10 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"])
if (choice.value) {
resp["mcqs"][cid] = choice.value;
if (mcq.justify !== undefined) {
+ if (resp["justifications"] == undefined)
+ resp["justifications"] = {};
if (choice.justify)
- resp["flags"][mcq.justify[nid++]] = choice.justify;
- else if (!choice.solved)
- nid++;
+ resp["justifications"][cid] = choice.justify;
}
}
}
diff --git a/frontend/static/views/defi.html b/frontend/static/views/defi.html
index c893db2e..aa3cdbe1 100644
--- a/frontend/static/views/defi.html
+++ b/frontend/static/views/defi.html
@@ -94,7 +94,7 @@
-
+
diff --git a/libfic/flag.go b/libfic/flag.go
index e13b8e60..10249ad6 100644
--- a/libfic/flag.go
+++ b/libfic/flag.go
@@ -52,6 +52,12 @@ func (e Exercice) GetFlags() ([]Flag, error) {
}
}
+// GetFlagByLabel returns a flag matching the given label.
+func (e Exercice) GetFlagByLabel(label string) (k Flag, err error) {
+ err = DBQueryRow("SELECT id_flag, id_exercice, type, help, ignorecase, validator_regexp, cksum FROM exercice_flags WHERE type = ? AND id_exercice = ?", label, e.Id).Scan(&k.Id, &k.IdExercice, &k.Label, &k.Help, &k.IgnoreCase, &k.ValidatorRegexp, &k.Checksum)
+ return
+}
+
// getHashedFlag calculates the expected checksum for the given raw_value.
func getHashedFlag(raw_value []byte) [blake2b.Size]byte {
hash := blake2b.Sum512(raw_value)
diff --git a/libfic/mcq.go b/libfic/mcq.go
index 205da856..067858af 100644
--- a/libfic/mcq.go
+++ b/libfic/mcq.go
@@ -66,6 +66,35 @@ func (e Exercice) GetMCQ() ([]MCQ, error) {
}
}
+// GetMCQbyChoice returns the MCQ corresponding to a choice ID.
+func GetMCQbyChoice(cid int64) (m MCQ, c MCQ_entry, err error) {
+ if errr := DBQueryRow("SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_mcq = (SELECT id_mcq FROM mcq_entries WHERE id_mcq_entry = ?)", cid).Scan(&m.Id, &m.IdExercice, &m.Title); err != nil {
+ return MCQ{}, MCQ_entry{}, errr
+ }
+
+ if entries_rows, errr := DBQuery("SELECT id_mcq_entry, label, response FROM mcq_entries WHERE id_mcq = ?", m.Id); err != nil {
+ return MCQ{}, MCQ_entry{}, errr
+ } else {
+ defer entries_rows.Close()
+
+ for entries_rows.Next() {
+ var e MCQ_entry
+
+ if err = entries_rows.Scan(&e.Id, &e.Label, &e.Response); err != nil {
+ return
+ }
+
+ if e.Id == cid {
+ c = e
+ }
+
+ m.Entries = append(m.Entries, e)
+ }
+ }
+
+ return
+}
+
// AddMCQ creates and fills a new struct MCQ and registers it into the database.
func (e Exercice) AddMCQ(title string) (MCQ, error) {
if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, title) VALUES (?, ?)", e.Id, title); err != nil {
@@ -145,6 +174,11 @@ func (e Exercice) WipeMCQs() (int64, error) {
}
}
+// GetJustifiedFlag searchs for a flag in the scope of the given exercice.
+func (m MCQ) GetJustifiedFlag(e Exercice, c MCQ_entry) (Flag, error) {
+ return e.GetFlagByLabel("%" + m.Title + "%" + c.Label)
+}
+
// Check if the given vals are the expected ones to validate this flag.
func (m MCQ) Check(vals map[int64]bool) int {
diff := 0
diff --git a/libfic/team_my.go b/libfic/team_my.go
index 48e4ea8e..da3220c5 100644
--- a/libfic/team_my.go
+++ b/libfic/team_my.go
@@ -23,7 +23,7 @@ type myTeamHint struct {
}
type myTeamMCQ struct {
Title string `json:"title"`
- Justify []int64 `json:"justify,omitempty"`
+ Justify bool `json:"justify,omitempty"`
Choices map[int64]string `json:"choices,omitempty"`
Solved *time.Time `json:"solved,omitempty"`
PSolved map[int64]int `json:"checks_solved,omitempty"`
@@ -211,8 +211,6 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
soluce := ""
solved_justify := true
- var nb_gen_justify_id int64
- var max_justify_id int64
for _, e := range mcq.Entries {
m.Choices[e.Id] = e.Label
@@ -222,31 +220,18 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
soluce += "f"
}
if v, ok := justifiedMCQ[m.Title + "%" + e.Label]; ok {
- if m.Justify == nil {
- m.Justify = []int64{}
- }
+ m.Justify = true
if t == nil {
soluce += hex.EncodeToString(v)
}
- if v, ok := justifiedMCQ_ids[m.Title + "%" + e.Label]; ok {
+ if _, ok := justifiedMCQ_ids[m.Title + "%" + e.Label]; ok {
solved_justify = false
- m.Justify = append(m.Justify, v)
- if v > max_justify_id {
- max_justify_id = v
- }
}
- } else {
- nb_gen_justify_id += 1
}
}
- // Fill the rest of the array with factice values in order to hide number of valid choices
- for i := int64(0); i < nb_gen_justify_id; i++ {
- m.Justify = append(m.Justify, max_justify_id + 1 + i)
- }
-
if t != nil {
if solved_justify {
m.Solved = t.HasPartiallyRespond(mcq)