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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"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
|
||||
// Verify the provided credentials, set up a cookie (if requested)
|
||||
// and redirect back to /admin
|
||||
// TODO: Set up the cookie
|
||||
func handleAdminDoLogin(w http.ResponseWriter, req *http.Request) {
|
||||
page := initAdminRequest(w, req)
|
||||
// Fetch the login credentials
|
||||
email := req.FormValue("email")
|
||||
password := req.FormValue("password")
|
||||
if email != "" && password != "" {
|
||||
if err := dbCheckCredentials(email, password); err != nil {
|
||||
if err := doLogin(email, password); err != nil {
|
||||
page.session.setFlashMessage("Invalid Login", "error")
|
||||
} else {
|
||||
page.session.setStringValue("email", email)
|
||||
}
|
||||
} else {
|
||||
page.session.setFlashMessage("Invalid Login", "error")
|
||||
}
|
||||
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
|
||||
// Expire the session
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
if(isEscape) {
|
||||
showAdminPanel();
|
||||
toggleAdminPanel();
|
||||
}
|
||||
}
|
||||
|
16
main.go
16
main.go
@ -48,8 +48,11 @@ type pageData struct {
|
||||
LoggedIn bool
|
||||
Menu []menuItem
|
||||
BottomMenu []menuItem
|
||||
HideAdminMenu bool
|
||||
session *pageSession
|
||||
CurrentJam string
|
||||
ClientID string
|
||||
ClientIsAuth bool
|
||||
|
||||
TemplateData interface{}
|
||||
}
|
||||
@ -159,6 +162,13 @@ func initialize() {
|
||||
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 {
|
||||
@ -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{"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 {
|
||||
p.FlashMessage = "Error Loading Current GameJam: " + err.Error()
|
||||
p.FlashClass = "error"
|
||||
}
|
||||
|
||||
p.ClientID = p.session.getClientID()
|
||||
p.ClientIsAuth = dbClientIsAuth(p.ClientID)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
|
53
model.go
53
model.go
@ -1,6 +1,11 @@
|
||||
package main
|
||||
|
||||
import "github.com/br0xen/boltease"
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/br0xen/boltease"
|
||||
)
|
||||
|
||||
var db *boltease.DB
|
||||
var dbOpened bool
|
||||
@ -24,7 +29,7 @@ func initDatabase() error {
|
||||
return err
|
||||
}
|
||||
// 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
|
||||
}
|
||||
// Create the path to the bucket to store site config data
|
||||
@ -41,51 +46,25 @@ func dbSetCurrentJam(name string) error {
|
||||
}
|
||||
|
||||
func dbHasCurrentJam() bool {
|
||||
var nm string
|
||||
var err error
|
||||
if nm, err = dbGetCurrentJam(); err != nil {
|
||||
if _, err = dbGetCurrentJam(); err != nil {
|
||||
return false
|
||||
}
|
||||
ret, err := dbIsValidJam(nm)
|
||||
return ret && err != nil
|
||||
return true
|
||||
}
|
||||
|
||||
func dbGetCurrentJam() (string, error) {
|
||||
if err := db.OpenDB(); err != nil {
|
||||
var ret string
|
||||
var err error
|
||||
if err = db.OpenDB(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer db.CloseDB()
|
||||
|
||||
return db.GetValue([]string{"site"}, "current-jam")
|
||||
}
|
||||
ret, err = db.GetValue([]string{"site"}, "current-jam")
|
||||
|
||||
func dbIsValidJam(name string) (bool, error) {
|
||||
var err error
|
||||
if err = db.OpenDB(); err != nil {
|
||||
return false, err
|
||||
if err == nil && strings.TrimSpace(ret) == "" {
|
||||
return ret, errors.New("No Jam Name Specified")
|
||||
}
|
||||
defer db.CloseDB()
|
||||
|
||||
// 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
|
||||
return ret, err
|
||||
}
|
||||
|
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pborman/uuid"
|
||||
)
|
||||
|
||||
@ -28,99 +26,78 @@ func dbCreateNewTeam(nm string) error {
|
||||
}
|
||||
defer db.CloseDB()
|
||||
|
||||
var currJam string
|
||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate a UUID
|
||||
uuid := uuid.New()
|
||||
teamPath := []string{"jams", currJam, "teams", uuid}
|
||||
teamPath := []string{"teams", uuid}
|
||||
|
||||
if err := db.MkBucketPath(teamPath); err != nil {
|
||||
fmt.Println("Error at 39: " + uuid)
|
||||
return err
|
||||
}
|
||||
if err := db.SetValue(teamPath, "name", nm); err != nil {
|
||||
fmt.Println("Error at 43")
|
||||
return err
|
||||
}
|
||||
if err := db.MkBucketPath(append(teamPath, "members")); err != nil {
|
||||
fmt.Println("Error at 47")
|
||||
return err
|
||||
}
|
||||
gamePath := append(teamPath, "game")
|
||||
if err := db.MkBucketPath(gamePath); err != nil {
|
||||
fmt.Println("Error at 52")
|
||||
return err
|
||||
}
|
||||
if err := db.SetValue(append(gamePath), "name", ""); err != nil {
|
||||
fmt.Println("Error at 56")
|
||||
return err
|
||||
}
|
||||
return db.MkBucketPath(append(gamePath, "screenshots"))
|
||||
}
|
||||
|
||||
func dbIsValidTeam(nm string) bool {
|
||||
func dbIsValidTeam(id string) bool {
|
||||
var err error
|
||||
var currJam string
|
||||
if err = db.OpenDB(); err != nil {
|
||||
return false
|
||||
}
|
||||
defer db.CloseDB()
|
||||
|
||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
||||
return false
|
||||
}
|
||||
teamPath := []string{"jams", currJam, "teams"}
|
||||
teamPath := []string{"teams"}
|
||||
if teamUids, err := db.GetBucketList(teamPath); err == nil {
|
||||
for _, v := range teamUids {
|
||||
if tstName, err := db.GetValue(append(teamPath, v), "name"); err == nil {
|
||||
if tstName == nm {
|
||||
if v == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func dbGetAllTeams() []Team {
|
||||
var ret []Team
|
||||
var err error
|
||||
var currJam string
|
||||
if err = db.OpenDB(); err != nil {
|
||||
return ret
|
||||
}
|
||||
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
|
||||
}
|
||||
teamPath := []string{"jams", currJam, "teams"}
|
||||
if teamUids, err := db.GetBucketList(teamPath); err != nil {
|
||||
for _, v := range teamUids {
|
||||
if tm := dbGetTeam(v); tm != nil {
|
||||
ret = append(ret, *tm)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func dbGetTeam(id string) *Team {
|
||||
var err error
|
||||
var currJam string
|
||||
if err = db.OpenDB(); err != nil {
|
||||
return nil
|
||||
}
|
||||
defer db.CloseDB()
|
||||
|
||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
||||
return nil
|
||||
}
|
||||
teamPath := []string{"jams", currJam, "teams", id}
|
||||
teamPath := []string{"teams", id}
|
||||
tm := new(Team)
|
||||
tm.UUID = id
|
||||
if tm.Name, err = db.GetValue(teamPath, "name"); err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -129,16 +106,12 @@ func dbGetTeam(id string) *Team {
|
||||
|
||||
func dbGetTeamByName(nm string) *Team {
|
||||
var err error
|
||||
var currJam string
|
||||
if err = db.OpenDB(); err != nil {
|
||||
return nil
|
||||
}
|
||||
defer db.CloseDB()
|
||||
|
||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
||||
return nil
|
||||
}
|
||||
teamPath := []string{"jams", currJam, "teams"}
|
||||
teamPath := []string{"teams"}
|
||||
var teamUids []string
|
||||
if teamUids, err = db.GetBucketList(teamPath); err != nil {
|
||||
for _, v := range teamUids {
|
||||
@ -151,17 +124,24 @@ func dbGetTeamByName(nm string) *Team {
|
||||
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 {
|
||||
var err error
|
||||
var currJam string
|
||||
if err = db.OpenDB(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.CloseDB()
|
||||
|
||||
if currJam, err = dbGetCurrentJam(); err != nil {
|
||||
return err
|
||||
}
|
||||
teamPath := []string{"jams", currJam, "teams"}
|
||||
teamPath := []string{"teams"}
|
||||
return db.DeleteBucket(teamPath, id)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/pborman/uuid"
|
||||
)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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) {
|
||||
p.setStringValue("flash_message", msg)
|
||||
p.setStringValue("flash_status", status)
|
@ -7,14 +7,18 @@ import (
|
||||
|
||||
func initPublicPage(w http.ResponseWriter, req *http.Request) *pageData {
|
||||
p := InitPageData(w, req)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func handleMain(w http.ResponseWriter, req *http.Request) {
|
||||
page := initPublicPage(w, req)
|
||||
page.SubTitle = "!"
|
||||
page.SubTitle = ""
|
||||
|
||||
for _, tmpl := range []string{
|
||||
"htmlheader.html",
|
||||
"admin-menu.html",
|
||||
"header.html",
|
||||
"main.html",
|
||||
"footer.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>
|
||||
<div class="pure-control-group">
|
||||
<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>
|
||||
|
||||
<button type="submit" class="pure-button pure-button-primary">Add Team</button>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<fieldset>
|
||||
<div class="pure-control-group">
|
||||
<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 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">
|
||||
<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 class="pure-control-group reset-pull">
|
||||
|
@ -3,7 +3,7 @@
|
||||
<fieldset>
|
||||
<div class="pure-control-group">
|
||||
<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 class="pure-control-group">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div id="menu">
|
||||
<div id="menu" class="{{if .HideAdminMenu}}hidden{{end}}">
|
||||
<div class="pure-menu">
|
||||
<a class="pure-menu-heading" href="/admin/">Admin</a>
|
||||
<a href="#menu" class="menu-button">
|
||||
@ -12,6 +12,11 @@
|
||||
</li>
|
||||
{{ end }}
|
||||
</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">
|
||||
{{ range $k, $v := .BottomMenu }}
|
||||
<li class="pure-menu-item">
|
||||
|
@ -13,8 +13,8 @@
|
||||
<tr>
|
||||
<td>{{ $v.Name }}</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/users/{{ $v.UUID }}/delete" class="pure-button pure-button-plain"><i class="fa fa-trash"></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/teams/{{ $v.UUID }}/delete" class="pure-button pure-button-plain"><i class="fa fa-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
|
@ -1,9 +1,12 @@
|
||||
<script>
|
||||
var clientID = "{{.ClientID}}";
|
||||
</script>
|
||||
<div class="content">
|
||||
<aside class="flash center {{.FlashClass}}">
|
||||
{{.FlashMessage}}
|
||||
</aside>
|
||||
<div class="header">
|
||||
ICT GameJam 2017
|
||||
devICT Game Jam - {{.CurrentJam}}
|
||||
</div>
|
||||
<div class="header-menu">
|
||||
<h2>{{.SubTitle}}</h2>
|
||||
|
Loading…
Reference in New Issue
Block a user