Newer
Older
"code.electrolab.fr/it/vote.electrolab.fr/app/server/pages/common"
"log"
"net/http"
"strings"
)
const (
FORM_VOTER_PRIVATE_TOKEN = "private_token"
)
var (
func RegisterRoutes(mux *http.ServeMux, app *server.App) {
mux.Handle("/events/Electrolab-AG-2021/votes/", server.NewAppHandler(app, handlePage))
func handlePage(app *server.App, ctx context.Context, w http.ResponseWriter, r *http.Request) {
templateVars = new(TemplateVars)
)
pathParts := strings.Split(r.URL.Path, "/")
templateVars.User, err = model.FetchUser(app.Context, app.Service.DB, r.FormValue("private_token"))
// Query has an error
log.Printf("Query error: %s", err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
if templateVars.User == nil {
templateVars.Question, err = model.FetchQuestion(app.Context, app.Service.DB, templateVars.User.Uuid, questionName)
// Query has an error
log.Printf("Query error 1: %s", err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
if templateVars.Question == nil {
// Question is not found
// w.Header().Set("Location", "/votes")
w.WriteHeader(http.StatusNotFound)
return
templateVars.PageTitle = "Vote Électrolab - " + templateVars.Question.Title
switch r.FormValue("action") {
case "openclose":
if !templateVars.User.Admin {
w.WriteHeader(http.StatusForbidden)
fmt.Fprintf(w, "User is not admin")
return
}
err := doOpenClose(ctx, app.Service.DB, templateVars.Question.Name, r.FormValue("open") == "true")
if err != nil {
templateVars.Error = err.Error()
} else {
// Vote is a success, redirect to the page as GET
w.Header().Set("Location", r.URL.String())
w.WriteHeader(http.StatusMovedPermanently)
return
}
case "vote":
err := doVote(ctx, app.Service.DB, templateVars.Question.Name, templateVars.User.PrivateToken, r.Form["answer"])
if err != nil {
templateVars.VoteError = err.Error()
} else {
// Vote is a success, redirect to the page as GET
w.Header().Set("Location", r.URL.String())
w.WriteHeader(http.StatusMovedPermanently)
return
}
if templateVars.Question.VoteOpen || templateVars.Question.VoteCount == 0 {
if err != nil {
// Template has an error
log.Printf("Template execution error: %s", err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
return
}
func doVote(ctx context.Context, db db.Service, questionName, userPrivateToken string, answers []string) error {
questionName,
userPrivateToken,
pq.StringArray(answers),
// pq.StringArray(r.Form["answer"]),
).Scan(&voteErrorMsg)
if err != nil {
return fmt.Errorf("SQL query error: %s", err.Error())
}
if len(voteErrorMsg) > 0 {
return fmt.Errorf("%s", voteErrorMsg)
}
return nil
}
func doOpenClose(ctx context.Context, db db.Service, questionName string, isOpen bool) error {
q := `
UPDATE questions
SET vote_open = $2
WHERE name = $1
`
result, err := db.ExecContext(ctx, q, questionName, isOpen)
if err != nil {
return fmt.Errorf("SQL query error: %s", err.Error())
}
rowsAffected, _ := result.RowsAffected()
if rowsAffected == 0 {
return fmt.Errorf("Question not found: %s", questionName)
}
if rowsAffected > 1 {
return fmt.Errorf("Multiple question not found, should not happen: %s", questionName)
}
return nil
}