package api import ( "encoding/hex" "encoding/json" "errors" "strings" "srs.epita.fr/fic-server/admin/sync" "srs.epita.fr/fic-server/libfic" "github.com/julienschmidt/httprouter" ) func init() { router.GET("/api/exercices/", apiHandler(listExercices)) router.GET("/api/exercices/:eid", apiHandler(exerciceHandler(showExercice))) router.PUT("/api/exercices/:eid", apiHandler(exerciceHandler(updateExercice))) router.DELETE("/api/exercices/:eid", apiHandler(exerciceHandler(deleteExercice))) router.GET("/api/exercices/:eid/files", apiHandler(exerciceHandler(listExerciceFiles))) router.POST("/api/exercices/:eid/files", apiHandler(exerciceHandler(createExerciceFile))) router.GET("/api/exercices/:eid/files/:fid", apiHandler(exerciceFileHandler(showExerciceFile))) router.DELETE("/api/exercices/:eid/files/:fid", apiHandler(exerciceFileHandler(deleteExerciceFile))) router.GET("/api/exercices/:eid/hints", apiHandler(exerciceHandler(listExerciceHints))) router.POST("/api/exercices/:eid/hints", apiHandler(exerciceHandler(createExerciceHint))) router.GET("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(showExerciceHint))) router.PUT("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(updateExerciceHint))) router.DELETE("/api/exercices/:eid/hints/:hid", apiHandler(hintHandler(deleteExerciceHint))) router.GET("/api/exercices/:eid/keys", apiHandler(exerciceHandler(listExerciceKeys))) router.POST("/api/exercices/:eid/keys", apiHandler(exerciceHandler(createExerciceKey))) router.GET("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(showExerciceKey))) router.PUT("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(updateExerciceKey))) router.DELETE("/api/exercices/:eid/keys/:kid", apiHandler(keyHandler(deleteExerciceKey))) router.GET("/api/exercices/:eid/quiz", apiHandler(exerciceHandler(listExerciceQuiz))) router.GET("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(showExerciceQuiz))) router.DELETE("/api/exercices/:eid/quiz/:qid", apiHandler(quizHandler(deleteExerciceQuiz))) // Synchronize router.POST("/api/sync/exercices/:eid/files", apiHandler(exerciceHandler( func(exercice fic.Exercice, _ []byte) (interface{}, error) { return sync.SyncExerciceFiles(sync.GlobalImporter, exercice), nil }))) router.POST("/api/sync/exercices/:eid/hints", apiHandler(exerciceHandler( func(exercice fic.Exercice, _ []byte) (interface{}, error) { return sync.SyncExerciceHints(sync.GlobalImporter, exercice), nil }))) router.POST("/api/sync/exercices/:eid/keys", apiHandler(exerciceHandler( func(exercice fic.Exercice, _ []byte) (interface{}, error) { return sync.SyncExerciceKeys(sync.GlobalImporter, exercice), nil }))) router.POST("/api/sync/exercices/:eid/fixurlid", apiHandler(exerciceHandler( func(exercice fic.Exercice, _ []byte) (interface{}, error) { if exercice.FixURLId() { return exercice.Update() } return 0, nil }))) } func listExercices(_ httprouter.Params, body []byte) (interface{}, error) { // List all exercices return fic.GetExercices() } func listExerciceFiles(exercice fic.Exercice, body []byte) (interface{}, error) { return exercice.GetFiles() } func listExerciceHints(exercice fic.Exercice, body []byte) (interface{}, error) { return exercice.GetHints() } func listExerciceKeys(exercice fic.Exercice, body []byte) (interface{}, error) { return exercice.GetKeys() } func listExerciceQuiz(exercice fic.Exercice, body []byte) (interface{}, error) { return exercice.GetMCQ() } func showExercice(exercice fic.Exercice, body []byte) (interface{}, error) { return exercice, nil } func deleteExercice(exercice fic.Exercice, _ []byte) (interface{}, error) { return exercice.Delete() } func updateExercice(exercice fic.Exercice, body []byte) (interface{}, error) { var ue fic.Exercice if err := json.Unmarshal(body, &ue); err != nil { return nil, err } ue.Id = exercice.Id if len(ue.Title) == 0 { return nil, errors.New("Exercice's title not filled") } if _, err := ue.Update(); err != nil { return nil, err } return ue, nil } func createExercice(theme fic.Theme, body []byte) (interface{}, error) { // Create a new exercice var ue fic.Exercice if err := json.Unmarshal(body, &ue); err != nil { return nil, err } if len(ue.Title) == 0 { return nil, errors.New("Title not filled") } var depend *fic.Exercice = nil if ue.Depend != nil { if d, err := fic.GetExercice(*ue.Depend); err != nil { return nil, err } else { depend = &d } } return theme.AddExercice(ue.Title, ue.URLId, ue.Path, ue.Statement, ue.Overview, depend, ue.Gain, ue.VideoURI) } type uploadedHint struct { Title string Path string Content string Cost int64 URI string } func createExerciceHint(exercice fic.Exercice, body []byte) (interface{}, error) { var uh uploadedHint if err := json.Unmarshal(body, &uh); err != nil { return nil, err } if len(uh.Content) != 0 { return exercice.AddHint(uh.Title, uh.Content, uh.Cost) } else if len(uh.URI) != 0 { return sync.ImportFile(sync.GlobalImporter, uh.URI, func(filePath string, origin string) (interface{}, error) { return exercice.AddHint(uh.Title, "$FILES"+strings.TrimPrefix(filePath, fic.FilesDir), uh.Cost) }) } else { return nil, errors.New("Hint's content not filled") } } func showExerciceHint(hint fic.EHint, body []byte) (interface{}, error) { return hint, nil } func updateExerciceHint(hint fic.EHint, body []byte) (interface{}, error) { var uh fic.EHint if err := json.Unmarshal(body, &uh); err != nil { return nil, err } uh.Id = hint.Id if len(uh.Title) == 0 { return nil, errors.New("Hint's title not filled") } if _, err := uh.Update(); err != nil { return nil, err } return uh, nil } func deleteExerciceHint(hint fic.EHint, _ []byte) (interface{}, error) { return hint.Delete() } type uploadedKey struct { Label string Key string Hash []byte } func createExerciceKey(exercice fic.Exercice, body []byte) (interface{}, error) { var uk uploadedKey if err := json.Unmarshal(body, &uk); err != nil { return nil, err } if len(uk.Key) == 0 { return nil, errors.New("Key not filled") } return exercice.AddRawKey(uk.Label, uk.Key) } func showExerciceKey(key fic.Key, _ fic.Exercice, body []byte) (interface{}, error) { return key, nil } func updateExerciceKey(key fic.Key, exercice fic.Exercice, body []byte) (interface{}, error) { var uk uploadedKey if err := json.Unmarshal(body, &uk); err != nil { return nil, err } if len(uk.Label) == 0 { key.Label = "Flag" } else { key.Label = uk.Label } key.Checksum = uk.Hash if _, err := key.Update(); err != nil { return nil, err } return key, nil } func deleteExerciceKey(key fic.Key, _ fic.Exercice, _ []byte) (interface{}, error) { return key.Delete() } func showExerciceQuiz(quiz fic.MCQ, _ fic.Exercice, body []byte) (interface{}, error) { return quiz, nil } func deleteExerciceQuiz(quiz fic.MCQ, _ fic.Exercice, _ []byte) (interface{}, error) { return quiz.Delete() } type uploadedFile struct { URI string Digest string } func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) { var uf uploadedFile if err := json.Unmarshal(body, &uf); err != nil { return nil, err } return sync.ImportFile(sync.GlobalImporter, uf.URI, func(filePath string, origin string) (interface{}, error) { if digest, err := hex.DecodeString(uf.Digest); err != nil { return nil, err } else { return exercice.ImportFile(filePath, origin, digest) } }) } func showExerciceFile(file fic.EFile, body []byte) (interface{}, error) { return file, nil } func deleteExerciceFile(file fic.EFile, _ []byte) (interface{}, error) { return file.Delete() }