Dependancy between flags

This commit is contained in:
nemunaire 2018-12-02 19:21:07 +01:00
commit f9abdd23c6
8 changed files with 111 additions and 1 deletions

View file

@ -172,6 +172,16 @@ CREATE TABLE IF NOT EXISTS exercice_flags(
cksum BINARY(64) NOT NULL,
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil {
return err
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS exercice_flags_deps(
id_flag INTEGER NOT NULL,
id_flag_dep INTEGER NOT NULL,
FOREIGN KEY(id_flag) REFERENCES exercice_flags(id_flag),
FOREIGN KEY(id_flag_dep) REFERENCES exercice_flags(id_flag)
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin;
`); err != nil {
return err
}

View file

@ -124,6 +124,8 @@ func (k Flag) Update() (int64, error) {
func (k Flag) Delete() (int64, error) {
if _, err := DBExec("DELETE FROM exercice_files_deps WHERE id_flag = ?", k.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_flags_deps WHERE id_flag = ?", k.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM flag_choices WHERE id_flag = ?", k.Id); err != nil {
return 0, err
} else if res, err := DBExec("DELETE FROM exercice_flags WHERE id_flag = ?", k.Id); err != nil {
@ -139,6 +141,8 @@ func (k Flag) Delete() (int64, error) {
func (e Exercice) WipeFlags() (int64, error) {
if _, err := DBExec("DELETE FROM exercice_files_deps WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_flags_deps WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM flag_choices WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id); err != nil {
return 0, err
} else if res, err := DBExec("DELETE FROM exercice_flags WHERE id_exercice = ?", e.Id); err != nil {
@ -150,6 +154,35 @@ func (e Exercice) WipeFlags() (int64, error) {
}
}
// AddDepend insert a new dependency to a given flag.
func (k Flag) AddDepend(d Flag) (err error) {
_, err = DBExec("INSERT INTO exercice_flags_deps (id_flag, id_flag_dep) VALUES (?, ?)", k.Id, d.Id)
return
}
// GetDepends retrieve the flag's dependency list.
func (k Flag) GetDepends() ([]Flag, error) {
if rows, err := DBQuery("SELECT id_flag_dep FROM exercice_flags_deps WHERE id_flag = ?", k.Id); err != nil {
return nil, err
} else {
defer rows.Close()
var deps = make([]Flag, 0)
for rows.Next() {
var d int64
if err := rows.Scan(&d); err != nil {
return nil, err
}
deps = append(deps, Flag{d, k.IdExercice, "", "", false, nil, []byte{}})
}
if err := rows.Err(); err != nil {
return nil, err
}
return deps, nil
}
}
// Check if the given val is the expected one for this flag.
func (k Flag) Check(val []byte) bool {
if k.IgnoreCase {

View file

@ -34,7 +34,7 @@ func ResetGame() (error) {
// ResetExercices wipes out all challenges (both attempts and statements).
func ResetExercices() (error) {
return truncateTable("team_hints", "exercice_files_deps", "exercice_files", "flag_found", "flag_choices", "exercice_flags", "exercice_solved", "exercice_tries", "exercice_hints", "mcq_found", "mcq_entries", "exercice_mcq", "exercice_tags", "exercices", "themes")
return truncateTable("team_hints", "exercice_files_deps", "exercice_files", "flag_found", "exercice_flags_deps", "flag_choices", "exercice_flags", "exercice_solved", "exercice_tries", "exercice_hints", "mcq_found", "mcq_entries", "exercice_mcq", "exercice_tags", "exercices", "themes")
}
// ResetTeams wipes out all teams, incluings members and attempts.

View file

@ -124,6 +124,25 @@ func (t Team) CanDownload(f EFile) bool {
}
}
// CanSeeFlag checks if the Team has access to the given flag.
func (t Team) CanSeeFlag(k Flag) bool {
if deps, err := k.GetDepends(); err != nil {
log.Printf("Unable to retrieve flag dependencies: %s\n", err)
return false
} else {
res := true
for _, dep := range deps {
if t.HasPartiallySolved(dep) == nil {
res = false
break
}
}
return res
}
}
// NbTry retrieves the number of attempts made by the Team to the given challenge.
func NbTry(t *Team, e Exercice) int {
var cnt *int

View file

@ -175,6 +175,11 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
for _, k := range flags {
var flag myTeamFlag
if t != nil && !t.CanSeeFlag(k) {
// Dependancy missing, skip the flag for now
continue
}
if fl, err := k.GetMCQJustification(); err == nil {
fl.Checksum = k.Checksum
if t != nil && t.HasPartiallySolved(k) != nil {