diff --git a/README.md b/README.md index a692756..a7350cb 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,16 @@ Copy `.env.example` to `.env` and fill out the info `DEV_FORCE_IS_EBOARD="true"` will force vote to treat all users as E-Board members `DEV_FORCE_IS_EVALS="true"` will force vote to treat all users as the Evals director +## Running Locally + +This project can be easily run using either `docker` or `podman` + +The run command is the same for both, just replace `podman` with `docker` if you perfer to use docker over podman + +```sh +podman compose up +``` + ## Linting These will be checked by CI @@ -40,7 +50,7 @@ go vet *.go - [ ] Don't let the user fuck it up - [ ] Show E-Board polls with a higher priority -- [x] Move Hide Vote to create instead of after you vote :skull: +- [X] Move Hide Vote to create instead of after you vote :skull: - [X] Display the reason why a user is on the results page of a running poll - [ ] Display minimum time left that a poll is open - [ ] Move routes to their own functions diff --git a/api.go b/api.go index 8fe6c7c..2f7171f 100644 --- a/api.go +++ b/api.go @@ -224,6 +224,13 @@ func CreatePoll(c *gin.Context) { return } + poll.Id = pollId + + broker.Notifier <- sse.NotificationEvent{ + EventName: "new-polls", + Payload: poll, + } + c.Redirect(http.StatusFound, "/poll/"+pollId) } diff --git a/main.go b/main.go index e53aad4..5133cbf 100644 --- a/main.go +++ b/main.go @@ -49,7 +49,9 @@ func main() { "MakeLinks": MakeLinks, }) r.LoadHTMLGlob("templates/*") - broker = sse.NewBroker() + broker = sse.NewBroker( + GetUserData, + ) csh := cshAuth.CSHAuth{} csh.Init( diff --git a/sse/broker.go b/sse/broker.go index 464b333..3eff1d0 100644 --- a/sse/broker.go +++ b/sse/broker.go @@ -26,8 +26,11 @@ package sse import ( "io" "log" + "slices" "time" + cshAuth "github.com/computersciencehouse/csh-auth" + "github.com/computersciencehouse/vote/database" "github.com/gin-gonic/gin" ) @@ -54,22 +57,28 @@ type ( // Client connections registry clients map[NotifierChan]struct{} + + // Callbacks for cross-package access to main package functions + GetUser func(*gin.Context) cshAuth.CSHUserInfo } ) -func NewBroker() (broker *Broker) { +func NewBroker(getUser func(*gin.Context) cshAuth.CSHUserInfo) (broker *Broker) { // Instantiate a broker return &Broker{ Notifier: make(NotifierChan, 1), newClients: make(chan NotifierChan), closingClients: make(chan NotifierChan), clients: make(map[NotifierChan]struct{}), + GetUser: getUser, } } func (broker *Broker) ServeHTTP(c *gin.Context) { eventName := c.Param("topic") + username := broker.GetUser(c).Username + // Each connection registers its own message channel with the Broker's connections registry messageChan := make(NotifierChan) @@ -86,8 +95,18 @@ func (broker *Broker) ServeHTTP(c *gin.Context) { // Emit Server Sent Events compatible event := <-messageChan - switch eventName { - case event.EventName: + switch event.EventName { + case "new-polls": + payload, ok := event.Payload.(*database.Poll) + + if !ok { + log.Fatal("Event payload is not of type database.Poll") + } + + if !(payload.Gatekeep && payload.HideForIneligible) || slices.Contains(payload.AllowedUsers, username) { + c.SSEvent(event.EventName, event.Payload) + } + case eventName: c.SSEvent(event.EventName, event.Payload) } diff --git a/templates/index.tmpl b/templates/index.tmpl index 640e358..7cbc815 100644 --- a/templates/index.tmpl +++ b/templates/index.tmpl @@ -18,18 +18,46 @@ class="list-group-item list-group-item-action p-3" href="/poll/{{ $poll.Id }}" > - - {{ $poll.Title }} - + + {{ $poll.Title }} + - (created by {{ $poll.CreatedBy }}) + (created by {{ $poll.CreatedBy }}) {{ end }} +