POST /api/v1/quizzes/import runs behind golem15.user's user.api_token with the write scope and the golem15.quizzes.access_quizzes permission.
59 lines
1.8 KiB
Go
59 lines
1.8 KiB
Go
package api
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
|
|
"git.golem15.com/golem15/sm-quizzes-plugin/classes"
|
|
"git.golem15.com/golem15/summercms/modules/wire"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// ImportQuiz answers POST /import?replace=: quizzes:import over HTTP, for
|
|
// the management API behind golem15.user's API token. The body is the
|
|
// import document. A document that does not parse is a 422 and writes
|
|
// nothing; an existing slug is a 409 unless replace is 1 or true.
|
|
func (h *Handlers) ImportQuiz(w http.ResponseWriter, r *http.Request) {
|
|
raw, err := io.ReadAll(r.Body)
|
|
var tooLarge *http.MaxBytesError
|
|
switch {
|
|
case errors.As(err, &tooLarge):
|
|
wire.WriteJSON(w, http.StatusRequestEntityTooLarge, map[string]any{"error": true, "message": "Request body too large."})
|
|
return
|
|
case err != nil:
|
|
wire.WriteJSON(w, http.StatusBadRequest, map[string]any{"error": true, "message": "Unreadable request body."})
|
|
return
|
|
}
|
|
doc, err := classes.ParseImport(raw)
|
|
if err != nil {
|
|
wire.WriteJSON(w, http.StatusUnprocessableEntity, map[string]any{"message": err.Error()})
|
|
return
|
|
}
|
|
var db *gorm.DB
|
|
if h.App != nil {
|
|
db, _ = h.App.Lookup[*gorm.DB]()
|
|
}
|
|
if db == nil {
|
|
wire.WriteOpaque500(w)
|
|
return
|
|
}
|
|
replace := r.URL.Query().Get("replace")
|
|
res, err := classes.Import(r.Context(), db, doc, replace == "1" || replace == "true")
|
|
if errors.Is(err, classes.ErrQuizExists) {
|
|
wire.WriteJSON(w, http.StatusConflict, map[string]any{"error": true, "message": "A quiz with the slug " + doc.Slug + " already exists; pass replace=1 to replace its questions."})
|
|
return
|
|
}
|
|
if err != nil {
|
|
wire.WriteOpaque500(w)
|
|
return
|
|
}
|
|
wire.WriteJSON(w, http.StatusOK, map[string]any{"data": map[string]any{
|
|
"id": res.Quiz.ID,
|
|
"slug": res.Quiz.Slug,
|
|
"created": res.Created,
|
|
"questions": res.Questions,
|
|
"answers": res.Answers,
|
|
}})
|
|
}
|