feat: sqlite
This commit is contained in:
parent
cf3e84202b
commit
1de4893f8e
|
|
@ -1 +1,3 @@
|
||||||
|
.DS_Store
|
||||||
gin-bin
|
gin-bin
|
||||||
|
lishwist.db
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
"lishwist/db"
|
"lishwist/db"
|
||||||
"lishwist/env"
|
"lishwist/env"
|
||||||
"lishwist/types"
|
|
||||||
|
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
)
|
)
|
||||||
|
|
@ -27,16 +26,16 @@ func (auth *AuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (auth *AuthMiddleware) ExpectUser(r *http.Request) *types.UserData {
|
func (auth *AuthMiddleware) ExpectUser(r *http.Request) *db.User {
|
||||||
session, _ := auth.Store.Get(r, "lishwist_user")
|
session, _ := auth.Store.Get(r, "lishwist_user")
|
||||||
username, ok := session.Values["username"].(string)
|
username, ok := session.Values["username"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Fatalln("Failed to get username")
|
log.Fatalln("Failed to get username")
|
||||||
}
|
}
|
||||||
|
|
||||||
user := db.GetUser(username)
|
user, err := db.GetUser(username)
|
||||||
if user == nil {
|
if err != nil {
|
||||||
log.Fatalln("Failed to get user")
|
log.Fatalf("Failed to get user: %s\n", err)
|
||||||
}
|
}
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"lishwist/db"
|
"lishwist/db"
|
||||||
"lishwist/types"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -19,14 +18,20 @@ func (auth *AuthMiddleware) LoginPost(w http.ResponseWriter, r *http.Request) {
|
||||||
username := r.Form.Get("username")
|
username := r.Form.Get("username")
|
||||||
password := r.Form.Get("password")
|
password := r.Form.Get("password")
|
||||||
|
|
||||||
user, ok := db.Get("user:" + username).(types.UserData)
|
user, err := db.GetUser(username)
|
||||||
if !ok {
|
if err != nil {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(time.Second)
|
||||||
http.Error(w, "Username or password invalid", http.StatusUnauthorized)
|
http.Error(w, "Username or password invalid", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := bcrypt.CompareHashAndPassword(user.PassHash, []byte(password))
|
passHash, err := user.GetPassHash()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Something went wrong. Error code: Momo", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bcrypt.CompareHashAndPassword(passHash, []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Username or password invalid", http.StatusUnauthorized)
|
http.Error(w, "Username or password invalid", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"lishwist/db"
|
"lishwist/db"
|
||||||
"lishwist/types"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
@ -19,7 +18,8 @@ func (auth *AuthMiddleware) RegisterPost(w http.ResponseWriter, r *http.Request)
|
||||||
newPassword := r.Form.Get("newPassword")
|
newPassword := r.Form.Get("newPassword")
|
||||||
confirmPassword := r.Form.Get("confirmPassword")
|
confirmPassword := r.Form.Get("confirmPassword")
|
||||||
|
|
||||||
if db.Exists("user:" + username) {
|
existingUser, _ := db.GetUser(username)
|
||||||
|
if existingUser != nil {
|
||||||
http.Error(w, "Username is taken", http.StatusBadRequest)
|
http.Error(w, "Username is taken", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -35,10 +35,11 @@ func (auth *AuthMiddleware) RegisterPost(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
db.Set("user:"+username, types.UserData{
|
_, err = db.CreateUser(username, hashedPasswordBytes)
|
||||||
Username: username,
|
if err != nil {
|
||||||
PassHash: hashedPasswordBytes,
|
http.Error(w, "Something went wrong. Error code: Ozai", http.StatusInternalServerError)
|
||||||
})
|
return
|
||||||
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@ package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"lishwist/auth"
|
"lishwist/auth"
|
||||||
"lishwist/db"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Context struct {
|
type Context struct {
|
||||||
|
|
@ -17,12 +16,13 @@ func (ctx *Context) WishlistAdd(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
items := db.GetUserItems(user.Username)
|
newGiftName := r.Form.Get("gift_name")
|
||||||
newItem := r.Form.Get("item")
|
err := user.AddGift(newGiftName)
|
||||||
if newItem != "" {
|
if err != nil {
|
||||||
items = append(items, newItem)
|
log.Printf("Failed to add gift: %s\n", err)
|
||||||
|
http.Error(w, "Failed to add gift.", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
db.SetUserItems(user.Username, items)
|
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,18 +32,16 @@ func (ctx *Context) WishlistDelete(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
items := db.GetUserItems(user.Username)
|
target := r.Form.Get("gift_id")
|
||||||
target := r.Form.Get("item")
|
|
||||||
if target == "" {
|
if target == "" {
|
||||||
http.Error(w, "Item not provided"+target, http.StatusBadRequest)
|
http.Error(w, "Gift ID not provided"+target, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
idx := slices.Index(items, target)
|
err := user.RemoveGift(target)
|
||||||
if idx < 0 {
|
if err != nil {
|
||||||
http.Error(w, "Couldn't find item: "+target, http.StatusBadRequest)
|
log.Printf("Failed to remove gift: %s\n", err)
|
||||||
|
http.Error(w, "Failed to remove gift.", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
items = append(items[:idx], items[idx+1:]...)
|
|
||||||
db.SetUserItems(user.Username, items)
|
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,25 +3,37 @@ package context
|
||||||
import (
|
import (
|
||||||
"lishwist/db"
|
"lishwist/db"
|
||||||
"lishwist/templates"
|
"lishwist/templates"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ForeignWishlistProps struct {
|
type ForeignWishlistProps struct {
|
||||||
Username string
|
Username string
|
||||||
Items []string
|
Gifts []db.Gift
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) ViewForeignWishlist(w http.ResponseWriter, r *http.Request) {
|
func (ctx *Context) ViewForeignWishlist(w http.ResponseWriter, r *http.Request) {
|
||||||
otherUsername := r.PathValue("username")
|
otherUsername := r.PathValue("username")
|
||||||
user := ctx.Auth.ExpectUser(r)
|
user := ctx.Auth.ExpectUser(r)
|
||||||
if user.Username == otherUsername {
|
if user.Name == otherUsername {
|
||||||
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
http.Error(w, "You can't view your own list, silly ;)", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
items := db.GetUserItems(otherUsername)
|
otherUser, err := db.GetUser(otherUsername)
|
||||||
if items == nil {
|
if err != nil {
|
||||||
http.Error(w, "User not found", http.StatusNotFound)
|
log.Printf("An error occurred while fetching a user: %s\n", err)
|
||||||
|
http.Error(w, "An error occurred while fetching this user :(", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
p := ForeignWishlistProps{Username: otherUsername, Items: items}
|
if otherUser == nil {
|
||||||
|
http.Error(w, "User not found", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
gifts, err := otherUser.GetGifts()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "An error occurred while fetching this user's wishlist :(", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p := ForeignWishlistProps{Username: otherUsername, Gifts: gifts}
|
||||||
templates.Execute(w, "foreign_wishlist.gotmpl", p)
|
templates.Execute(w, "foreign_wishlist.gotmpl", p)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type HomeProps struct {
|
type HomeProps struct {
|
||||||
Items []string
|
Gifts []db.Gift
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) Home(w http.ResponseWriter, r *http.Request) {
|
func (ctx *Context) Home(w http.ResponseWriter, r *http.Request) {
|
||||||
user := ctx.Auth.ExpectUser(r)
|
user := ctx.Auth.ExpectUser(r)
|
||||||
items := db.GetUserItems(user.Username)
|
gifts, err := user.GetGifts()
|
||||||
p := HomeProps{Items: items}
|
if err != nil {
|
||||||
|
http.Error(w, "An error occurred while fetching your wishlist :(", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p := HomeProps{Gifts: gifts}
|
||||||
templates.Execute(w, "home.gotmpl", p)
|
templates.Execute(w, "home.gotmpl", p)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
49
db/db.go
49
db/db.go
|
|
@ -1,40 +1,31 @@
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"os"
|
||||||
|
|
||||||
var database map[string]any = map[string]any{}
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
func Add(key string, value any) error {
|
var database *sql.DB
|
||||||
_, existing := database[key]
|
|
||||||
if existing {
|
func Open() error {
|
||||||
return fmt.Errorf("A value already exists under '%s'", key)
|
db, err := sql.Open("sqlite3", "./lishwist.db")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
database[key] = value
|
database = db
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Set(key string, value any) {
|
func Init() error {
|
||||||
database[key] = value
|
initStmt, err := os.ReadFile("./db/init.sql")
|
||||||
}
|
if err != nil {
|
||||||
|
return err
|
||||||
func Get(key string) any {
|
|
||||||
value, existing := database[key]
|
|
||||||
if !existing {
|
|
||||||
return fmt.Errorf("No value under '%s'", key)
|
|
||||||
}
|
}
|
||||||
return value
|
_, err = database.Exec(string(initStmt))
|
||||||
}
|
if err != nil {
|
||||||
|
return err
|
||||||
func Remove(key string) any {
|
|
||||||
value, existing := database[key]
|
|
||||||
if !existing {
|
|
||||||
return fmt.Errorf("No value under '%s'", key)
|
|
||||||
}
|
}
|
||||||
delete(database, key)
|
return nil
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
func Exists(key string) bool {
|
|
||||||
_, existing := database[key]
|
|
||||||
return existing
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
CREATE TABLE IF NOT EXISTS "user" (
|
||||||
|
"id" INTEGER NOT NULL UNIQUE,
|
||||||
|
"name" TEXT NOT NULL UNIQUE,
|
||||||
|
"reference" TEXT NOT NULL UNIQUE,
|
||||||
|
"motto" TEXT NOT NULL,
|
||||||
|
"password_hash" TEXT NOT NULL,
|
||||||
|
PRIMARY KEY("id" AUTOINCREMENT)
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "gift" (
|
||||||
|
"id" INTEGER NOT NULL UNIQUE,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"recipient_id" INTEGER NOT NULL,
|
||||||
|
"claimant_id" INTEGER,
|
||||||
|
"creator_id" INTEGER NOT NULL,
|
||||||
|
"sent" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY("id" AUTOINCREMENT),
|
||||||
|
FOREIGN KEY("recipient_id") REFERENCES "user"("id"),
|
||||||
|
FOREIGN KEY("creator_id") REFERENCES "user"("id"),
|
||||||
|
FOREIGN KEY("claimant_id") REFERENCES "user"("id")
|
||||||
|
);
|
||||||
|
COMMIT;
|
||||||
122
db/user.go
122
db/user.go
|
|
@ -1,39 +1,113 @@
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"lishwist/types"
|
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetUser(username string) *types.UserData {
|
type User struct {
|
||||||
user, ok := Get("user:" + username).(types.UserData)
|
Id string
|
||||||
if !ok {
|
Name string
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &user
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserItems(username string) []string {
|
type Gift struct {
|
||||||
user := GetUser(username)
|
Id string
|
||||||
if user == nil {
|
Name string
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
items, ok := Get("user_items:" + user.Username).([]string)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return items
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetUserItems(username string, items []string) error {
|
func GetUser(username string) (*User, error) {
|
||||||
user := GetUser(username)
|
stmt := "SELECT user.id, user.name FROM user WHERE user.name = ?"
|
||||||
if user == nil {
|
var id string
|
||||||
return fmt.Errorf("Didn't find user")
|
var name string
|
||||||
|
err := database.QueryRow(stmt, username).Scan(&id, &name)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
user := User{
|
||||||
|
Id: id,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
return &user, nil
|
||||||
|
}
|
||||||
|
|
||||||
Set("user_items:"+user.Username, items)
|
func CreateUser(username string, passHash []byte) (*User, error) {
|
||||||
|
stmt := "INSERT INTO user (name, motto, reference, password_hash) VALUES (?, '', ?, ?)"
|
||||||
|
reference, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result, err := database.Exec(stmt, username, reference, passHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
id, err := result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user := User{
|
||||||
|
Id: fmt.Sprintf("%d", id),
|
||||||
|
Name: username,
|
||||||
|
}
|
||||||
|
return &user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) GetPassHash() ([]byte, error) {
|
||||||
|
stmt := "SELECT user.password_hash FROM user WHERE user.id = ?"
|
||||||
|
var passHash string
|
||||||
|
err := database.QueryRow(stmt, u.Id).Scan(&passHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []byte(passHash), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) GetGifts() ([]Gift, error) {
|
||||||
|
stmt := "SELECT gift.id, gift.name FROM gift JOIN user ON gift.recipient_id = user.id WHERE user.id = ?"
|
||||||
|
rows, err := database.Query(stmt, u.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
gifts := []Gift{}
|
||||||
|
for rows.Next() {
|
||||||
|
var id string
|
||||||
|
var name string
|
||||||
|
rows.Scan(&id, &name)
|
||||||
|
gift := Gift{
|
||||||
|
Id: id,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
gifts = append(gifts, gift)
|
||||||
|
}
|
||||||
|
err = rows.Err()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return gifts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) AddGift(name string) error {
|
||||||
|
stmt := "INSERT INTO gift (name, recipient_id, creator_id) VALUES (?, ?, ?)"
|
||||||
|
_, err := database.Exec(stmt, name, u.Id, u.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) RemoveGift(id string) error {
|
||||||
|
stmt := "DELETE FROM gift WHERE gift.creator_id = ? AND gift.id = ?"
|
||||||
|
result, err := database.Exec(stmt, u.Id, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
affected, _ := result.RowsAffected()
|
||||||
|
if affected == 0 {
|
||||||
|
return fmt.Errorf("No gift match.")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -3,7 +3,9 @@ module lishwist
|
||||||
go 1.22.0
|
go 1.22.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/sessions v1.2.2
|
github.com/gorilla/sessions v1.2.2
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22
|
||||||
golang.org/x/crypto v0.22.0
|
golang.org/x/crypto v0.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -1,8 +1,12 @@
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||||
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
|
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
|
||||||
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
|
|
|
||||||
11
main.go
11
main.go
|
|
@ -1,14 +1,25 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"lishwist/auth"
|
"lishwist/auth"
|
||||||
"lishwist/context"
|
"lishwist/context"
|
||||||
|
"lishwist/db"
|
||||||
"lishwist/templates"
|
"lishwist/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
err := db.Open()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to open DB: %s\n", err)
|
||||||
|
}
|
||||||
|
err = db.Init()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to init DB: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
publicMux := http.NewServeMux()
|
publicMux := http.NewServeMux()
|
||||||
protectedMux := http.NewServeMux()
|
protectedMux := http.NewServeMux()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
{{define "body"}}
|
{{define "body"}}
|
||||||
|
<h1>Lishwist</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
|
@ -6,11 +7,10 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<h1>Lishwist</h1>
|
|
||||||
<h2>{{.Username}}'s list</h2>
|
<h2>{{.Username}}'s list</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{{range .Items}}
|
{{range .Gifts}}
|
||||||
<li>{{.}}</li>
|
<li>{{.Name}}</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -5,17 +5,17 @@
|
||||||
<h1>Lishwist</h1>
|
<h1>Lishwist</h1>
|
||||||
<h2>Your list</h2>
|
<h2>Your list</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{{range .Items}}
|
{{range .Gifts}}
|
||||||
<li>{{.}}
|
<li>{{.Name}}
|
||||||
<form method="post" action="wishlist/delete">
|
<form method="post" action="wishlist/delete">
|
||||||
<input type="hidden" name="item" value="{{.}}">
|
<input type="hidden" name="gift_id" value="{{.Id}}">
|
||||||
<input type="submit" value="Delete">
|
<input type="submit" value="Delete">
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
<form method="post" action="/wishlist/add">
|
<form method="post" action="/wishlist/add">
|
||||||
<input name="item" required>
|
<input name="gift_name" required>
|
||||||
<input type="submit">
|
<input type="submit">
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package types
|
|
||||||
|
|
||||||
type UserData struct {
|
|
||||||
Username string
|
|
||||||
PassHash []byte
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue