Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

require authentication as 'ref' user to view ref pages #12

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions model/event_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type EventSettings struct {
SwitchPassword string
PlcAddress string
AdminPassword string
RefPassword string
WarmupDurationSec int
AutoDurationSec int
PauseDurationSec int
Expand Down
4 changes: 4 additions & 0 deletions templates/setup_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@
<div class="col-lg-7">
<input type="password" class="form-control" name="adminPassword" value="{{.AdminPassword}}">
</div>
<label class="col-lg-5 control-label">Password for 'ref' user</label>
<div class="col-lg-7">
<input type="password" class="form-control" name="refPassword" value="{{.RefPassword}}">
</div>
</div>
</fieldset>
<fieldset>
Expand Down
8 changes: 8 additions & 0 deletions web/headref_display.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import (
// through a websockets integration, the head ref will be able to see score updates submitted by other
// refs in realtime.
func (web *Web) headrefDisplayHandler(w http.ResponseWriter, r *http.Request) {
if !web.userIsExpected(w, r, []string{adminUser, refUser}) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there be some sort of error message returned to the client here? something equivalent to handleWebErr

return
}

// if !web.enforceDisplayConfiguration(w, r, map[string]string{"background": "#0f0", "reversed": "false",
// "overlayLocation": "bottom"}) {
// return
Expand Down Expand Up @@ -41,6 +45,10 @@ func (web *Web) headrefDisplayHandler(w http.ResponseWriter, r *http.Request) {

// The websocket endpoint for the ref display client to receive status updates.
func (web *Web) headrefDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
if !web.userIsExpected(w, r, []string{adminUser, refUser}) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there be some sort of error message returned to the client here? something equivalent to handleWebErr

return
}

ws, err := websocket.NewWebsocket(w, r)
if err != nil {
handleWebErr(w, err)
Expand Down
29 changes: 25 additions & 4 deletions web/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ package web

import (
"fmt"
"github.com/Team254/cheesy-arena-lite/model"
"github.com/google/uuid"
"net/http"
"net/url"
"time"

"github.com/Team254/cheesy-arena-lite/model"
"github.com/google/uuid"
)

// Shows the login form.
Expand Down Expand Up @@ -58,14 +59,24 @@ func (web *Web) renderLogin(w http.ResponseWriter, r *http.Request, errorMessage
}
}

func contains(slice []string, expected string) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for _, s := range slice {
if s == expected {
return true
}
}
return false

}

// Returns true if the given user is authorized for admin operations. Used for HTTP cookie authentication.
func (web *Web) userIsAdmin(w http.ResponseWriter, r *http.Request) bool {
func (web *Web) userIsExpected(w http.ResponseWriter, r *http.Request, expectedUsers []string) bool {
if web.arena.EventSettings.AdminPassword == "" {
// Disable auth if there is no password configured.
return true
}
session := web.getUserSessionFromCookie(r)
if session != nil && session.Username == adminUser {
if session != nil && contains(expectedUsers, session.Username) {
return true
} else {
redirect := r.URL.Path
Expand All @@ -77,6 +88,14 @@ func (web *Web) userIsAdmin(w http.ResponseWriter, r *http.Request) bool {
}
}

func (web *Web) userIsAdmin(w http.ResponseWriter, r *http.Request) bool {
return web.userIsExpected(w, r, []string{adminUser})
}

func (web *Web) userIsRef(w http.ResponseWriter, r *http.Request) bool {
return web.userIsExpected(w, r, []string{refUser})
}

func (web *Web) getUserSessionFromCookie(r *http.Request) *model.UserSession {
token, err := r.Cookie(sessionTokenCookie)
if err != nil {
Expand All @@ -89,6 +108,8 @@ func (web *Web) getUserSessionFromCookie(r *http.Request) *model.UserSession {
func (web *Web) checkAuthPassword(user, password string) error {
if user == adminUser && password == web.arena.EventSettings.AdminPassword {
return nil
} else if user == refUser && password == web.arena.EventSettings.RefPassword {
return nil
} else {
return fmt.Errorf("Invalid login credentials.")
}
Expand Down
8 changes: 8 additions & 0 deletions web/ref_display.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
// field elements. through a websockets integration, each ref will be able to see score updates
// submitted by other refs in realtime.
func (web *Web) refDisplayHandler(w http.ResponseWriter, r *http.Request) {
if !web.userIsExpected(w, r, []string{adminUser, refUser}) {
return
}

vars := mux.Vars(r)
alliance := vars["alliance"]
if alliance != "red" && alliance != "blue" {
Expand Down Expand Up @@ -48,6 +52,10 @@ func (web *Web) refDisplayHandler(w http.ResponseWriter, r *http.Request) {

// The websocket endpoint for the ref display client to receive status updates.
func (web *Web) refDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
if !web.userIsExpected(w, r, []string{adminUser, refUser}) {
return
}

ws, err := websocket.NewWebsocket(w, r)
if err != nil {
handleWebErr(w, err)
Expand Down
4 changes: 3 additions & 1 deletion web/setup_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ package web

import (
"fmt"
"github.com/Team254/cheesy-arena-lite/model"
"io"
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"
"time"

"github.com/Team254/cheesy-arena-lite/model"
)

// Shows the event settings editing page.
Expand Down Expand Up @@ -76,6 +77,7 @@ 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.RefPassword = r.PostFormValue("refPassword")
eventSettings.WarmupDurationSec, _ = strconv.Atoi(r.PostFormValue("warmupDurationSec"))
eventSettings.AutoDurationSec, _ = strconv.Atoi(r.PostFormValue("autoDurationSec"))
eventSettings.PauseDurationSec, _ = strconv.Atoi(r.PostFormValue("pauseDurationSec"))
Expand Down
1 change: 1 addition & 0 deletions web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
const (
sessionTokenCookie = "session_token"
adminUser = "admin"
refUser = "ref"
)

type Web struct {
Expand Down