From 3008f915a4039a974a697b6f99c7ec03573d3ec0 Mon Sep 17 00:00:00 2001 From: pikachu0542 <112343747+pikachu0542@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:02:41 -0500 Subject: [PATCH 01/25] Changed all status codes to the http.StatusCode equivalent. Also changed some 500s to 400s where appropriate to indicate user error (#85) --- main.go | 82 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/main.go b/main.go index 7e9239e..dba0cb7 100644 --- a/main.go +++ b/main.go @@ -104,7 +104,7 @@ func main() { polls, err := database.GetOpenPolls(c) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } sort.Slice(polls, func(i, j int) bool { @@ -113,12 +113,12 @@ func main() { closedPolls, err := database.GetClosedVotedPolls(c, claims.UserInfo.Username) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } ownedPolls, err := database.GetClosedOwnedPolls(c, claims.UserInfo.Username) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } closedPolls = append(closedPolls, ownedPolls...) @@ -128,7 +128,7 @@ func main() { }) closedPolls = uniquePolls(closedPolls) - c.HTML(200, "index.tmpl", gin.H{ + c.HTML(http.StatusOK, "index.tmpl", gin.H{ "Polls": polls, "Username": claims.UserInfo.Username, "FullName": claims.UserInfo.FullName, @@ -141,12 +141,12 @@ func main() { closedPolls, err := database.GetClosedVotedPolls(c, claims.UserInfo.Username) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } ownedPolls, err := database.GetClosedOwnedPolls(c, claims.UserInfo.Username) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } closedPolls = append(closedPolls, ownedPolls...) @@ -156,7 +156,7 @@ func main() { }) closedPolls = uniquePolls(closedPolls) - c.HTML(200, "closed.tmpl", gin.H{ + c.HTML(http.StatusOK, "closed.tmpl", gin.H{ "ClosedPolls": closedPolls, "Username": claims.UserInfo.Username, "FullName": claims.UserInfo.FullName, @@ -167,14 +167,14 @@ func main() { cl, _ := c.Get("cshauth") claims := cl.(cshAuth.CSHClaims) if !DEV_DISABLE_ACTIVE_FILTERS && !slices.Contains(claims.UserInfo.Groups, "active") { - c.HTML(403, "unauthorized.tmpl", gin.H{ + c.HTML(http.StatusForbidden, "unauthorized.tmpl", gin.H{ "Username": claims.UserInfo.Username, "FullName": claims.UserInfo.FullName, }) return } - c.HTML(200, "create.tmpl", gin.H{ + c.HTML(http.StatusOK, "create.tmpl", gin.H{ "Username": claims.UserInfo.Username, "FullName": claims.UserInfo.FullName, "IsEvals": isEvals(claims.UserInfo), @@ -185,7 +185,7 @@ func main() { cl, _ := c.Get("cshauth") claims := cl.(cshAuth.CSHClaims) if !DEV_DISABLE_ACTIVE_FILTERS && !slices.Contains(claims.UserInfo.Groups, "active") { - c.HTML(403, "unauthorized.tmpl", gin.H{ + c.HTML(http.StatusForbidden, "unauthorized.tmpl", gin.H{ "Username": claims.UserInfo.Username, "FullName": claims.UserInfo.FullName, }) @@ -239,7 +239,7 @@ func main() { } if poll.Gatekeep { if !isEvals(claims.UserInfo) { - c.HTML(403, "unauthorized.tmpl", gin.H{ + c.HTML(http.StatusForbidden, "unauthorized.tmpl", gin.H{ "Username": claims.UserInfo.Username, "FullName": claims.UserInfo.FullName, }) @@ -253,11 +253,11 @@ func main() { pollId, err := database.CreatePoll(c, poll) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - c.Redirect(302, "/poll/"+pollId) + c.Redirect(http.StatusFound, "/poll/"+pollId) })) r.GET("/poll/:id", csh.AuthWrapper(func(c *gin.Context) { @@ -268,13 +268,13 @@ func main() { poll, err := database.GetPoll(c, c.Param("id")) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // If the user can't vote, just show them results if canVote(claims.UserInfo, *poll, poll.AllowedUsers) > 0 || !poll.Open { - c.Redirect(302, "/results/"+poll.Id) + c.Redirect(http.StatusFound, "/results/"+poll.Id) return } @@ -305,18 +305,18 @@ func main() { poll, err := database.GetPoll(c, c.Param("id")) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if canVote(claims.UserInfo, *poll, poll.AllowedUsers) > 0 || !poll.Open { - c.Redirect(302, "/results/"+poll.Id) + c.Redirect(http.StatusFound, "/results/"+poll.Id) return } pId, err := primitive.ObjectIDFromHex(poll.Id) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } @@ -336,7 +336,7 @@ func main() { } else if poll.AllowWriteIns && c.PostForm("option") == "writein" { vote.Option = c.PostForm("writeinOption") } else { - c.JSON(400, gin.H{"error": "Invalid Option"}) + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid Option"}) return } database.CastSimpleVote(c, &vote, &voter) @@ -359,7 +359,7 @@ func main() { continue } if err != nil { - c.JSON(400, gin.H{"error": "non-number ranking"}) + c.JSON(http.StatusBadRequest, gin.H{"error": "non-number ranking"}) return } @@ -370,17 +370,17 @@ func main() { 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"}) + c.JSON(http.StatusBadRequest, 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": "Write-in rank is not numerical"}) + c.JSON(http.StatusBadRequest, gin.H{"error": "Write-in rank is not numerical"}) return } if rank < 1 { - c.JSON(500, gin.H{"error": "Write-in rank is not positive"}) + c.JSON(http.StatusBadRequest, gin.H{"error": "Write-in rank is not positive"}) return } vote.Options[c.PostForm("writeinOption")] = rank @@ -392,12 +392,12 @@ func main() { for _, rank := range vote.Options { if rank > 0 && rank <= maxNum { if voted[rank-1] { - c.JSON(400, gin.H{"error": "You ranked two or more candidates at the same level"}) + c.JSON(http.StatusBadRequest, gin.H{"error": "You ranked two or more candidates at the same level"}) return } voted[rank-1] = true } else { - c.JSON(400, gin.H{"error": fmt.Sprintf("votes must be from 1 - %d", maxNum)}) + c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("votes must be from 1 - %d", maxNum)}) return } } @@ -405,13 +405,13 @@ func main() { rankedCandidates := len(vote.Options) for _, voteOpt := range vote.Options { if voteOpt > rankedCandidates { - c.JSON(400, gin.H{"error": "Rank choice is more than the amount of candidates ranked"}) + c.JSON(http.StatusBadRequest, gin.H{"error": "Rank choice is more than the amount of candidates ranked"}) return } } database.CastRankedVote(c, &vote, &voter) } else { - c.JSON(500, gin.H{"error": "Unknown Poll Type"}) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Unknown Poll Type"}) return } @@ -427,7 +427,7 @@ func main() { } } - c.Redirect(302, "/results/"+poll.Id) + c.Redirect(http.StatusFound, "/results/"+poll.Id) })) r.GET("/results/:id", csh.AuthWrapper(func(c *gin.Context) { @@ -438,20 +438,20 @@ func main() { poll, err := database.GetPoll(c, c.Param("id")) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } results, err := poll.GetResult(c) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } canModify := containsString(claims.UserInfo.Groups, "active_rtp") || containsString(claims.UserInfo.Groups, "eboard") || poll.CreatedBy == claims.UserInfo.Username votesNeededForQuorum := int(poll.QuorumType * float64(len(poll.AllowedUsers))) - c.HTML(200, "result.tmpl", gin.H{ + c.HTML(http.StatusOK, "result.tmpl", gin.H{ "Id": poll.Id, "Title": poll.Title, "Description": poll.Description, @@ -476,18 +476,18 @@ func main() { poll, err := database.GetPoll(c, c.Param("id")) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if poll.CreatedBy != claims.UserInfo.Username { - c.JSON(403, gin.H{"error": "Only the creator can hide a poll result"}) + c.JSON(http.StatusForbidden, gin.H{"error": "Only the creator can hide a poll result"}) return } err = poll.Hide(c) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } pId, _ := primitive.ObjectIDFromHex(poll.Id) @@ -500,11 +500,11 @@ func main() { } err = database.WriteAction(c, &action) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - c.Redirect(302, "/results/"+poll.Id) + c.Redirect(http.StatusFound, "/results/"+poll.Id) })) r.POST("/poll/:id/close", csh.AuthWrapper(func(c *gin.Context) { @@ -515,7 +515,7 @@ func main() { poll, err := database.GetPoll(c, c.Param("id")) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } @@ -527,14 +527,14 @@ func main() { if poll.CreatedBy != claims.UserInfo.Username { if containsString(claims.UserInfo.Groups, "active_rtp") || containsString(claims.UserInfo.Groups, "eboard") { } else { - c.JSON(403, gin.H{"error": "You cannot end this poll."}) + c.JSON(http.StatusForbidden, gin.H{"error": "You cannot end this poll."}) return } } err = poll.Close(c) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } pId, _ := primitive.ObjectIDFromHex(poll.Id) @@ -547,11 +547,11 @@ func main() { } err = database.WriteAction(c, &action) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - c.Redirect(302, "/results/"+poll.Id) + c.Redirect(http.StatusFound, "/results/"+poll.Id) })) r.GET("/stream/:topic", csh.AuthWrapper(broker.ServeHTTP)) From eec83b812ee838f4ff913ba5b42e8e3a52c7999e Mon Sep 17 00:00:00 2001 From: pikachu0542 Date: Wed, 1 Apr 2026 12:22:26 -0400 Subject: [PATCH 02/25] Started working on navbar --- eboard.go | 4 +- templates/closed.tmpl | 24 +------- templates/create.tmpl | 14 +---- templates/eboard.tmpl | 14 +---- templates/header.tmpl | 115 ++++++++++++++++++++++++++++++++++++ templates/hidden.tmpl | 27 +-------- templates/index.tmpl | 23 +------- templates/nav.tmpl | 39 ------------ templates/poll.tmpl | 20 +------ templates/result.tmpl | 24 +------- templates/unauthorized.tmpl | 27 +-------- 11 files changed, 126 insertions(+), 205 deletions(-) create mode 100644 templates/header.tmpl delete mode 100644 templates/nav.tmpl diff --git a/eboard.go b/eboard.go index 8f3b57e..7f86683 100644 --- a/eboard.go +++ b/eboard.go @@ -16,7 +16,7 @@ var OPTIONS = []string{"Pass", "Fail", "Abstain"} func HandleGetEboardVote(c *gin.Context) { user := GetUserData(c) - if IsEboard(user) { + if !IsEboard(user) { c.JSON(http.StatusUnauthorized, gin.H{"error": "You need to be E-Board to access this page"}) return } @@ -34,7 +34,7 @@ func HandleGetEboardVote(c *gin.Context) { func HandlePostEboardVote(c *gin.Context) { user := GetUserData(c) - if IsEboard(user) { + if !IsEboard(user) { c.JSON(http.StatusUnauthorized, gin.H{"error": "You need to be E-Board to access this page"}) return } diff --git a/templates/closed.tmpl b/templates/closed.tmpl index b4c17bb..bd3778b 100644 --- a/templates/closed.tmpl +++ b/templates/closed.tmpl @@ -1,26 +1,4 @@ - - - - CSH Vote - - - - - - - - - - - {{ template "nav" . }} + {{ template "header.tmpl" . }}

Closed Polls
diff --git a/templates/create.tmpl b/templates/create.tmpl index 41eacab..578ffef 100644 --- a/templates/create.tmpl +++ b/templates/create.tmpl @@ -1,16 +1,4 @@ - - - - CSH Vote - - - - - - - - - {{ template "nav" . }} + {{ template "header.tmpl" . }}

Create Poll

diff --git a/templates/eboard.tmpl b/templates/eboard.tmpl index 0e3d9a5..8a751ed 100644 --- a/templates/eboard.tmpl +++ b/templates/eboard.tmpl @@ -1,17 +1,5 @@ - - - - CSH Vote - +{{ template "header.tmpl" . }} - - - - - -{{ template "nav" . }}

E-Board Vote

diff --git a/templates/header.tmpl b/templates/header.tmpl new file mode 100644 index 0000000..5763d11 --- /dev/null +++ b/templates/header.tmpl @@ -0,0 +1,115 @@ +{{ define "header.tmpl" }} + + + + CSH Vote + + + + + + + + + + + +{{ end }} \ No newline at end of file diff --git a/templates/hidden.tmpl b/templates/hidden.tmpl index 76b93c3..ed6fe94 100644 --- a/templates/hidden.tmpl +++ b/templates/hidden.tmpl @@ -1,29 +1,4 @@ - - - - CSH Vote - - - - - - - - - - {{ template "nav" . }} + {{ template "header.tmpl" . }}
- - - CSH Vote - - - - - - - - - - {{ template "nav" . }} + {{ template "header.tmpl" . }}

diff --git a/templates/nav.tmpl b/templates/nav.tmpl deleted file mode 100644 index 4fdacbe..0000000 --- a/templates/nav.tmpl +++ /dev/null @@ -1,39 +0,0 @@ -{{ define "nav" }} - - -{{ end }} \ No newline at end of file diff --git a/templates/poll.tmpl b/templates/poll.tmpl index 74e14bd..8304361 100644 --- a/templates/poll.tmpl +++ b/templates/poll.tmpl @@ -1,21 +1,4 @@ - - - - CSH Vote - - - - - - - - - - {{ template "nav" . }} + {{ template "header.tmpl" . }}

{{ .Title }}

@@ -103,3 +86,4 @@
+ diff --git a/templates/result.tmpl b/templates/result.tmpl index f007a35..8e748ff 100644 --- a/templates/result.tmpl +++ b/templates/result.tmpl @@ -1,26 +1,4 @@ - - - - CSH Vote - - - - - - - - - - - {{ template "nav" . }} + {{ template "header.tmpl" . }}
{{ if eq .CanVote 9 }} diff --git a/templates/unauthorized.tmpl b/templates/unauthorized.tmpl index b06a319..38facb9 100644 --- a/templates/unauthorized.tmpl +++ b/templates/unauthorized.tmpl @@ -1,29 +1,4 @@ - - - - CSH Vote - - - - - - - - - - {{ template "nav" . }} + {{ template "header.tmpl" . }}
Date: Sat, 4 Apr 2026 11:09:07 -0400 Subject: [PATCH 03/25] More progress --- eboard.go | 5 +-- templates/header.tmpl | 77 +++++++++++++++---------------------------- 2 files changed, 29 insertions(+), 53 deletions(-) diff --git a/eboard.go b/eboard.go index 7f86683..8a43d68 100644 --- a/eboard.go +++ b/eboard.go @@ -23,9 +23,10 @@ func HandleGetEboardVote(c *gin.Context) { if votes == nil { votes = make(map[string]float32) } - fmt.Println(votes) + // fmt.Println(votes) + fmt.Println(user) c.HTML(http.StatusOK, "eboard.tmpl", gin.H{ - "Username": user, + "Username": user.Username, "Voted": slices.Contains(voters, user.Username), "Results": votes, "Options": OPTIONS, diff --git a/templates/header.tmpl b/templates/header.tmpl index 5763d11..a630671 100644 --- a/templates/header.tmpl +++ b/templates/header.tmpl @@ -10,13 +10,17 @@ media="screen" /> + + -