From 9569c04912213358819b9c93556e9d8be644ea63 Mon Sep 17 00:00:00 2001 From: Patrick Fairbank Date: Mon, 19 Aug 2019 19:12:16 -0700 Subject: [PATCH] Remove 'reader' authenticated user as it just complicates display and API access. --- .../20140524160241_CreateEventSettings.sql | 1 - model/event_settings.go | 1 - templates/setup_settings.html | 8 +---- web/alliance_station_display.go | 8 ----- web/announcer_display.go | 8 ----- web/api.go | 16 --------- web/audience_display.go | 8 ----- web/field_monitor_display.go | 8 ----- web/login_test.go | 36 +++++-------------- web/match_review.go | 4 --- web/pit_display.go | 8 ----- web/placeholder_display.go | 8 ----- web/queueing_display.go | 8 ----- web/reports.go | 24 ------------- web/setup_settings.go | 1 - web/twitch_display.go | 8 ----- web/web.go | 26 ++------------ 17 files changed, 11 insertions(+), 170 deletions(-) diff --git a/db/migrations/20140524160241_CreateEventSettings.sql b/db/migrations/20140524160241_CreateEventSettings.sql index 2f1a597..2fed953 100644 --- a/db/migrations/20140524160241_CreateEventSettings.sql +++ b/db/migrations/20140524160241_CreateEventSettings.sql @@ -22,7 +22,6 @@ CREATE TABLE event_settings ( plcaddress VARCHAR(255), tbadownloadenabled bool, adminpassword VARCHAR(255), - readerpassword VARCHAR(255), habdockingthreshold int ); diff --git a/model/event_settings.go b/model/event_settings.go index eeb1a4a..564847e 100644 --- a/model/event_settings.go +++ b/model/event_settings.go @@ -27,7 +27,6 @@ type EventSettings struct { SwitchPassword string PlcAddress string AdminPassword string - ReaderPassword string HabDockingThreshold int } diff --git a/templates/setup_settings.html b/templates/setup_settings.html index 9a46be2..6fe0958 100644 --- a/templates/setup_settings.html +++ b/templates/setup_settings.html @@ -115,19 +115,13 @@
Authentication -

Configure passwords to enable HTTP Basic authentication, or leave blank to disable.

+

Configure password to enable authentication, or leave blank to disable.

-
- -
- -
-
Networking diff --git a/web/alliance_station_display.go b/web/alliance_station_display.go index 12acf3b..d42b363 100644 --- a/web/alliance_station_display.go +++ b/web/alliance_station_display.go @@ -13,10 +13,6 @@ import ( // Renders the team number and status display shown above each alliance station. func (web *Web) allianceStationDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, map[string]string{"station": "R1"}) { return } @@ -39,10 +35,6 @@ func (web *Web) allianceStationDisplayHandler(w http.ResponseWriter, r *http.Req // The websocket endpoint for the alliance station display client to receive status updates. func (web *Web) allianceStationDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/announcer_display.go b/web/announcer_display.go index 1b7674d..be84ec8 100644 --- a/web/announcer_display.go +++ b/web/announcer_display.go @@ -13,10 +13,6 @@ import ( // Renders the announcer display which shows team info and scores for the current match. func (web *Web) announcerDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, nil) { return } @@ -39,10 +35,6 @@ func (web *Web) announcerDisplayHandler(w http.ResponseWriter, r *http.Request) // The websocket endpoint for the announcer display client to send control commands and receive status updates. func (web *Web) announcerDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/api.go b/web/api.go index d2551db..fe63a48 100644 --- a/web/api.go +++ b/web/api.go @@ -31,10 +31,6 @@ type RankingWithNickname struct { // Generates a JSON dump of the matches and results. func (web *Web) matchesApiHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - vars := mux.Vars(r) matches, err := web.arena.Database.GetMatchesByType(vars["type"]) if err != nil { @@ -75,10 +71,6 @@ func (web *Web) matchesApiHandler(w http.ResponseWriter, r *http.Request) { // Generates a JSON dump of the sponsor slides for use by the audience display. func (web *Web) sponsorSlidesApiHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - sponsors, err := web.arena.Database.GetAllSponsorSlides() if err != nil { handleWebErr(w, err) @@ -105,10 +97,6 @@ func (web *Web) sponsorSlidesApiHandler(w http.ResponseWriter, r *http.Request) // Generates a JSON dump of the qualification rankings, primarily for use by the pit display. func (web *Web) rankingsApiHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - rankings, err := web.arena.Database.GetAllRankings() if err != nil { handleWebErr(w, err) @@ -169,10 +157,6 @@ func (web *Web) rankingsApiHandler(w http.ResponseWriter, r *http.Request) { // Generates a JSON dump of the alliances. func (web *Web) alliancesApiHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - alliances, err := web.arena.Database.GetAllAlliances() if err != nil { handleWebErr(w, err) diff --git a/web/audience_display.go b/web/audience_display.go index e83a9a3..8b34be6 100644 --- a/web/audience_display.go +++ b/web/audience_display.go @@ -14,10 +14,6 @@ import ( // Renders the audience display to be chroma keyed over the video feed. func (web *Web) audienceDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, map[string]string{"background": "#0f0", "reversed": "false", "overlayLocation": "bottom"}) { return @@ -42,10 +38,6 @@ func (web *Web) audienceDisplayHandler(w http.ResponseWriter, r *http.Request) { // The websocket endpoint for the audience display client to receive status updates. func (web *Web) audienceDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/field_monitor_display.go b/web/field_monitor_display.go index 2b2b0f6..c1eaafd 100644 --- a/web/field_monitor_display.go +++ b/web/field_monitor_display.go @@ -13,10 +13,6 @@ import ( // Renders the field monitor display. func (web *Web) fieldMonitorDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, map[string]string{"reversed": "false"}) { return } @@ -38,10 +34,6 @@ func (web *Web) fieldMonitorDisplayHandler(w http.ResponseWriter, r *http.Reques // The websocket endpoint for the field monitor display client to receive status updates. func (web *Web) fieldMonitorDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/login_test.go b/web/login_test.go index 6e9e966..cb8633d 100644 --- a/web/login_test.go +++ b/web/login_test.go @@ -10,55 +10,35 @@ import ( func TestLoginDisplay(t *testing.T) { web := setupTestWeb(t) - web.arena.EventSettings.ReaderPassword = "reader" web.arena.EventSettings.AdminPassword = "admin" - // Check that hitting a reader-level protected page redirects to the login. - recorder := web.getHttpResponse("/api/alliances") + // Check that hitting a protected page redirects to the login. + recorder := web.getHttpResponse("/match_play") assert.Equal(t, 307, recorder.Code) - assert.Equal(t, "/login?redirect=/api/alliances", recorder.Header().Get("Location")) + assert.Equal(t, "/login?redirect=/match_play", recorder.Header().Get("Location")) - recorder = web.getHttpResponse("/login?redirect=/api/alliances") + recorder = web.getHttpResponse("/login?redirect=/match_play") assert.Equal(t, 200, recorder.Code) assert.Contains(t, recorder.Body.String(), "Log In - Untitled Event - Cheesy Arena") // Check logging in with the wrong username and right password. - recorder = web.postHttpResponse("/login?redirect=/api/alliances", "username=blorpy&password=reader") + recorder = web.postHttpResponse("/login?redirect=/match_play", "username=blorpy&password=reader") assert.Equal(t, 200, recorder.Code) assert.Contains(t, recorder.Body.String(), "Bad username or password") // Check logging in with the right username and wrong password. - recorder = web.postHttpResponse("/login?redirect=/api/alliances", "username=reader&password=blorpy") + recorder = web.postHttpResponse("/login?redirect=/match_play", "username=admin&password=blorpy") assert.Equal(t, 200, recorder.Code) assert.Contains(t, recorder.Body.String(), "Bad username or password") // Check logging in with the right username and password. - recorder = web.postHttpResponse("/login?redirect=/api/alliances", "username=reader&password=reader") + recorder = web.postHttpResponse("/login?redirect=/match_play", "username=admin&password=admin") assert.Equal(t, 303, recorder.Code) - assert.Equal(t, "/api/alliances", recorder.Header().Get("Location")) + assert.Equal(t, "/match_play", recorder.Header().Get("Location")) cookie := recorder.Header().Get("Set-Cookie") assert.Contains(t, cookie, "Authorization=") // Check that hitting the reader-level protected page works now. - recorder = web.getHttpResponseWithHeaders("/api/alliances", map[string]string{"Cookie": cookie}) - assert.Equal(t, 200, recorder.Code) - - // Check that hitting a admin-level protected at a higher level requires a different login. recorder = web.getHttpResponseWithHeaders("/match_play", map[string]string{"Cookie": cookie}) - assert.Equal(t, 307, recorder.Code) - assert.Equal(t, "/login?redirect=/match_play", recorder.Header().Get("Location")) - recorder = web.getHttpResponseWithHeaders("/login?redirect=/match_play", map[string]string{"Cookie": cookie}) - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "insufficient privileges") - recorder = web.postHttpResponse("/login?redirect=/match_play", "username=admin&password=admin") - assert.Equal(t, 303, recorder.Code) - assert.Equal(t, "/match_play", recorder.Header().Get("Location")) - cookie = recorder.Header().Get("Set-Cookie") - assert.Contains(t, cookie, "Authorization=") - recorder = web.getHttpResponseWithHeaders("/match_play", map[string]string{"Cookie": cookie}) - assert.Equal(t, 200, recorder.Code) - - // Check that the admin user also has access to the reader-level pages. - recorder = web.getHttpResponseWithHeaders("/api/alliances", map[string]string{"Cookie": cookie}) assert.Equal(t, 200, recorder.Code) } diff --git a/web/match_review.go b/web/match_review.go index b731374..9a5a888 100644 --- a/web/match_review.go +++ b/web/match_review.go @@ -26,10 +26,6 @@ type MatchReviewListItem struct { // Shows the match review interface. func (web *Web) matchReviewHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - practiceMatches, err := web.buildMatchReviewList("practice") if err != nil { handleWebErr(w, err) diff --git a/web/pit_display.go b/web/pit_display.go index 0c6fdeb..c1b3df8 100644 --- a/web/pit_display.go +++ b/web/pit_display.go @@ -13,10 +13,6 @@ import ( // Renders the pit display which shows scrolling rankings. func (web *Web) pitDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, map[string]string{"scrollMsPerRow": "1000"}) { return } @@ -38,10 +34,6 @@ func (web *Web) pitDisplayHandler(w http.ResponseWriter, r *http.Request) { // The websocket endpoint for the pit display, used only to force reloads remotely. func (web *Web) pitDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/placeholder_display.go b/web/placeholder_display.go index 198b2ef..7806ffe 100644 --- a/web/placeholder_display.go +++ b/web/placeholder_display.go @@ -13,10 +13,6 @@ import ( // Shows a random ID to visually identify the display so that it can be configured on the server. func (web *Web) placeholderDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, nil) { return } @@ -38,10 +34,6 @@ func (web *Web) placeholderDisplayHandler(w http.ResponseWriter, r *http.Request // The websocket endpoint for sending configuration commands to the display. func (web *Web) placeholderDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/queueing_display.go b/web/queueing_display.go index 5c6e4e4..90ccc9b 100644 --- a/web/queueing_display.go +++ b/web/queueing_display.go @@ -16,10 +16,6 @@ const numMatchesToShow = 5 // Renders the queueing display that shows upcoming matches and timing information. func (web *Web) queueingDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, nil) { return } @@ -61,10 +57,6 @@ func (web *Web) queueingDisplayHandler(w http.ResponseWriter, r *http.Request) { // The websocket endpoint for the queueing display to receive updates. func (web *Web) queueingDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/reports.go b/web/reports.go index a65267d..f88cb33 100644 --- a/web/reports.go +++ b/web/reports.go @@ -16,10 +16,6 @@ import ( // Generates a CSV-formatted report of the qualification rankings. func (web *Web) rankingsCsvReportHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - rankings, err := web.arena.Database.GetAllRankings() if err != nil { handleWebErr(w, err) @@ -42,10 +38,6 @@ func (web *Web) rankingsCsvReportHandler(w http.ResponseWriter, r *http.Request) // Generates a PDF-formatted report of the qualification rankings. func (web *Web) rankingsPdfReportHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - rankings, err := web.arena.Database.GetAllRankings() if err != nil { handleWebErr(w, err) @@ -104,10 +96,6 @@ func (web *Web) rankingsPdfReportHandler(w http.ResponseWriter, r *http.Request) // Generates a CSV-formatted report of the match schedule. func (web *Web) scheduleCsvReportHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - vars := mux.Vars(r) matches, err := web.arena.Database.GetMatchesByType(vars["type"]) if err != nil { @@ -131,10 +119,6 @@ func (web *Web) scheduleCsvReportHandler(w http.ResponseWriter, r *http.Request) // Generates a PDF-formatted report of the match schedule. func (web *Web) schedulePdfReportHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - vars := mux.Vars(r) matches, err := web.arena.Database.GetMatchesByType(vars["type"]) if err != nil { @@ -247,10 +231,6 @@ func (web *Web) schedulePdfReportHandler(w http.ResponseWriter, r *http.Request) // Generates a CSV-formatted report of the team list. func (web *Web) teamsCsvReportHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - teams, err := web.arena.Database.GetAllTeams() if err != nil { handleWebErr(w, err) @@ -273,10 +253,6 @@ func (web *Web) teamsCsvReportHandler(w http.ResponseWriter, r *http.Request) { // Generates a PDF-formatted report of the team list. func (web *Web) teamsPdfReportHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - teams, err := web.arena.Database.GetAllTeams() if err != nil { handleWebErr(w, err) diff --git a/web/setup_settings.go b/web/setup_settings.go index 0fc4f6e..657f194 100644 --- a/web/setup_settings.go +++ b/web/setup_settings.go @@ -65,7 +65,6 @@ func (web *Web) settingsPostHandler(w http.ResponseWriter, r *http.Request) { eventSettings.SwitchPassword = r.PostFormValue("switchPassword") eventSettings.PlcAddress = r.PostFormValue("plcAddress") eventSettings.AdminPassword = r.PostFormValue("adminPassword") - eventSettings.ReaderPassword = r.PostFormValue("readerPassword") eventSettings.HabDockingThreshold, _ = strconv.Atoi(r.PostFormValue("habDockingThreshold")) err := web.arena.Database.SaveEventSettings(eventSettings) diff --git a/web/twitch_display.go b/web/twitch_display.go index 0767659..2ebffe5 100644 --- a/web/twitch_display.go +++ b/web/twitch_display.go @@ -13,10 +13,6 @@ import ( // Renders the Twitch stream view. func (web *Web) twitchDisplayHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - if !web.enforceDisplayConfiguration(w, r, map[string]string{"channel": "team254"}) { return } @@ -38,10 +34,6 @@ func (web *Web) twitchDisplayHandler(w http.ResponseWriter, r *http.Request) { // The websocket endpoint for sending configuration commands to the display. func (web *Web) twitchDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) { - if !web.userIsReader(w, r) { - return - } - display, err := web.registerDisplay(r) if err != nil { handleWebErr(w, err) diff --git a/web/web.go b/web/web.go index a03e2ab..3ed17cf 100644 --- a/web/web.go +++ b/web/web.go @@ -18,8 +18,7 @@ import ( ) const ( - adminUser = "admin" - readerUser = "reader" + adminUser = "admin" ) type Web struct { @@ -108,29 +107,8 @@ func (web *Web) userIsAdmin(w http.ResponseWriter, r *http.Request) bool { } } -// Returns true if the given user is authorized for read-only operations. Used for HTTP cookie authentication. -func (web *Web) userIsReader(w http.ResponseWriter, r *http.Request) bool { - if web.arena.EventSettings.ReaderPassword == "" { - // Disable auth if there is no password configured. - return true - } - if username := web.cookieAuth.Authorize(r); username == readerUser || username == adminUser { - return true - } else { - http.Redirect(w, r, "/login?redirect="+r.URL.Path, 307) - return false - } -} - func (web *Web) checkAuthPassword(user, password string) bool { - switch user { - case adminUser: - return password == web.arena.EventSettings.AdminPassword - case readerUser: - return password == web.arena.EventSettings.ReaderPassword - default: - return false - } + return user == adminUser && password == web.arena.EventSettings.AdminPassword } // Sets up the mapping between URLs and handlers.