From a0aa8d467ce8a9ce13ce5a2cff4f22d0c13b9c34 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 23 Jan 2025 20:06:34 +0000 Subject: [PATCH 01/19] chore(deps): update module github.com/go-git/go-git/v5 to v5.13.2 --- go.mod | 10 +++++----- go.sum | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 6ea2d7d9..5fd8bfeb 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/cenkalti/dominantcolor v1.0.3 github.com/gin-contrib/sessions v1.0.2 github.com/gin-gonic/gin v1.10.0 - github.com/go-git/go-git/v5 v5.13.1 + github.com/go-git/go-git/v5 v5.13.2 github.com/go-sql-driver/mysql v1.8.1 github.com/google/gopacket v1.1.19 github.com/studio-b12/gowebdav v0.10.0 @@ -28,7 +28,7 @@ require ( dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v1.1.3 // indirect + github.com/ProtonMail/go-crypto v1.1.5 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect github.com/asticode/go-astikit v0.20.0 // indirect github.com/asticode/go-astits v1.8.0 // indirect @@ -47,7 +47,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.6.1 // indirect + github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect @@ -69,7 +69,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.0 // indirect @@ -79,7 +79,7 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/net v0.34.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/go.sum b/go.sum index 2b49b734..b6abb6ab 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0k github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= +github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= @@ -168,6 +170,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= +github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= +github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= @@ -199,6 +203,8 @@ github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZt github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -352,6 +358,8 @@ github.com/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI= github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= +github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -659,6 +667,8 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= From a4001759f6a8669eb84b0b8f93aa11f87aada921 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 14 Jan 2025 17:38:03 +0100 Subject: [PATCH 02/19] ui: Fix file disclaimer not showing --- .../fic/src/lib/components/ExerciceDownloads.svelte | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/fic/src/lib/components/ExerciceDownloads.svelte b/frontend/fic/src/lib/components/ExerciceDownloads.svelte index c05a45a0..14ae7e7e 100644 --- a/frontend/fic/src/lib/components/ExerciceDownloads.svelte +++ b/frontend/fic/src/lib/components/ExerciceDownloads.svelte @@ -33,9 +33,9 @@

{file.name}

- {#if file.disclamer} -
- {file.disclamer} + {#if file.disclaimer} +
+ {file.disclaimer}
{/if} @@ -61,10 +61,10 @@ {/if} From 96707e3a2935bc142a77251fdaa7816b324884b7 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 15:14:29 +0100 Subject: [PATCH 03/19] configs: Detect mkisofs --- configs/gen_metadata.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/gen_metadata.sh b/configs/gen_metadata.sh index ccb2f4fe..f51984eb 100755 --- a/configs/gen_metadata.sh +++ b/configs/gen_metadata.sh @@ -20,6 +20,8 @@ escape_newline () { sed 's/$/\\n/g' | tr -d '\n' } +which mkisofs > /dev/null 2> /dev/null || { echo "Please install genisoimage (Debian/Ubuntu) or cdrkit (Alpine)" >&2; exit 1; } + if [ $# -gt 0 ] then which jq > /dev/null 2> /dev/null || { echo "Please install jq" >&2; exit 1; } From 4ec4f47951acc7ff918a15b047a1b2205178ae92 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 15:15:48 +0100 Subject: [PATCH 04/19] fickit: keep last metadata iso when dm-crypt key change --- configs/update_imgs.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/update_imgs.sh b/configs/update_imgs.sh index 13866c22..fa507cee 100644 --- a/configs/update_imgs.sh +++ b/configs/update_imgs.sh @@ -21,6 +21,8 @@ OLD_KEY=$(cat /run/config/dm-crypt/key) [ "${NEW_KEY}" != "${OLD_KEY}" ] && { read -p "DM-CRYPT key changed in metadata, are you sure you want to erase it? (y/N) " V [ "$V" != "y" ] && [ "$V" != "Y" ] && while true; do + mv /boot/imgs/fickit-metadata.iso /boot/imgs/fickit-metadata.iso.skipped + cp /boot/imgs/fickit-metadata.iso.bak /boot/imgs/fickit-metadata.iso echo echo "Metadata drive not erased" echo From ffb69663b6b4be9d76c520cee76102f30e74f8e3 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 19:09:57 +0100 Subject: [PATCH 05/19] fickit: Initiate sshd config with keys on first run --- fickit-backend.yml | 10 +++++++++- fickit-frontend.yml | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/fickit-backend.yml b/fickit-backend.yml index be0ecef7..16a57215 100644 --- a/fickit-backend.yml +++ b/fickit-backend.yml @@ -153,6 +153,15 @@ onboot: mkdir: - /var/lib/fic/secrets + - name: create-ssh-keys + image: nemunaire/rsync:a3d76b2dd0a9ad73be44dc77ad765b20d96a3285 + command: ["/bin/sh", "-c", "touch /etc/ssh/sshd_config && ssh-keygen -A"] + binds: + - /var/lib/fic/ssh:/etc/ssh + runtime: + mkdir: + - /var/lib/fic/ssh + services: # - name: getty # image: linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b @@ -361,7 +370,6 @@ services: - /var/lib/fic/files - /var/lib/fic/pki/shared - /var/lib/fic/settingsdist - - /var/lib/fic/ssh - /var/lib/fic/submissions - /var/lib/fic/teams - /var/log/frontend diff --git a/fickit-frontend.yml b/fickit-frontend.yml index d2c558a2..c50b9141 100644 --- a/fickit-frontend.yml +++ b/fickit-frontend.yml @@ -136,6 +136,15 @@ onboot: - /etc/iptables/rules.v6:/etc/iptables/rules.v6:ro net: /run/netns/sshd + - name: create-ssh-keys + image: nemunaire/rsync:a3d76b2dd0a9ad73be44dc77ad765b20d96a3285 + command: ["/bin/sh", "-c", "touch /etc/ssh/sshd_config && ssh-keygen -A"] + binds: + - /var/lib/fic/ssh:/etc/ssh + runtime: + mkdir: + - /var/lib/fic/ssh + services: # - name: getty # image: linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b @@ -257,7 +266,6 @@ services: - /var/lib/fic/files - /var/lib/fic/pki - /var/lib/fic/settingsdist - - /var/lib/fic/ssh - /var/lib/fic/submissions - /var/lib/fic/teams From c28d974105b3c766daa930e9da49f7b5fed0052c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 19:10:37 +0100 Subject: [PATCH 06/19] fickit: Update images --- fickit-prepare.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fickit-prepare.yml b/fickit-prepare.yml index 64f7b3ba..b8472acb 100644 --- a/fickit-prepare.yml +++ b/fickit-prepare.yml @@ -7,9 +7,9 @@ kernel: init: - nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67 - nemunaire/syslinux:086f221f281d577d300949aa1094fb20c5cd90dc - - linuxkit/format:3c858f0cf42a2b14441bfb5c266b78f14d2b75a4 - - linuxkit/dm-crypt:19fa6affe9da03afc91694e36d72a4924c65a0e0 - - linuxkit/metadata:f35b5aafc7d19bb6a44a900840727902dad78e44 + - linuxkit/format:8f487d728959192289e0783784fc2b185eadbc82 + - linuxkit/dm-crypt:ad2a05dcffa28ef809a61aa27ba230c82f02f603 + - linuxkit/metadata:83cda7b43112b201613084ea8b7fab585b6e5549 - alpine:latest files: From 407b67f4c22402a0627b4ec0e152f8cbe8c20705 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 19:10:58 +0100 Subject: [PATCH 07/19] sync: Ensure placeholder and raw are not the same --- admin/sync/exercice_keys.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/admin/sync/exercice_keys.go b/admin/sync/exercice_keys.go index 8404df86..d4a88f3c 100644 --- a/admin/sync/exercice_keys.go +++ b/admin/sync/exercice_keys.go @@ -279,6 +279,7 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau } type importFlag struct { + origin ExerciceFlag Line int Flag fic.Flag JustifyOf *fic.MCQ_entry @@ -392,8 +393,9 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl errs = multierr.Append(errs, berrs) if addedFlag != nil { ret = append(ret, importFlag{ - Line: nline + 1, - Flag: addedFlag, + origin: flag, + Line: nline + 1, + Flag: addedFlag, }) } } else if flag.Type == "key" || strings.HasPrefix(flag.Type, "number") || flag.Type == "text" || flag.Type == "ucq" || flag.Type == "radio" || flag.Type == "vector" { @@ -401,6 +403,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl errs = multierr.Append(errs, berrs) if addedFlag != nil { ret = append(ret, importFlag{ + origin: flag, Line: nline + 1, Flag: *addedFlag, Choices: choices, @@ -462,6 +465,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl errs = multierr.Append(errs, berrs) if addedFlag != nil { ret = append(ret, importFlag{ + origin: flag, Line: nline + 1, Flag: *addedFlag, JustifyOf: entry, @@ -479,8 +483,9 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl } ret = append([]importFlag{importFlag{ - Line: nline + 1, - Flag: &addedFlag, + origin: flag, + Line: nline + 1, + Flag: &addedFlag, }}, ret...) } return @@ -570,6 +575,10 @@ func CheckExerciceFlags(i Importer, exercice *fic.Exercice, files []string, exce if int64(fk.ChoicesCost) >= exercice.Gain { errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag's choice_cost is higher than exercice gain"))) } + + if raw, ok := flag.origin.Raw.(string); ok && raw == fk.Placeholder { + errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag's placeholder and raw are identical"))) + } } // Check dependency loop From 24686a6a24bda8d194aa064ed7aee3b961ada939 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 23:47:35 +0100 Subject: [PATCH 08/19] admin: Fix check file on disk for compressed files --- admin/static/views/file-list.html | 8 ++++---- libfic/file.go | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/admin/static/views/file-list.html b/admin/static/views/file-list.html index cd0d36a7..83a3242c 100644 --- a/admin/static/views/file-list.html +++ b/admin/static/views/file-list.html @@ -30,13 +30,13 @@
- + {{ file[field] }} - - {{ file.checksum | bto16 }} -
{{ file.checksum_shown | bto16 }}
+ +
{{ file.checksum | bto16 }}
+
{{ file.checksum_shown | bto16 }}
diff --git a/libfic/file.go b/libfic/file.go index 4e5bf37f..d39bb6b0 100644 --- a/libfic/file.go +++ b/libfic/file.go @@ -392,7 +392,12 @@ func (f *EFile) GetDepends() ([]Flag, error) { // CheckFileOnDisk recalculates the hash of the file on disk. func (f *EFile) CheckFileOnDisk() error { - if _, size, err := checkFileHash(path.Join(FilesDir, f.Path), f.Checksum); err != nil { + firstChecksum := f.Checksum + if len(f.ChecksumShown) > 0 { + firstChecksum = f.ChecksumShown + } + + if _, size, err := checkFileHash(path.Join(FilesDir, f.Path), firstChecksum); size > 0 && err != nil { return err } else if size == 0 { if _, _, err := checkFileHash(path.Join(FilesDir, f.Path+".gz"), f.Checksum); err != nil { @@ -400,9 +405,17 @@ func (f *EFile) CheckFileOnDisk() error { } else { return nil } - } else { - return nil + } else if err != nil { + return err } + + if _, err := os.Stat(path.Join(FilesDir, f.Path+".gz")); !os.IsNotExist(err) { + if _, _, err = checkFileHash(path.Join(FilesDir, f.Path+".gz"), f.Checksum); err != nil { + return err + } + } + + return nil } // GunzipFileOnDisk gunzip a compressed file. From 57c3cd8fd65a001024032a89967f28b82bd32ad6 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 23:48:14 +0100 Subject: [PATCH 09/19] admin: Fix mcq entry update --- libfic/mcq.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfic/mcq.go b/libfic/mcq.go index 82315479..04bf3fd9 100644 --- a/libfic/mcq.go +++ b/libfic/mcq.go @@ -207,7 +207,7 @@ func (m *MCQ) AddEntry(e *MCQ_entry) (*MCQ_entry, error) { // Update applies modifications back to the database. func (n *MCQ_entry) Update() (int64, error) { - if res, err := DBExec("UPDATE mcq_entries SET label = ?, response = ? WHERE id_mcq = ?", n.Label, n.Response, n.Id); err != nil { + if res, err := DBExec("UPDATE mcq_entries SET label = ?, response = ? WHERE id_mcq_entry = ?", n.Label, n.Response, n.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err From ad7489e5584d5f3bf952ff8abd25dcb79fc3a7dd Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 24 Jan 2025 23:49:00 +0100 Subject: [PATCH 10/19] admin: Start compute flag stats --- admin/api/exercice.go | 29 ++++++++++++++++++++++++++ admin/static/js/app.js | 9 ++++++++ admin/static/views/exercice-flags.html | 11 +++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/admin/api/exercice.go b/admin/api/exercice.go index cfdb450d..c4fdaed9 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -62,6 +62,7 @@ func declareExercicesRoutes(router *gin.RouterGroup) { apiFlagsRoutes.POST("/try", tryExerciceFlag) apiFlagsRoutes.DELETE("/", deleteExerciceFlag) apiFlagsRoutes.GET("/dependancies", showExerciceFlagDeps) + apiFlagsRoutes.GET("/statistics", showExerciceFlagStats) apiFlagsRoutes.GET("/choices/", listFlagChoices) apiFlagsChoicesRoutes := apiExercicesRoutes.Group("/choices/:cid") apiFlagsChoicesRoutes.Use(FlagChoiceHandler) @@ -852,6 +853,34 @@ func showExerciceFlagDeps(c *gin.Context) { c.JSON(http.StatusOK, deps) } +func showExerciceFlagStats(c *gin.Context) { + exercice := c.MustGet("exercice").(*fic.Exercice) + flag := c.MustGet("flag-key").(*fic.FlagKey) + + history, err := exercice.GetHistory() + if err != nil { + log.Println("Unable to getExerciceHistory:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving exercice history"}) + return + } + + var completed, tries, nteams int64 + + for _, hline := range history { + if hline["kind"].(string) == "flag_found" { + if *hline["secondary"].(*int) == flag.Id { + completed += 1 + } + } + } + + c.JSON(http.StatusOK, gin.H{ + "completed": completed, + "tries": tries, + "nteams": nteams, + }) +} + func tryExerciceFlag(c *gin.Context) { flag := c.MustGet("flag-key").(*fic.FlagKey) diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 0753bbb0..2fa150f4 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -348,6 +348,9 @@ angular.module("FICApp") .factory("ExerciceFlagDeps", function ($resource) { return $resource("api/exercices/:exerciceId/flags/:flagId/dependancies", { exerciceId: '@idExercice', flagId: '@id' }) }) + .factory("ExerciceFlagStats", function ($resource) { + return $resource("api/exercices/:exerciceId/flags/:flagId/statistics", { exerciceId: '@idExercice', flagId: '@id' }) + }) .factory("ExerciceMCQFlag", function ($resource) { return $resource("api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, { update: { method: 'PUT' } @@ -2345,6 +2348,12 @@ angular.module("FICApp") } }) + .controller("ExerciceFlagStatsController", function ($scope, $routeParams, ExerciceFlagStats) { + $scope.init = function (flag) { + $scope.stats = ExerciceFlagStats.get({ exerciceId: $routeParams.exerciceId, flagId: flag.id }); + } + }) + .controller("ExerciceMCQFlagsController", function ($scope, ExerciceMCQFlag, $routeParams, $rootScope) { $scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId }); diff --git a/admin/static/views/exercice-flags.html b/admin/static/views/exercice-flags.html index 3caf3add..b23556ca 100644 --- a/admin/static/views/exercice-flags.html +++ b/admin/static/views/exercice-flags.html @@ -73,12 +73,21 @@
- Dépendances : + Dépendances :
sans
+
+
+ Statistiques +
    +
  • Validés : {{ stats["completed"] }}
  • +
  • Tentés : {{ stats["tries"] }}
  • +
  • Équipes : {{ stats["nteams"] }}
  • +
+