Files
qv/cmd/web/handlers.go

98 lines
2.4 KiB
Go
Raw Normal View History

2024-12-27 18:03:46 +01:00
package main
import (
api "code.dlmw.ch/dlmw/qv/internal"
"code.dlmw.ch/dlmw/qv/internal/validator"
"encoding/json"
"fmt"
"math/rand"
"net/http"
"time"
)
type createElectionRequestWithValidator struct {
api.CreateElectionRequest
validator.Validator
}
2024-12-27 18:03:46 +01:00
func (app *application) createElection(w http.ResponseWriter, r *http.Request) {
var request createElectionRequestWithValidator
2024-12-30 23:13:39 +01:00
if err := app.unmarshalRequest(r, &request); err != nil {
app.clientError(w, http.StatusBadRequest, err.Error())
return
}
2024-12-30 23:13:39 +01:00
if !isRequestValid(&request) {
app.unprocessableEntityError(w, request.Validator)
return
}
2024-12-30 23:13:39 +01:00
electionId, err := app.elections.Insert(
request.Name,
request.Tokens,
request.AreVotersKnown,
request.MaxVoters,
request.Choices,
request.ExpiresAt,
)
if err != nil {
app.serverError(w, r, err)
return
}
var res []byte
if request.AreVotersKnown {
voterIdentities := make([]string, 0, request.MaxVoters)
for i := 0; i < request.MaxVoters; i++ {
2024-12-30 23:15:25 +01:00
randomIdentity := randomVoterIdentity()
_, err := app.voters.Insert(randomIdentity, electionId)
if err != nil {
app.serverError(w, r, err)
}
voterIdentities = append(voterIdentities, randomIdentity)
}
res, err = json.Marshal(api.CreateElectionResponse{VoterIdentities: &voterIdentities})
if err != nil {
app.serverError(w, r, err)
return
}
}
2024-12-31 15:33:46 +01:00
w.Header().Set("Location", fmt.Sprintf("/election/%v", electionId))
w.Write(res)
}
2024-12-30 23:13:39 +01:00
func isRequestValid(r *createElectionRequestWithValidator) bool {
r.CheckField(validator.NotBlank(r.Name), "name", "must not be blank")
r.CheckField(validator.GreaterThan(r.Tokens, 0), "tokens", "must be greater than 0")
r.CheckField(validator.After(r.ExpiresAt, time.Now()), "expiresAt", "must expire in a future date")
r.CheckField(validator.GreaterThan(len(r.Choices), 1), "choices", "there must be more than 1 choice")
if r.AreVotersKnown {
r.CheckField(
validator.GreaterThan(r.MaxVoters, 0),
"maxVoters",
"must be greater than 0 when voters are known",
)
} else {
r.CheckField(
validator.GreaterThanOrEquals(r.MaxVoters, 0),
"maxVoters",
"must be a positive number",
)
}
2024-12-30 23:13:39 +01:00
return r.Valid()
}
2024-12-30 23:15:25 +01:00
func randomVoterIdentity() string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, 16)
for i := range b {
b[i] = charset[rand.Intn(len(charset))]
}
return string(b)
2024-12-27 18:03:46 +01:00
}