Making progress
This commit is contained in:
parent
abd7e803e9
commit
9a77a25342
57
admin_clients.go
Normal file
57
admin_clients.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleAdminClients(w http.ResponseWriter, req *http.Request, page *pageData) {
|
||||||
|
vars := mux.Vars(req)
|
||||||
|
page.SubTitle = "Clients"
|
||||||
|
clientId := vars["id"]
|
||||||
|
clientIp, _, _ := net.SplitHostPort(req.RemoteAddr)
|
||||||
|
if clientId == "" {
|
||||||
|
type clientsPageData struct {
|
||||||
|
Clients []Client
|
||||||
|
}
|
||||||
|
page.TemplateData = clientsPageData{Clients: dbGetAllClients()}
|
||||||
|
page.SubTitle = "Clients"
|
||||||
|
page.show("admin-clients.html", w)
|
||||||
|
} else {
|
||||||
|
switch vars["function"] {
|
||||||
|
case "add":
|
||||||
|
type actClientPageData struct {
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
page.TemplateData = actClientPageData{Id: clientId}
|
||||||
|
page.show("admin-activateclient.html", w)
|
||||||
|
case "auth":
|
||||||
|
email := req.FormValue("email")
|
||||||
|
password := req.FormValue("password")
|
||||||
|
remember := req.FormValue("remember")
|
||||||
|
if doLogin(email, password) == nil {
|
||||||
|
// Received a valid login
|
||||||
|
// Authenticate the client
|
||||||
|
if dbAuthClient(clientId, clientIp) == nil {
|
||||||
|
page.session.setFlashMessage("Client Authenticated", "success")
|
||||||
|
} else {
|
||||||
|
page.session.setFlashMessage("Client Authentication Failed", "error")
|
||||||
|
}
|
||||||
|
if remember == "on" {
|
||||||
|
// Go ahead and log in
|
||||||
|
page.session.setStringValue("email", email)
|
||||||
|
redirect("/admin/clients", w, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
redirect("/", w, req)
|
||||||
|
case "deauth":
|
||||||
|
remember := req.FormValue("remember")
|
||||||
|
fmt.Println("Remember: ", remember)
|
||||||
|
dbDeAuthClient(clientId)
|
||||||
|
redirect("/admin/clients", w, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
admin_endpoints.go
Normal file
47
admin_endpoints.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initAdminRequest(w http.ResponseWriter, req *http.Request) *pageData {
|
||||||
|
p := InitPageData(w, req)
|
||||||
|
p.Stylesheets = append(p.Stylesheets, "/assets/css/admin.css")
|
||||||
|
p.Scripts = append(p.Scripts, "/assets/js/admin.js")
|
||||||
|
p.HideAdminMenu = false
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main admin handler, routes the request based on the category
|
||||||
|
func handleAdmin(w http.ResponseWriter, req *http.Request) {
|
||||||
|
page := initAdminRequest(w, req)
|
||||||
|
vars := mux.Vars(req)
|
||||||
|
if !page.LoggedIn {
|
||||||
|
if vars["category"] == "clients" &&
|
||||||
|
vars["id"] != "" &&
|
||||||
|
(vars["function"] == "add" || vars["function"] == "auth") {
|
||||||
|
// When authenticating a client, we have an all-in-one login/auth page
|
||||||
|
handleAdminClients(w, req, page)
|
||||||
|
} else {
|
||||||
|
page.SubTitle = "Admin Login"
|
||||||
|
page.show("admin-login.html", w)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
adminCategory := vars["category"]
|
||||||
|
switch adminCategory {
|
||||||
|
case "users":
|
||||||
|
handleAdminUsers(w, req, page)
|
||||||
|
case "teams":
|
||||||
|
handleAdminTeams(w, req, page)
|
||||||
|
case "games":
|
||||||
|
handleAdminGames(w, req, page)
|
||||||
|
case "clients":
|
||||||
|
handleAdminClients(w, req, page)
|
||||||
|
default:
|
||||||
|
page.show("admin-main.html", w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
admin_games.go
Normal file
6
admin_games.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
func handleAdminGames(w http.ResponseWriter, req *http.Request, page *pageData) {
|
||||||
|
}
|
70
admin_teams.go
Normal file
70
admin_teams.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData) {
|
||||||
|
vars := mux.Vars(req)
|
||||||
|
page.SubTitle = "Teams"
|
||||||
|
teamId := vars["id"]
|
||||||
|
if teamId == "new" {
|
||||||
|
switch vars["function"] {
|
||||||
|
case "save":
|
||||||
|
name := req.FormValue("teamname")
|
||||||
|
if dbIsValidTeam(name) {
|
||||||
|
// A team with that name already exists
|
||||||
|
page.session.setFlashMessage("A team with the name "+name+" already exists!", "error")
|
||||||
|
} else {
|
||||||
|
if err := dbCreateNewTeam(name); err != nil {
|
||||||
|
page.session.setFlashMessage(err.Error(), "error")
|
||||||
|
} else {
|
||||||
|
page.session.setFlashMessage("Team "+name+" created!", "success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
redirect("/admin/teams", w, req)
|
||||||
|
default:
|
||||||
|
page.SubTitle = "Add New Team"
|
||||||
|
page.show("admin-addteam.html", w)
|
||||||
|
}
|
||||||
|
} else if teamId != "" {
|
||||||
|
if dbIsValidTeam(teamId) {
|
||||||
|
switch vars["function"] {
|
||||||
|
case "save":
|
||||||
|
tm := new(Team)
|
||||||
|
tm.UUID = teamId
|
||||||
|
tm.Name = req.FormValue("teamname")
|
||||||
|
if err := dbUpdateTeam(teamId, tm); err != nil {
|
||||||
|
page.session.setFlashMessage("Error updating team: "+err.Error(), "error")
|
||||||
|
} else {
|
||||||
|
page.session.setFlashMessage("Team Updated!", "success")
|
||||||
|
}
|
||||||
|
redirect("/admin/teams", w, req)
|
||||||
|
case "delete":
|
||||||
|
var err error
|
||||||
|
if err = dbDeleteTeam(teamId); err != nil {
|
||||||
|
page.session.setFlashMessage("Error deleting team: "+err.Error(), "error")
|
||||||
|
}
|
||||||
|
redirect("/admin/teams", w, req)
|
||||||
|
default:
|
||||||
|
page.SubTitle = "Edit Team"
|
||||||
|
t := dbGetTeam(teamId)
|
||||||
|
page.TemplateData = t
|
||||||
|
page.show("admin-editteam.html", w)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
page.session.setFlashMessage("Couldn't find the requested team, please try again.", "error")
|
||||||
|
redirect("/admin/teams", w, req)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type teamsPageData struct {
|
||||||
|
Teams []Team
|
||||||
|
}
|
||||||
|
|
||||||
|
page.TemplateData = teamsPageData{Teams: dbGetAllTeams()}
|
||||||
|
page.SubTitle = "Teams"
|
||||||
|
page.show("admin-teams.html", w)
|
||||||
|
}
|
||||||
|
}
|
@ -1,62 +1,39 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initAdminRequest(w http.ResponseWriter, req *http.Request) *pageData {
|
|
||||||
p := InitPageData(w, req)
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/css/admin.css")
|
|
||||||
p.Scripts = append(p.Scripts, "/assets/js/admin.js")
|
|
||||||
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleAdmin
|
|
||||||
// Main admin handler, routes the request based on the category
|
|
||||||
func handleAdmin(w http.ResponseWriter, req *http.Request) {
|
|
||||||
page := initAdminRequest(w, req)
|
|
||||||
if !page.LoggedIn {
|
|
||||||
page.SubTitle = "Admin Login"
|
|
||||||
page.show("admin-login.html", w)
|
|
||||||
} else {
|
|
||||||
vars := mux.Vars(req)
|
|
||||||
adminCategory := vars["category"]
|
|
||||||
switch adminCategory {
|
|
||||||
case "users":
|
|
||||||
handleAdminUsers(w, req, page)
|
|
||||||
case "teams":
|
|
||||||
handleAdminTeams(w, req, page)
|
|
||||||
case "games":
|
|
||||||
handleAdminGames(w, req, page)
|
|
||||||
default:
|
|
||||||
page.show("admin-main.html", w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleAdminDoLogin
|
// handleAdminDoLogin
|
||||||
// Verify the provided credentials, set up a cookie (if requested)
|
// Verify the provided credentials, set up a cookie (if requested)
|
||||||
// and redirect back to /admin
|
// and redirect back to /admin
|
||||||
|
// TODO: Set up the cookie
|
||||||
func handleAdminDoLogin(w http.ResponseWriter, req *http.Request) {
|
func handleAdminDoLogin(w http.ResponseWriter, req *http.Request) {
|
||||||
page := initAdminRequest(w, req)
|
page := initAdminRequest(w, req)
|
||||||
// Fetch the login credentials
|
// Fetch the login credentials
|
||||||
email := req.FormValue("email")
|
email := req.FormValue("email")
|
||||||
password := req.FormValue("password")
|
password := req.FormValue("password")
|
||||||
if email != "" && password != "" {
|
if err := doLogin(email, password); err != nil {
|
||||||
if err := dbCheckCredentials(email, password); err != nil {
|
|
||||||
page.session.setFlashMessage("Invalid Login", "error")
|
page.session.setFlashMessage("Invalid Login", "error")
|
||||||
} else {
|
} else {
|
||||||
page.session.setStringValue("email", email)
|
page.session.setStringValue("email", email)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
page.session.setFlashMessage("Invalid Login", "error")
|
|
||||||
}
|
|
||||||
redirect("/admin", w, req)
|
redirect("/admin", w, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// doLogin attempts to log in with the given email/password
|
||||||
|
// If it can't, it returns an error
|
||||||
|
func doLogin(email, password string) error {
|
||||||
|
if strings.TrimSpace(email) != "" && strings.TrimSpace(password) != "" {
|
||||||
|
return dbCheckCredentials(email, password)
|
||||||
|
}
|
||||||
|
return errors.New("Invalid Credentials")
|
||||||
|
}
|
||||||
|
|
||||||
// handleAdminDoLogout
|
// handleAdminDoLogout
|
||||||
// Expire the session
|
// Expire the session
|
||||||
func handleAdminDoLogout(w http.ResponseWriter, req *http.Request) {
|
func handleAdminDoLogout(w http.ResponseWriter, req *http.Request) {
|
||||||
@ -136,64 +113,3 @@ func handleAdminUsers(w http.ResponseWriter, req *http.Request, page *pageData)
|
|||||||
page.show("admin-users.html", w)
|
page.show("admin-users.html", w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleAdminTeams
|
|
||||||
func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData) {
|
|
||||||
vars := mux.Vars(req)
|
|
||||||
page.SubTitle = "Teams"
|
|
||||||
teamId := vars["id"]
|
|
||||||
if teamId == "new" {
|
|
||||||
switch vars["function"] {
|
|
||||||
case "save":
|
|
||||||
name := req.FormValue("teamname")
|
|
||||||
if dbIsValidTeam(name) {
|
|
||||||
// A team with that name already exists
|
|
||||||
page.session.setFlashMessage("A team with the name "+name+" already exists!", "error")
|
|
||||||
} else {
|
|
||||||
if err := dbCreateNewTeam(name); err != nil {
|
|
||||||
page.session.setFlashMessage(err.Error(), "error")
|
|
||||||
} else {
|
|
||||||
page.session.setFlashMessage("Team "+name+" created!", "success")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
redirect("/admin/teams", w, req)
|
|
||||||
default:
|
|
||||||
page.SubTitle = "Add New Team"
|
|
||||||
page.show("admin-addteam.html", w)
|
|
||||||
}
|
|
||||||
} else if teamId != "" {
|
|
||||||
if dbIsValidTeam(teamId) {
|
|
||||||
switch vars["function"] {
|
|
||||||
case "save":
|
|
||||||
page.session.setFlashMessage("Not implemented yet...", "success")
|
|
||||||
redirect("/admin/teams", w, req)
|
|
||||||
case "delete":
|
|
||||||
var err error
|
|
||||||
if err = dbDeleteTeam(teamId); err != nil {
|
|
||||||
page.session.setFlashMessage("Error deleting team: "+err.Error(), "error")
|
|
||||||
}
|
|
||||||
redirect("/admin/teams", w, req)
|
|
||||||
default:
|
|
||||||
page.SubTitle = "Edit Team"
|
|
||||||
t := dbGetTeam(teamId)
|
|
||||||
page.TemplateData = t
|
|
||||||
page.show("admin-editteam.html", w)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
page.session.setFlashMessage("Couldn't find the requested team, please try again.", "error")
|
|
||||||
redirect("/admin/teams", w, req)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
type teamsPageData struct {
|
|
||||||
Teams []Team
|
|
||||||
}
|
|
||||||
|
|
||||||
page.TemplateData = teamsPageData{Teams: dbGetAllTeams()}
|
|
||||||
page.SubTitle = "Teams"
|
|
||||||
page.show("admin-teams.html", w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleAdminGames
|
|
||||||
func handleAdminGames(w http.ResponseWriter, req *http.Request, page *pageData) {
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
function showAdminPanel() {
|
function toggleAdminPanel() {
|
||||||
|
document.querySelector('#menu').classList.toggle('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -12,6 +12,6 @@ document.onkeydown = function(evt) {
|
|||||||
isEscape = (evt.keyCode == 27);
|
isEscape = (evt.keyCode == 27);
|
||||||
}
|
}
|
||||||
if(isEscape) {
|
if(isEscape) {
|
||||||
showAdminPanel();
|
toggleAdminPanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
main.go
16
main.go
@ -48,8 +48,11 @@ type pageData struct {
|
|||||||
LoggedIn bool
|
LoggedIn bool
|
||||||
Menu []menuItem
|
Menu []menuItem
|
||||||
BottomMenu []menuItem
|
BottomMenu []menuItem
|
||||||
|
HideAdminMenu bool
|
||||||
session *pageSession
|
session *pageSession
|
||||||
CurrentJam string
|
CurrentJam string
|
||||||
|
ClientID string
|
||||||
|
ClientIsAuth bool
|
||||||
|
|
||||||
TemplateData interface{}
|
TemplateData interface{}
|
||||||
}
|
}
|
||||||
@ -159,6 +162,13 @@ func initialize() {
|
|||||||
fmt.Println("Error saving Current Jam")
|
fmt.Println("Error saving Current Jam")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jmNm, err := dbGetCurrentJam()
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println("Current Jam Name: " + jmNm)
|
||||||
|
} else {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loggingHandler(h http.Handler) http.Handler {
|
func loggingHandler(h http.Handler) http.Handler {
|
||||||
@ -215,13 +225,19 @@ func InitPageData(w http.ResponseWriter, req *http.Request) *pageData {
|
|||||||
|
|
||||||
p.BottomMenu = append(p.BottomMenu, menuItem{"Users", "/admin/users", "fa-user"})
|
p.BottomMenu = append(p.BottomMenu, menuItem{"Users", "/admin/users", "fa-user"})
|
||||||
p.BottomMenu = append(p.BottomMenu, menuItem{"Logout", "/admin/dologout", "fa-sign-out"})
|
p.BottomMenu = append(p.BottomMenu, menuItem{"Logout", "/admin/dologout", "fa-sign-out"})
|
||||||
|
} else {
|
||||||
|
p.BottomMenu = append(p.BottomMenu, menuItem{"Admin", "/admin", "fa-sign-in"})
|
||||||
}
|
}
|
||||||
|
p.HideAdminMenu = true
|
||||||
|
|
||||||
if p.CurrentJam, err = dbGetCurrentJam(); err != nil {
|
if p.CurrentJam, err = dbGetCurrentJam(); err != nil {
|
||||||
p.FlashMessage = "Error Loading Current GameJam: " + err.Error()
|
p.FlashMessage = "Error Loading Current GameJam: " + err.Error()
|
||||||
p.FlashClass = "error"
|
p.FlashClass = "error"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.ClientID = p.session.getClientID()
|
||||||
|
p.ClientIsAuth = dbClientIsAuth(p.ClientID)
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
model.go
53
model.go
@ -1,6 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/br0xen/boltease"
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/br0xen/boltease"
|
||||||
|
)
|
||||||
|
|
||||||
var db *boltease.DB
|
var db *boltease.DB
|
||||||
var dbOpened bool
|
var dbOpened bool
|
||||||
@ -24,7 +29,7 @@ func initDatabase() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Create the path to the bucket to store jam informations
|
// Create the path to the bucket to store jam informations
|
||||||
if err := db.MkBucketPath([]string{"jams"}); err != nil {
|
if err := db.MkBucketPath([]string{"jam"}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Create the path to the bucket to store site config data
|
// Create the path to the bucket to store site config data
|
||||||
@ -41,51 +46,25 @@ func dbSetCurrentJam(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dbHasCurrentJam() bool {
|
func dbHasCurrentJam() bool {
|
||||||
var nm string
|
|
||||||
var err error
|
var err error
|
||||||
if nm, err = dbGetCurrentJam(); err != nil {
|
if _, err = dbGetCurrentJam(); err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
ret, err := dbIsValidJam(nm)
|
return true
|
||||||
return ret && err != nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbGetCurrentJam() (string, error) {
|
func dbGetCurrentJam() (string, error) {
|
||||||
if err := db.OpenDB(); err != nil {
|
var ret string
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
return db.GetValue([]string{"site"}, "current-jam")
|
ret, err = db.GetValue([]string{"site"}, "current-jam")
|
||||||
}
|
|
||||||
|
|
||||||
func dbIsValidJam(name string) (bool, error) {
|
if err == nil && strings.TrimSpace(ret) == "" {
|
||||||
var err error
|
return ret, errors.New("No Jam Name Specified")
|
||||||
if err = db.OpenDB(); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
return ret, err
|
||||||
|
|
||||||
// Get all keys in the jams bucket
|
|
||||||
var keys []string
|
|
||||||
if keys, err = db.GetKeyList([]string{"jams", name}); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
// All valid gamejams will have:
|
|
||||||
// "name"
|
|
||||||
// "teams"
|
|
||||||
for _, v := range []string{"name", "teams"} {
|
|
||||||
found := false
|
|
||||||
for j := range keys {
|
|
||||||
if keys[j] == v {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
// If we make it here, we didn't find a key we need
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
}
|
||||||
|
101
model_clients.go
Normal file
101
model_clients.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
UUID string
|
||||||
|
Auth bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbGetAllClients() []Client {
|
||||||
|
var ret []Client
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
var clientUids []string
|
||||||
|
if clientUids, err = db.GetBucketList([]string{"clients"}); err != nil {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
for _, v := range clientUids {
|
||||||
|
if cl := dbGetClient(v); cl != nil {
|
||||||
|
ret = append(ret, *cl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbGetClient(id string) *Client {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
cl := new(Client)
|
||||||
|
cl.UUID = id
|
||||||
|
cl.Auth = dbClientIsAuth(id)
|
||||||
|
return cl
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbAddDeauthClient(cid, ip string) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
err = db.SetBool([]string{"clients", cid}, "auth", false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return db.SetValue([]string{"clients", cid}, "ip", ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbAuthClient(cid, ip string) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
err = db.SetBool([]string{"clients", cid}, "auth", false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return db.SetValue([]string{"clients", cid}, "ip", ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbDeAuthClient(cid string) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
return db.SetBool([]string{"clients", cid}, "auth", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbClientIsAuth(cid string) bool {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
var isAuth bool
|
||||||
|
if isAuth, err = db.GetBool([]string{"clients", cid}, "auth"); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return isAuth
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbUpdateClientIP(cid, ip string) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
return db.SetValue([]string{"clients", cid}, "ip", ip)
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/pborman/uuid"
|
"github.com/pborman/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,99 +26,78 @@ func dbCreateNewTeam(nm string) error {
|
|||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
var currJam string
|
|
||||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a UUID
|
// Generate a UUID
|
||||||
uuid := uuid.New()
|
uuid := uuid.New()
|
||||||
teamPath := []string{"jams", currJam, "teams", uuid}
|
teamPath := []string{"teams", uuid}
|
||||||
|
|
||||||
if err := db.MkBucketPath(teamPath); err != nil {
|
if err := db.MkBucketPath(teamPath); err != nil {
|
||||||
fmt.Println("Error at 39: " + uuid)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := db.SetValue(teamPath, "name", nm); err != nil {
|
if err := db.SetValue(teamPath, "name", nm); err != nil {
|
||||||
fmt.Println("Error at 43")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := db.MkBucketPath(append(teamPath, "members")); err != nil {
|
if err := db.MkBucketPath(append(teamPath, "members")); err != nil {
|
||||||
fmt.Println("Error at 47")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
gamePath := append(teamPath, "game")
|
gamePath := append(teamPath, "game")
|
||||||
if err := db.MkBucketPath(gamePath); err != nil {
|
if err := db.MkBucketPath(gamePath); err != nil {
|
||||||
fmt.Println("Error at 52")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := db.SetValue(append(gamePath), "name", ""); err != nil {
|
if err := db.SetValue(append(gamePath), "name", ""); err != nil {
|
||||||
fmt.Println("Error at 56")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return db.MkBucketPath(append(gamePath, "screenshots"))
|
return db.MkBucketPath(append(gamePath, "screenshots"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbIsValidTeam(nm string) bool {
|
func dbIsValidTeam(id string) bool {
|
||||||
var err error
|
var err error
|
||||||
var currJam string
|
|
||||||
if err = db.OpenDB(); err != nil {
|
if err = db.OpenDB(); err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
teamPath := []string{"teams"}
|
||||||
return false
|
|
||||||
}
|
|
||||||
teamPath := []string{"jams", currJam, "teams"}
|
|
||||||
if teamUids, err := db.GetBucketList(teamPath); err == nil {
|
if teamUids, err := db.GetBucketList(teamPath); err == nil {
|
||||||
for _, v := range teamUids {
|
for _, v := range teamUids {
|
||||||
if tstName, err := db.GetValue(append(teamPath, v), "name"); err == nil {
|
if v == id {
|
||||||
if tstName == nm {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbGetAllTeams() []Team {
|
func dbGetAllTeams() []Team {
|
||||||
var ret []Team
|
var ret []Team
|
||||||
var err error
|
var err error
|
||||||
var currJam string
|
|
||||||
if err = db.OpenDB(); err != nil {
|
if err = db.OpenDB(); err != nil {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
teamPath := []string{"teams"}
|
||||||
|
var teamUids []string
|
||||||
|
if teamUids, err = db.GetBucketList(teamPath); err != nil {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
teamPath := []string{"jams", currJam, "teams"}
|
|
||||||
if teamUids, err := db.GetBucketList(teamPath); err != nil {
|
|
||||||
for _, v := range teamUids {
|
for _, v := range teamUids {
|
||||||
if tm := dbGetTeam(v); tm != nil {
|
if tm := dbGetTeam(v); tm != nil {
|
||||||
ret = append(ret, *tm)
|
ret = append(ret, *tm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbGetTeam(id string) *Team {
|
func dbGetTeam(id string) *Team {
|
||||||
var err error
|
var err error
|
||||||
var currJam string
|
|
||||||
if err = db.OpenDB(); err != nil {
|
if err = db.OpenDB(); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
teamPath := []string{"teams", id}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
teamPath := []string{"jams", currJam, "teams", id}
|
|
||||||
tm := new(Team)
|
tm := new(Team)
|
||||||
|
tm.UUID = id
|
||||||
if tm.Name, err = db.GetValue(teamPath, "name"); err != nil {
|
if tm.Name, err = db.GetValue(teamPath, "name"); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -129,16 +106,12 @@ func dbGetTeam(id string) *Team {
|
|||||||
|
|
||||||
func dbGetTeamByName(nm string) *Team {
|
func dbGetTeamByName(nm string) *Team {
|
||||||
var err error
|
var err error
|
||||||
var currJam string
|
|
||||||
if err = db.OpenDB(); err != nil {
|
if err = db.OpenDB(); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
teamPath := []string{"teams"}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
teamPath := []string{"jams", currJam, "teams"}
|
|
||||||
var teamUids []string
|
var teamUids []string
|
||||||
if teamUids, err = db.GetBucketList(teamPath); err != nil {
|
if teamUids, err = db.GetBucketList(teamPath); err != nil {
|
||||||
for _, v := range teamUids {
|
for _, v := range teamUids {
|
||||||
@ -151,17 +124,24 @@ func dbGetTeamByName(nm string) *Team {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dbUpdateTeam(id string, tm *Team) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
teamPath := []string{"teams", id}
|
||||||
|
return db.SetValue(teamPath, "name", tm.Name)
|
||||||
|
}
|
||||||
|
|
||||||
func dbDeleteTeam(id string) error {
|
func dbDeleteTeam(id string) error {
|
||||||
var err error
|
var err error
|
||||||
var currJam string
|
|
||||||
if err = db.OpenDB(); err != nil {
|
if err = db.OpenDB(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
teamPath := []string{"teams"}
|
||||||
return err
|
|
||||||
}
|
|
||||||
teamPath := []string{"jams", currJam, "teams"}
|
|
||||||
return db.DeleteBucket(teamPath, id)
|
return db.DeleteBucket(teamPath, id)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
|
"github.com/pborman/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is basically a convenience struct for
|
// This is basically a convenience struct for
|
||||||
@ -30,6 +31,17 @@ func (p *pageSession) setStringValue(key, val string) {
|
|||||||
p.session.Save(p.req, p.w)
|
p.session.Save(p.req, p.w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *pageSession) getClientID() string {
|
||||||
|
var clientId string
|
||||||
|
var err error
|
||||||
|
if clientId, err = p.getStringValue("client_id"); err != nil {
|
||||||
|
// No client id, generate and save one
|
||||||
|
clientId := uuid.New()
|
||||||
|
p.setStringValue("client_id", clientId)
|
||||||
|
}
|
||||||
|
return clientId
|
||||||
|
}
|
||||||
|
|
||||||
func (p *pageSession) setFlashMessage(msg, status string) {
|
func (p *pageSession) setFlashMessage(msg, status string) {
|
||||||
p.setStringValue("flash_message", msg)
|
p.setStringValue("flash_message", msg)
|
||||||
p.setStringValue("flash_status", status)
|
p.setStringValue("flash_status", status)
|
@ -7,14 +7,18 @@ import (
|
|||||||
|
|
||||||
func initPublicPage(w http.ResponseWriter, req *http.Request) *pageData {
|
func initPublicPage(w http.ResponseWriter, req *http.Request) *pageData {
|
||||||
p := InitPageData(w, req)
|
p := InitPageData(w, req)
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMain(w http.ResponseWriter, req *http.Request) {
|
func handleMain(w http.ResponseWriter, req *http.Request) {
|
||||||
page := initPublicPage(w, req)
|
page := initPublicPage(w, req)
|
||||||
page.SubTitle = "!"
|
page.SubTitle = ""
|
||||||
|
|
||||||
for _, tmpl := range []string{
|
for _, tmpl := range []string{
|
||||||
"htmlheader.html",
|
"htmlheader.html",
|
||||||
|
"admin-menu.html",
|
||||||
|
"header.html",
|
||||||
"main.html",
|
"main.html",
|
||||||
"footer.html",
|
"footer.html",
|
||||||
"htmlfooter.html",
|
"htmlfooter.html",
|
22
templates/admin-activateclient.html
Normal file
22
templates/admin-activateclient.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<div class="center">
|
||||||
|
<form class="pure-form pure-form-aligned" action="/admin/clients/{{ .TemplateData.Id }}/auth" method="POST">
|
||||||
|
<fieldset>
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label for="email">Email Address</label>
|
||||||
|
<input id="email" name="email" type="text" placeholder="Email Address" autofocus>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input id="password" name="password" type="password" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pure-controls">
|
||||||
|
<label for="remember" class="pure-checkbox">
|
||||||
|
<input id="remember" name="remember" type="checkbox"> Stay Logged In
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="pure-button pure-button-primary">Submit</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
@ -3,7 +3,7 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
<label for="teamname">Team Name</label>
|
<label for="teamname">Team Name</label>
|
||||||
<input id="teamname" name="teamname" type="text" placeholder="Team Name" value="">
|
<input id="teamname" name="teamname" type="text" placeholder="Team Name" value="" autofocus>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="pure-button pure-button-primary">Add Team</button>
|
<button type="submit" class="pure-button pure-button-primary">Add Team</button>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
<label for="email">Email Address</label>
|
<label for="email">Email Address</label>
|
||||||
<input id="email" name="email" type="text" placeholder="Email Address" value="">
|
<input id="email" name="email" type="text" placeholder="Email Address" value="" autofocus>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
|
28
templates/admin-clients.html
Normal file
28
templates/admin-clients.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<table id="clients-table" class="hidden sortable pure-table pure-table-bordered center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Client ID</th>
|
||||||
|
<th>Last Known IP</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range $i, $v := .TemplateData.Clients }}
|
||||||
|
<tr>
|
||||||
|
<td>{{ $v.Id }}</td>
|
||||||
|
<td>{{ $v.Ip }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="/admin/clients/{{ $v.UUID }}/deauth" class="pure-button pure-button-plain"><i class="fa fa-trash"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<script>
|
||||||
|
snack.ready(function() {
|
||||||
|
var tableBody = document.querySelector("#clients-table>tbody");
|
||||||
|
if(tableBody.children.length>0) {
|
||||||
|
// Show the table
|
||||||
|
document.getElementById('clients-table').classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
<label class="control-label" for="teamname">Team Name</label>
|
<label class="control-label" for="teamname">Team Name</label>
|
||||||
<input id="teamname" name="teamname" type="password" placeholder="Team Name">
|
<input id="teamname" name="teamname" value="{{.TemplateData.Name}}" placeholder="Team Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pure-control-group reset-pull">
|
<div class="pure-control-group reset-pull">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
<label for="email">Email Address</label>
|
<label for="email">Email Address</label>
|
||||||
<input id="email" name="email" type="text" placeholder="Email Address">
|
<input id="email" name="email" type="text" placeholder="Email Address" autofocus>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div id="menu">
|
<div id="menu" class="{{if .HideAdminMenu}}hidden{{end}}">
|
||||||
<div class="pure-menu">
|
<div class="pure-menu">
|
||||||
<a class="pure-menu-heading" href="/admin/">Admin</a>
|
<a class="pure-menu-heading" href="/admin/">Admin</a>
|
||||||
<a href="#menu" class="menu-button">
|
<a href="#menu" class="menu-button">
|
||||||
@ -12,6 +12,11 @@
|
|||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
{{if .ClientIsAuth}}
|
||||||
|
<a href="/admin/clients/{{.ClientID}}/remove" class="pure-menu-link"><i class="fa fa-key"></i> DeAuth Client</a>
|
||||||
|
{{else}}
|
||||||
|
<a href="/admin/clients/{{.ClientID}}/add" class="pure-menu-link"><i class="fa fa-key"></i> Auth Client</a>
|
||||||
|
{{end}}
|
||||||
<ul class="pure-menu-list menu-bottom">
|
<ul class="pure-menu-list menu-bottom">
|
||||||
{{ range $k, $v := .BottomMenu }}
|
{{ range $k, $v := .BottomMenu }}
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ $v.Name }}</td>
|
<td>{{ $v.Name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="/admin/users/{{ $v.UUID }}/edit" class="pure-button pure-button-plain"><i class="fa fa-pencil"></i></a>
|
<a href="/admin/teams/{{ $v.UUID }}/edit" class="pure-button pure-button-plain"><i class="fa fa-pencil"></i></a>
|
||||||
<a href="/admin/users/{{ $v.UUID }}/delete" class="pure-button pure-button-plain"><i class="fa fa-trash"></i></a>
|
<a href="/admin/teams/{{ $v.UUID }}/delete" class="pure-button pure-button-plain"><i class="fa fa-trash"></i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
var clientID = "{{.ClientID}}";
|
||||||
|
</script>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<aside class="flash center {{.FlashClass}}">
|
<aside class="flash center {{.FlashClass}}">
|
||||||
{{.FlashMessage}}
|
{{.FlashMessage}}
|
||||||
</aside>
|
</aside>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
ICT GameJam 2017
|
devICT Game Jam - {{.CurrentJam}}
|
||||||
</div>
|
</div>
|
||||||
<div class="header-menu">
|
<div class="header-menu">
|
||||||
<h2>{{.SubTitle}}</h2>
|
<h2>{{.SubTitle}}</h2>
|
||||||
|
Loading…
Reference in New Issue
Block a user