Files
cheesy-arena-lite/web/login.go
2020-04-04 14:19:47 -07:00

96 lines
2.6 KiB
Go

// Copyright 2018 Team 254. All Rights Reserved.
// Author: pat@patfairbank.com (Patrick Fairbank)
//
// Web routes for authenticating with the server.
package web
import (
"fmt"
"github.com/Team254/cheesy-arena/model"
"github.com/google/uuid"
"net/http"
"net/url"
"time"
)
// Shows the login form.
func (web *Web) loginHandler(w http.ResponseWriter, r *http.Request) {
web.renderLogin(w, r, "")
}
// Processes the login request.
func (web *Web) loginPostHandler(w http.ResponseWriter, r *http.Request) {
username := r.PostFormValue("username")
if err := web.checkAuthPassword(username, r.PostFormValue("password")); err != nil {
web.renderLogin(w, r, err.Error())
return
}
session := model.UserSession{Token: uuid.New().String(), Username: username, CreatedAt: time.Now()}
if err := web.arena.Database.CreateUserSession(&session); err != nil {
handleWebErr(w, err)
return
}
http.SetCookie(w, &http.Cookie{Name: sessionTokenCookie, Value: session.Token})
redirectUrl := r.URL.Query().Get("redirect")
if redirectUrl == "" {
redirectUrl = "/"
}
http.Redirect(w, r, redirectUrl, 303)
}
func (web *Web) renderLogin(w http.ResponseWriter, r *http.Request, errorMessage string) {
template, err := web.parseFiles("templates/login.html", "templates/base.html")
if err != nil {
handleWebErr(w, err)
return
}
data := struct {
*model.EventSettings
ErrorMessage string
}{web.arena.EventSettings, errorMessage}
err = template.ExecuteTemplate(w, "base", data)
if err != nil {
handleWebErr(w, err)
return
}
}
// 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 {
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 {
return true
} else {
redirect := r.URL.Path
if r.URL.RawQuery != "" {
redirect += "?" + r.URL.RawQuery
}
http.Redirect(w, r, "/login?redirect="+url.QueryEscape(redirect), 307)
return false
}
}
func (web *Web) getUserSessionFromCookie(r *http.Request) *model.UserSession {
token, err := r.Cookie(sessionTokenCookie)
if err != nil {
return nil
}
session, _ := web.arena.Database.GetUserSessionByToken(token.Value)
return session
}
func (web *Web) checkAuthPassword(user, password string) error {
if user == adminUser && password == web.arena.EventSettings.AdminPassword {
return nil
} else {
return fmt.Errorf("Invalid login credentials.")
}
}