diff --git a/README.md b/README.md index 9a8b259..ae35812 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ You'll need to set up these values in your environment. Ask an RTP for OIDC cred ``` VOTE_HOST=http://localhost:8080 VOTE_JWT_SECRET= +VOTE_MONGO_DB= VOTE_MONGODB_URI= VOTE_OIDC_ID=vote VOTE_OIDC_SECRET= diff --git a/database/poll.go b/database/poll.go index b85f62e..699d95f 100644 --- a/database/poll.go +++ b/database/poll.go @@ -214,7 +214,6 @@ func (poll *Poll) GetResult(ctx context.Context) ([]map[string]int, error) { case POLL_TYPE_RANKED: // We want to store those that were eliminated eliminated := make([]string, 0) - eliminated = append(eliminated, "Isaac Ingram", "Charlotte George") // Get all votes cursor, err := Client.Database(db).Collection("votes").Aggregate(ctx, mongo.Pipeline{ diff --git a/main.go b/main.go index 5145343..eb44b44 100644 --- a/main.go +++ b/main.go @@ -3,19 +3,21 @@ package main import ( "encoding/json" "fmt" - cshAuth "github.com/computersciencehouse/csh-auth" - "github.com/computersciencehouse/vote/database" - "github.com/computersciencehouse/vote/sse" - "github.com/gin-gonic/gin" - "go.mongodb.org/mongo-driver/bson/primitive" "html/template" - "mvdan.cc/xurls/v2" + "log" "net/http" "os" "sort" "strconv" "strings" "time" + + cshAuth "github.com/computersciencehouse/csh-auth" + "github.com/computersciencehouse/vote/database" + "github.com/computersciencehouse/vote/sse" + "github.com/gin-gonic/gin" + "go.mongodb.org/mongo-driver/bson/primitive" + "mvdan.cc/xurls/v2" ) func inc(x int) string { @@ -280,18 +282,41 @@ func main() { PollId: pId, UserId: claims.UserInfo.Username, } + + voted := make([]bool, len(poll.Options)) + max_num := len(vote.Options) + for _, opt := range poll.Options { - if c.PostForm(opt) != "" { - rank, err := strconv.Atoi(c.PostForm(opt)) - if err != nil { - c.JSON(500, gin.H{"error": "error parsing votes"}) - } - if rank > 0 { - vote.Options[opt] = rank - } + if c.PostForm(opt) == "" { + c.JSON(400, gin.H{"error": "did not fill out all rankings"}) + return + } + rank, err := strconv.Atoi(c.PostForm(opt)) + if err != nil { + c.JSON(400, gin.H{"error": "non-number ranking"}) + return + } + if rank > 0 && rank <= max_num { + vote.Options[opt] = rank + voted[rank-1] = true + } else { + c.JSON(400, gin.H{"error": fmt.Sprintf("votes must be from 1 - %d", max_num)}) + return + } + } + for num, vote := range voted { + if !vote { + c.JSON(400, gin.H{"error": fmt.Sprintf("no candidate ranked at #%d", num+1)}) + return } } if c.PostForm("writeinOption") != "" && c.PostForm("writein") != "" { + for candidate := range vote.Options { + if strings.EqualFold(candidate, strings.TrimSpace(c.PostForm("writeinOption"))) { + c.JSON(500, gin.H{"error": "write-in is already an option"}) + return + } + } rank, err := strconv.Atoi(c.PostForm("writein")) if err != nil { c.JSON(500, gin.H{"error": "error parsing votes"}) @@ -334,7 +359,10 @@ func main() { } if poll.Hidden && poll.CreatedBy != claims.UserInfo.Username { - c.JSON(403, gin.H{"Success": "Result Hidden"}) + c.HTML(403, "hidden.tmpl", gin.H{ + "Username": claims.UserInfo.Username, + "FullName": claims.UserInfo.FullName, + }) return } @@ -486,7 +514,7 @@ func main() { r.Run() } -func canVote(groups []string) bool { +func canVote(groups []string, username string) bool { var active, fallCoop, springCoop bool for _, group := range groups { if group == "active" { @@ -503,10 +531,38 @@ func canVote(groups []string) bool { } } + type Result struct { + Result bool `json:"result"` + } + + // gatekeep + gatekeepURL := "https://conditional.csh.rit.edu/gatekeep/" + username + voteToken := os.Getenv("VOTE_TOKEN") + req, err := http.NewRequest("GET", gatekeepURL, nil) + if err != nil { + log.Fatal(err) + return false + } + req.Header.Add("X-VOTE-TOKEN", voteToken) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + log.Fatal(err) + return false + } + defer resp.Body.Close() + + var result Result + err = json.NewDecoder(resp.Body).Decode(&result) + if err != nil { + log.Fatal(err) + return false + } + gatekeep := result.Result if time.Now().Month() > time.July { - return active && !fallCoop + return active && !fallCoop && gatekeep } else { - return active && !springCoop + return active && !springCoop && gatekeep } } diff --git a/templates/hidden.tmpl b/templates/hidden.tmpl new file mode 100644 index 0000000..e7a0969 --- /dev/null +++ b/templates/hidden.tmpl @@ -0,0 +1,50 @@ + + + + CSH Vote + + + + + + + + +
+ Attention! +
+

The results are hidden!

+

Looks like you aren't allowed to see the results.

+

+ Please contact the owner of this poll or a Root Type Person if you think + this is an error. +

+
+ +