Making Progress
This commit is contained in:
parent
3b9efffc3f
commit
abd7e803e9
@ -4,57 +4,13 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/gorilla/sessions"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initAdminRequest(w http.ResponseWriter, req *http.Request) *pageData {
|
func initAdminRequest(w http.ResponseWriter, req *http.Request) *pageData {
|
||||||
if site.DevMode {
|
p := InitPageData(w, req)
|
||||||
w.Header().Set("Cache-Control", "no-cache")
|
|
||||||
}
|
|
||||||
p := new(pageData)
|
|
||||||
// Get session
|
|
||||||
var err error
|
|
||||||
var s *sessions.Session
|
|
||||||
if s, err = sessionStore.Get(req, site.SessionName); err != nil {
|
|
||||||
http.Error(w, err.Error(), 500)
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
p.session = new(pageSession)
|
|
||||||
p.session.session = s
|
|
||||||
p.session.req = req
|
|
||||||
p.session.w = w
|
|
||||||
|
|
||||||
// First check if we're logged in
|
|
||||||
userEmail, _ := p.session.getStringValue("email")
|
|
||||||
|
|
||||||
// With a valid account
|
|
||||||
p.LoggedIn = dbIsValidUserEmail(userEmail)
|
|
||||||
p.Site = site
|
|
||||||
p.SubTitle = ""
|
|
||||||
p.Stylesheets = make([]string, 0, 0)
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/css/pure-min.css")
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/css/grids-responsive-min.css")
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/font-awesome/css/font-awesome.min.css")
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/css/gjvote.css")
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/css/admin.css")
|
p.Stylesheets = append(p.Stylesheets, "/assets/css/admin.css")
|
||||||
|
|
||||||
p.HeaderScripts = make([]string, 0, 0)
|
|
||||||
p.HeaderScripts = append(p.HeaderScripts, "/assets/js/snack-min.js")
|
|
||||||
p.Scripts = make([]string, 0, 0)
|
|
||||||
p.Scripts = append(p.Scripts, "/assets/js/admin.js")
|
p.Scripts = append(p.Scripts, "/assets/js/admin.js")
|
||||||
p.FlashMessage, p.FlashClass = p.session.getFlashMessage()
|
|
||||||
if p.FlashClass == "" {
|
|
||||||
p.FlashClass = "hidden"
|
|
||||||
}
|
|
||||||
// Build the menu
|
|
||||||
if p.LoggedIn {
|
|
||||||
p.Menu = append(p.Menu, menuItem{"Votes", "/admin/votes", "fa-sticky-note"})
|
|
||||||
p.Menu = append(p.Menu, menuItem{"Teams", "/admin/teams", "fa-users"})
|
|
||||||
p.Menu = append(p.Menu, menuItem{"Games", "/admin/games", "fa-gamepad"})
|
|
||||||
|
|
||||||
p.BottomMenu = append(p.BottomMenu, menuItem{"Users", "/admin/users", "fa-user"})
|
|
||||||
p.BottomMenu = append(p.BottomMenu, menuItem{"Logout", "/admin/dologout", "fa-sign-out"})
|
|
||||||
}
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +139,59 @@ func handleAdminUsers(w http.ResponseWriter, req *http.Request, page *pageData)
|
|||||||
|
|
||||||
// handleAdminTeams
|
// handleAdminTeams
|
||||||
func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData) {
|
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
|
// handleAdminGames
|
||||||
|
@ -1 +1,17 @@
|
|||||||
console.log('ICTGameJam Wahoo!');
|
function showAdminPanel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document.onkeydown = function(evt) {
|
||||||
|
evt = evt || window.event;
|
||||||
|
var isEscape = false;
|
||||||
|
if("key" in evt) {
|
||||||
|
isEscape = (evt.key == "Escape" || evt.key == "Esc");
|
||||||
|
} else {
|
||||||
|
isEscape = (evt.keyCode == 27);
|
||||||
|
}
|
||||||
|
if(isEscape) {
|
||||||
|
showAdminPanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
{"title":"ICT GameJam Voting","port":8080,"session":"ict-gamejam","dir":"./","devmode":true,"db":"gjvote.db"}
|
{"title":"ICT GameJam Voting","port":8080,"session":"ict-gamejam","dir":"./","devmode":true,"db":"gjvote.db","CurrentJam":""}
|
75
main.go
75
main.go
@ -30,6 +30,8 @@ type siteData struct {
|
|||||||
ServerDir string `json:"dir"`
|
ServerDir string `json:"dir"`
|
||||||
DevMode bool `json:"devmode"`
|
DevMode bool `json:"devmode"`
|
||||||
DB string `json:"db"`
|
DB string `json:"db"`
|
||||||
|
|
||||||
|
CurrentJam string
|
||||||
}
|
}
|
||||||
|
|
||||||
// pageData is stuff that changes per request
|
// pageData is stuff that changes per request
|
||||||
@ -47,6 +49,7 @@ type pageData struct {
|
|||||||
Menu []menuItem
|
Menu []menuItem
|
||||||
BottomMenu []menuItem
|
BottomMenu []menuItem
|
||||||
session *pageSession
|
session *pageSession
|
||||||
|
CurrentJam string
|
||||||
|
|
||||||
TemplateData interface{}
|
TemplateData interface{}
|
||||||
}
|
}
|
||||||
@ -124,7 +127,7 @@ func saveConfig() {
|
|||||||
|
|
||||||
func initialize() {
|
func initialize() {
|
||||||
// Check if the database has been created
|
// Check if the database has been created
|
||||||
assertError(openDatabase())
|
assertError(initDatabase())
|
||||||
|
|
||||||
if !dbHasUser() {
|
if !dbHasUser() {
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
@ -146,12 +149,82 @@ func initialize() {
|
|||||||
}
|
}
|
||||||
assertError(dbUpdateUserPassword(email, string(pw1)))
|
assertError(dbUpdateUserPassword(email, string(pw1)))
|
||||||
}
|
}
|
||||||
|
if !dbHasCurrentJam() {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
fmt.Println("Create New Game Jam")
|
||||||
|
fmt.Print("GameJam Name: ")
|
||||||
|
gjName, _ := reader.ReadString('\n')
|
||||||
|
gjName = strings.TrimSpace(gjName)
|
||||||
|
if dbSetCurrentJam(gjName) != nil {
|
||||||
|
fmt.Println("Error saving Current Jam")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loggingHandler(h http.Handler) http.Handler {
|
func loggingHandler(h http.Handler) http.Handler {
|
||||||
return handlers.LoggingHandler(os.Stdout, h)
|
return handlers.LoggingHandler(os.Stdout, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InitPageData(w http.ResponseWriter, req *http.Request) *pageData {
|
||||||
|
if site.DevMode {
|
||||||
|
w.Header().Set("Cache-Control", "no-cache")
|
||||||
|
}
|
||||||
|
p := new(pageData)
|
||||||
|
// Get session
|
||||||
|
var err error
|
||||||
|
var s *sessions.Session
|
||||||
|
if s, err = sessionStore.Get(req, site.SessionName); err != nil {
|
||||||
|
http.Error(w, err.Error(), 500)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
p.session = new(pageSession)
|
||||||
|
p.session.session = s
|
||||||
|
p.session.req = req
|
||||||
|
p.session.w = w
|
||||||
|
|
||||||
|
// First check if we're logged in
|
||||||
|
userEmail, _ := p.session.getStringValue("email")
|
||||||
|
// With a valid account
|
||||||
|
p.LoggedIn = dbIsValidUserEmail(userEmail)
|
||||||
|
|
||||||
|
p.Site = site
|
||||||
|
p.SubTitle = "GameJam Voting"
|
||||||
|
p.Stylesheets = make([]string, 0, 0)
|
||||||
|
p.Stylesheets = append(p.Stylesheets, "/assets/css/pure-min.css")
|
||||||
|
p.Stylesheets = append(p.Stylesheets, "/assets/css/grids-responsive-min.css")
|
||||||
|
p.Stylesheets = append(p.Stylesheets, "/assets/font-awesome/css/font-awesome.min.css")
|
||||||
|
p.Stylesheets = append(p.Stylesheets, "/assets/css/gjvote.css")
|
||||||
|
|
||||||
|
p.HeaderScripts = make([]string, 0, 0)
|
||||||
|
p.HeaderScripts = append(p.HeaderScripts, "/assets/js/snack-min.js")
|
||||||
|
|
||||||
|
p.Scripts = make([]string, 0, 0)
|
||||||
|
p.Scripts = append(p.Scripts, "/assets/js/gjvote.js")
|
||||||
|
|
||||||
|
p.FlashMessage, p.FlashClass = p.session.getFlashMessage()
|
||||||
|
if p.FlashClass == "" {
|
||||||
|
p.FlashClass = "hidden"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the menu
|
||||||
|
if p.LoggedIn {
|
||||||
|
p.Menu = append(p.Menu, menuItem{"Admin", "/admin", "fa-key"})
|
||||||
|
p.Menu = append(p.Menu, menuItem{"Votes", "/admin/votes", "fa-sticky-note"})
|
||||||
|
p.Menu = append(p.Menu, menuItem{"Teams", "/admin/teams", "fa-users"})
|
||||||
|
p.Menu = append(p.Menu, menuItem{"Games", "/admin/games", "fa-gamepad"})
|
||||||
|
|
||||||
|
p.BottomMenu = append(p.BottomMenu, menuItem{"Users", "/admin/users", "fa-user"})
|
||||||
|
p.BottomMenu = append(p.BottomMenu, menuItem{"Logout", "/admin/dologout", "fa-sign-out"})
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.CurrentJam, err = dbGetCurrentJam(); err != nil {
|
||||||
|
p.FlashMessage = "Error Loading Current GameJam: " + err.Error()
|
||||||
|
p.FlashClass = "error"
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
func (p *pageData) show(tmplName string, w http.ResponseWriter) error {
|
func (p *pageData) show(tmplName string, w http.ResponseWriter) error {
|
||||||
for _, tmpl := range []string{
|
for _, tmpl := range []string{
|
||||||
"htmlheader.html",
|
"htmlheader.html",
|
||||||
|
109
model.go
109
model.go
@ -1,11 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "github.com/br0xen/boltease"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/br0xen/boltease"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var db *boltease.DB
|
var db *boltease.DB
|
||||||
var dbOpened bool
|
var dbOpened bool
|
||||||
@ -24,83 +19,73 @@ func openDatabase() error {
|
|||||||
|
|
||||||
func initDatabase() error {
|
func initDatabase() error {
|
||||||
openDatabase()
|
openDatabase()
|
||||||
db.MkBucketPath([]string{"users"})
|
// Create the path to the bucket to store admin users
|
||||||
db.MkBucketPath([]string{"teams"})
|
if err := db.MkBucketPath([]string{"users"}); err != nil {
|
||||||
return nil
|
return err
|
||||||
|
}
|
||||||
|
// Create the path to the bucket to store jam informations
|
||||||
|
if err := db.MkBucketPath([]string{"jams"}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Create the path to the bucket to store site config data
|
||||||
|
return db.MkBucketPath([]string{"site"})
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbHasUser
|
func dbSetCurrentJam(name string) error {
|
||||||
// Returns true if there are any users in the database
|
|
||||||
func dbHasUser() bool {
|
|
||||||
return len(dbGetAllUsers()) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func dbGetAllUsers() []string {
|
|
||||||
if err := db.OpenDB(); err != nil {
|
if err := db.OpenDB(); err != nil {
|
||||||
return []string{}
|
return err
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
usrs, err := db.GetBucketList([]string{"users"})
|
return db.SetValue([]string{"site"}, "current-jam", name)
|
||||||
if err != nil {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return usrs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbIsValidUserEmail(email string) bool {
|
func dbHasCurrentJam() bool {
|
||||||
if err := db.OpenDB(); err != nil {
|
var nm string
|
||||||
|
var err error
|
||||||
|
if nm, err = dbGetCurrentJam(); err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
ret, err := dbIsValidJam(nm)
|
||||||
|
return ret && err != nil
|
||||||
usrPath := []string{"users", email}
|
|
||||||
if _, err := db.GetValue(usrPath, "password"); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbCheckCredentials(email, pw string) error {
|
func dbGetCurrentJam() (string, error) {
|
||||||
var err error
|
|
||||||
if err = db.OpenDB(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer db.CloseDB()
|
|
||||||
|
|
||||||
var uPw string
|
|
||||||
usrPath := []string{"users", email}
|
|
||||||
if uPw, err = db.GetValue(usrPath, "password"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return bcrypt.CompareHashAndPassword([]byte(uPw), []byte(pw))
|
|
||||||
}
|
|
||||||
|
|
||||||
// dbUpdateUserPassword
|
|
||||||
// Takes an email address and a password
|
|
||||||
// Creates the user if it doesn't exist, encrypts the password
|
|
||||||
// and updates it in the db
|
|
||||||
func dbUpdateUserPassword(email, password string) error {
|
|
||||||
cryptPw, cryptError := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
||||||
if cryptError != nil {
|
|
||||||
return cryptError
|
|
||||||
}
|
|
||||||
if err := db.OpenDB(); err != nil {
|
if err := db.OpenDB(); err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
usrPath := []string{"users", email}
|
return db.GetValue([]string{"site"}, "current-jam")
|
||||||
return db.SetValue(usrPath, "password", string(cryptPw))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbDeleteUser(email string) error {
|
func dbIsValidJam(name string) (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
fmt.Println("Deleting User:", email)
|
|
||||||
if err = db.OpenDB(); err != nil {
|
if err = db.OpenDB(); err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
defer db.CloseDB()
|
defer db.CloseDB()
|
||||||
|
|
||||||
return db.DeleteBucket([]string{"users"}, email)
|
// 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
|
||||||
}
|
}
|
||||||
|
8
model_games.go
Normal file
8
model_games.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/pborman/uuid"
|
||||||
|
|
||||||
|
type Game struct {
|
||||||
|
UUID *uuid.UUID
|
||||||
|
Name string
|
||||||
|
}
|
167
model_teams.go
Normal file
167
model_teams.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pborman/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Team struct {
|
||||||
|
UUID string
|
||||||
|
Name string
|
||||||
|
Members []TeamMember
|
||||||
|
Game *Game
|
||||||
|
}
|
||||||
|
|
||||||
|
type TeamMember struct {
|
||||||
|
UUID string
|
||||||
|
Name string
|
||||||
|
SlackId string
|
||||||
|
Twitter string
|
||||||
|
Email string
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbCreateNewTeam(nm string) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
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}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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"}
|
||||||
|
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 {
|
||||||
|
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 {
|
||||||
|
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}
|
||||||
|
tm := new(Team)
|
||||||
|
if tm.Name, err = db.GetValue(teamPath, "name"); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return tm
|
||||||
|
}
|
||||||
|
|
||||||
|
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"}
|
||||||
|
var teamUids []string
|
||||||
|
if teamUids, err = db.GetBucketList(teamPath); err != nil {
|
||||||
|
for _, v := range teamUids {
|
||||||
|
var name string
|
||||||
|
if name, err = db.GetValue(append(teamPath, v), "name"); name == nm {
|
||||||
|
return dbGetTeam(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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"}
|
||||||
|
return db.DeleteBucket(teamPath, id)
|
||||||
|
}
|
76
model_users.go
Normal file
76
model_users.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
// dbHasUser
|
||||||
|
// Returns true if there are any users in the database
|
||||||
|
func dbHasUser() bool {
|
||||||
|
return len(dbGetAllUsers()) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbGetAllUsers() []string {
|
||||||
|
if err := db.OpenDB(); err != nil {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
usrs, err := db.GetBucketList([]string{"users"})
|
||||||
|
if err != nil {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
return usrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbIsValidUserEmail(email string) bool {
|
||||||
|
if err := db.OpenDB(); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
usrPath := []string{"users", email}
|
||||||
|
_, err := db.GetValue(usrPath, "password")
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbCheckCredentials(email, pw string) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
var uPw string
|
||||||
|
usrPath := []string{"users", email}
|
||||||
|
if uPw, err = db.GetValue(usrPath, "password"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return bcrypt.CompareHashAndPassword([]byte(uPw), []byte(pw))
|
||||||
|
}
|
||||||
|
|
||||||
|
// dbUpdateUserPassword
|
||||||
|
// Takes an email address and a password
|
||||||
|
// Creates the user if it doesn't exist, encrypts the password
|
||||||
|
// and updates it in the db
|
||||||
|
func dbUpdateUserPassword(email, password string) error {
|
||||||
|
cryptPw, cryptError := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
|
if cryptError != nil {
|
||||||
|
return cryptError
|
||||||
|
}
|
||||||
|
if err := db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
usrPath := []string{"users", email}
|
||||||
|
return db.SetValue(usrPath, "password", string(cryptPw))
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbDeleteUser(email string) error {
|
||||||
|
var err error
|
||||||
|
if err = db.OpenDB(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.CloseDB()
|
||||||
|
|
||||||
|
return db.DeleteBucket([]string{"users"}, email)
|
||||||
|
}
|
@ -3,41 +3,16 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/sessions"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initPublicPage(w http.ResponseWriter, req *http.Request) *pageData {
|
func initPublicPage(w http.ResponseWriter, req *http.Request) *pageData {
|
||||||
p := new(pageData)
|
p := InitPageData(w, req)
|
||||||
// Get session
|
|
||||||
var err error
|
|
||||||
var s *sessions.Session
|
|
||||||
if s, err = sessionStore.Get(req, site.SessionName); err != nil {
|
|
||||||
http.Error(w, err.Error(), 500)
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
p.session = new(pageSession)
|
|
||||||
p.session.session = s
|
|
||||||
p.session.req = req
|
|
||||||
p.session.w = w
|
|
||||||
|
|
||||||
p.Site = site
|
|
||||||
p.SubTitle = "GameJam Voting"
|
|
||||||
p.Stylesheets = make([]string, 0, 0)
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/css/pure-min.css")
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/font-awesome/css/font-awesome.min.css")
|
|
||||||
p.Stylesheets = append(p.Stylesheets, "/assets/css/gjvote.css")
|
|
||||||
p.HeaderScripts = make([]string, 0, 0)
|
|
||||||
p.HeaderScripts = append(p.HeaderScripts, "/assets/js/snack-min.js")
|
|
||||||
p.Scripts = make([]string, 0, 0)
|
|
||||||
p.Scripts = append(p.Scripts, "/assets/js/gjvote.js")
|
|
||||||
p.FlashMessage, p.FlashClass = p.session.getFlashMessage()
|
|
||||||
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 = "Place your Vote!"
|
page.SubTitle = "!"
|
||||||
for _, tmpl := range []string{
|
for _, tmpl := range []string{
|
||||||
"htmlheader.html",
|
"htmlheader.html",
|
||||||
"main.html",
|
"main.html",
|
||||||
|
12
templates/admin-addteam.html
Normal file
12
templates/admin-addteam.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<div class="center">
|
||||||
|
<form class="pure-form pure-form-aligned" action="/admin/teams/new/save" method="POST">
|
||||||
|
<fieldset>
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label for="teamname">Team Name</label>
|
||||||
|
<input id="teamname" name="teamname" type="text" placeholder="Team Name" value="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="pure-button pure-button-primary">Add Team</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
42
templates/admin-editteam.html
Normal file
42
templates/admin-editteam.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<div class="center">
|
||||||
|
<form class="pure-form pure-form-aligned" action="/admin/teams/{{ .TemplateData.UUID }}/save" method="POST">
|
||||||
|
<fieldset>
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<span>{{ .TemplateData.Name }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label class="control-label" for="teamname">Team Name</label>
|
||||||
|
<input id="teamname" name="teamname" type="password" placeholder="Team Name">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pure-control-group reset-pull">
|
||||||
|
<a href="/admin/teams" class="pull-left space pure-button pure-button-plain">Cancel</a>
|
||||||
|
<button type="submit" class="pull-right space pure-button pure-button-primary">Update</button>
|
||||||
|
<button type="button" id="btnDeleteUser" class="pull-right space pure-button pure-button-error">Delete</button>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
snack.listener(
|
||||||
|
{node:document.getElementById('btnDeleteTeam'),event:'click'},
|
||||||
|
function() {
|
||||||
|
showModal({
|
||||||
|
title: 'Delete Team',
|
||||||
|
subtitle: '({{ .TemplateData.Name }} - {{ .TemplateData.UUID }})',
|
||||||
|
body: 'Are you sure? This cannot be undone.',
|
||||||
|
buttons: [{
|
||||||
|
title:'Cancel',
|
||||||
|
position:'left',
|
||||||
|
click: hideModal
|
||||||
|
},{
|
||||||
|
title:'Delete',
|
||||||
|
position:'right',
|
||||||
|
class: 'pure-button-error',
|
||||||
|
href: '/admin/teams/{{ .TemplateData.UUID }}/delete'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
31
templates/admin-teams.html
Normal file
31
templates/admin-teams.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<div class="bottom-space center">
|
||||||
|
<a id="btnAddTeam" class="pure-button pure-button-success" href="/admin/teams/new"><i class="fa fa-plus"></i> Add Team</a>
|
||||||
|
</div>
|
||||||
|
<table id="teams-table" class="hidden sortable pure-table pure-table-bordered center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range $i, $v := .TemplateData.Teams }}
|
||||||
|
<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>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<script>
|
||||||
|
snack.ready(function() {
|
||||||
|
var tableBody = document.querySelector("#teams-table>tbody");
|
||||||
|
if(tableBody.children.length>0) {
|
||||||
|
// Show the table
|
||||||
|
document.getElementById('teams-table').classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user