Dirty implementation of createVotes
This commit is contained in:
@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -140,22 +141,95 @@ func (app *application) createVotes(w http.ResponseWriter, r *http.Request) {
|
||||
app.serverError(w, r, err)
|
||||
}
|
||||
|
||||
// TODO check if he has voted
|
||||
|
||||
//var voterIdentity string
|
||||
if election.AreVotersKnown {
|
||||
if request.VoterIdentity == nil || validator.Blank(*request.VoterIdentity) {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("election has known voters; you must provide an identity provided by the organizer"))
|
||||
for _, c := range request.Choices {
|
||||
choiceExists := slices.Contains(election.Choices, c.ChoiceText)
|
||||
if !choiceExists {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("choice %v doesn't exist", c.ChoiceText))
|
||||
return
|
||||
}
|
||||
//voterIdentity = *request.VoterIdentity
|
||||
} else {
|
||||
// TODO: get requester's IP address as identity
|
||||
}
|
||||
|
||||
// TODO verify if choice exists
|
||||
// TODO count tokens to make sure user isn't trying to cheat
|
||||
tokensUsed := 0
|
||||
for _, c := range request.Choices {
|
||||
tokensUsed += c.Tokens
|
||||
}
|
||||
|
||||
json, _ := json.Marshal(election)
|
||||
w.Write(json)
|
||||
if tokensUsed > election.Tokens {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("you used too many tokens; must not exceed %v tokens", election.Tokens))
|
||||
return
|
||||
}
|
||||
|
||||
electionHasExpired := election.ExpiresAt.Before(time.Now())
|
||||
if electionHasExpired {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("election has expired"))
|
||||
return
|
||||
}
|
||||
|
||||
// this snippet of code also inserts in the `voters` table
|
||||
voterIdentity := func() string {
|
||||
var voterIdentity string
|
||||
if election.AreVotersKnown {
|
||||
if request.VoterIdentity == nil || validator.Blank(*request.VoterIdentity) {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("election has known voters; you must provide an identity provided by the organizer"))
|
||||
return ""
|
||||
}
|
||||
|
||||
voterIdentity = *request.VoterIdentity
|
||||
hasCastVotes, err := app.votes.Exists(voterIdentity, election.ID)
|
||||
if err != nil {
|
||||
app.serverError(w, r, err)
|
||||
return ""
|
||||
}
|
||||
if hasCastVotes {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("you already voted"))
|
||||
return ""
|
||||
}
|
||||
} else {
|
||||
voterIdentity = r.RemoteAddr
|
||||
|
||||
// if voters are known, voter will always exist
|
||||
voterExists, err := app.voters.Exists(voterIdentity, election.ID)
|
||||
if err != nil {
|
||||
app.serverError(w, r, err)
|
||||
return ""
|
||||
}
|
||||
if voterExists {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("you already voted"))
|
||||
return ""
|
||||
}
|
||||
|
||||
_, err = app.voters.Insert(voterIdentity, election.ID)
|
||||
if err != nil {
|
||||
app.serverError(w, r, err)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return voterIdentity
|
||||
}()
|
||||
|
||||
if voterIdentity == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if !election.AreVotersKnown {
|
||||
voterCount, err := app.voters.CountByElection(election.ID)
|
||||
if err != nil && !errors.Is(sql.ErrNoRows, err) {
|
||||
app.serverError(w, r, err)
|
||||
return
|
||||
}
|
||||
// if voters are known, voterCount == election.MaxVoters in all cases
|
||||
if voterCount == election.MaxVoters {
|
||||
app.unprocessableEntityErrorSingle(w, fmt.Errorf("maximum voters reached"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range request.Choices {
|
||||
_, err := app.votes.Insert(voterIdentity, election.ID, c.ChoiceText, c.Tokens)
|
||||
if err != nil {
|
||||
app.serverError(w, r, err)
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
Reference in New Issue
Block a user