From dcba801dde09b077b169a95dd1f4b8179a18e719 Mon Sep 17 00:00:00 2001
From: Teajey <21069848+Teajey@users.noreply.github.com>
Date: Fri, 22 Nov 2024 10:38:53 +0900
Subject: [PATCH] feat: user deletion and get user as json
---
server/db/group.go | 2 +-
server/db/init.sql | 14 ++++++-
server/db/migration/1.sql | 22 ++++++++++
server/db/user.go | 62 +++++++++++++++++------------
server/main.go | 2 +
server/routing/error.go | 2 +-
server/routing/foreign_wishlist.go | 8 ++--
server/routing/groups.go | 16 ++++----
server/routing/home.go | 18 ++++-----
server/routing/todo.go | 7 ++--
server/routing/users.go | 64 +++++++++++++++++++++++++++++-
server/routing/wishlist.go | 18 ++++-----
server/templates/home.gotmpl | 2 +-
13 files changed, 173 insertions(+), 64 deletions(-)
create mode 100644 server/db/migration/1.sql
diff --git a/server/db/group.go b/server/db/group.go
index a9c72a0..951a526 100644
--- a/server/db/group.go
+++ b/server/db/group.go
@@ -66,7 +66,7 @@ func queryForGroups(query string, args ...any) ([]Group, error) {
}
func queryForGroupMembers(groupId string) ([]User, error) {
- query := "SELECT user.id, user.name, user.reference, user.is_admin FROM user JOIN group_member ON group_member.user_id = user.id JOIN [group] ON [group].id = group_member.group_id WHERE [group].id = ? ORDER BY group_member.user_id"
+ query := "SELECT user.id, user.name, user.reference, user.is_admin, user.is_live FROM v_user AS user JOIN group_member ON group_member.user_id = user.id JOIN [group] ON [group].id = group_member.group_id WHERE [group].id = ? ORDER BY group_member.user_id"
members, err := queryForUsers(query, groupId)
if err != nil {
return members, fmt.Errorf("Failed to get members: %w", err)
diff --git a/server/db/init.sql b/server/db/init.sql
index 1d69a55..5f1aeff 100644
--- a/server/db/init.sql
+++ b/server/db/init.sql
@@ -3,9 +3,10 @@ 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,
+ "motto" TEXT NOT NULL DEFAULT "",
"password_hash" TEXT NOT NULL,
"is_admin" INTEGER NOT NULL DEFAULT 0,
+ "is_live" INTEGER NOT NULL DEFAULT 1,
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "gift" (
@@ -38,4 +39,15 @@ CREATE TABLE IF NOT EXISTS "session" (
"value" TEXT NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT)
);
+
+DROP VIEW IF EXISTS "v_user";
+CREATE VIEW "v_user"
+AS
+SELECT * FROM user WHERE user.is_live = 1;
+
+-- DROP VIEW IF EXISTS "v_wish";
+-- CREATE VIEW "v_wish"
+-- AS
+-- SELECT gift.id, gift.name, gift.sent FROM gift JOIN user AS recipient;
+
COMMIT;
diff --git a/server/db/migration/1.sql b/server/db/migration/1.sql
new file mode 100644
index 0000000..c286b74
--- /dev/null
+++ b/server/db/migration/1.sql
@@ -0,0 +1,22 @@
+BEGIN TRANSACTION;
+
+ALTER TABLE user ADD COLUMN "is_live" INTEGER NOT NULL DEFAULT 1;
+
+ALTER TABLE user RENAME TO old_user;
+
+CREATE TABLE "user" (
+ "id" INTEGER NOT NULL UNIQUE,
+ "name" TEXT NOT NULL UNIQUE,
+ "reference" TEXT NOT NULL UNIQUE,
+ "motto" TEXT NOT NULL DEFAULT "",
+ "password_hash" TEXT NOT NULL,
+ "is_admin" INTEGER NOT NULL DEFAULT 0,
+ "is_live" INTEGER NOT NULL DEFAULT 1,
+ PRIMARY KEY("id" AUTOINCREMENT)
+);
+
+INSERT INTO user SELECT * FROM old_user;
+
+DROP TABLE "old_user";
+
+COMMIT;
diff --git a/server/db/user.go b/server/db/user.go
index f6e2141..daca2f6 100644
--- a/server/db/user.go
+++ b/server/db/user.go
@@ -12,6 +12,7 @@ type User struct {
Name string
Reference string
IsAdmin bool
+ IsLive bool
}
type Gift struct {
@@ -29,7 +30,7 @@ type Gift struct {
func queryForUser(query string, args ...any) (*User, error) {
var u User
- err := database.QueryRow(query, args...).Scan(&u.Id, &u.Name, &u.Reference, &u.IsAdmin)
+ err := database.QueryRow(query, args...).Scan(&u.Id, &u.Name, &u.Reference, &u.IsAdmin, &u.IsLive)
if err == sql.ErrNoRows {
return nil, nil
} else if err != nil {
@@ -47,7 +48,7 @@ func queryForUsers(query string, args ...any) ([]User, error) {
users := []User{}
for rows.Next() {
var u User
- err = rows.Scan(&u.Id, &u.Name, &u.Reference, &u.IsAdmin)
+ err = rows.Scan(&u.Id, &u.Name, &u.Reference, &u.IsAdmin, &u.IsLive)
if err != nil {
return nil, err
}
@@ -61,27 +62,42 @@ func queryForUsers(query string, args ...any) ([]User, error) {
}
func GetAllUsers() ([]User, error) {
- stmt := "SELECT user.id, user.name, user.reference, user.is_admin FROM user"
+ stmt := "SELECT id, name, reference, is_admin, is_live FROM user"
return queryForUsers(stmt)
}
func GetUser(id string) (*User, error) {
- stmt := "SELECT user.id, user.name, user.reference, user.is_admin FROM user WHERE user.id = ?"
+ stmt := "SELECT id, name, reference, is_admin, is_live FROM v_user WHERE id = ?"
return queryForUser(stmt, id)
}
func GetUserByName(username string) (*User, error) {
- stmt := "SELECT user.id, user.name, user.reference, user.is_admin FROM user WHERE user.name = ?"
+ stmt := "SELECT id, name, reference, is_admin, is_live FROM v_user WHERE name = ?"
return queryForUser(stmt, username)
}
func GetUserByReference(reference string) (*User, error) {
- stmt := "SELECT user.id, user.name, user.reference, user.is_admin FROM user WHERE user.reference = ?"
+ stmt := "SELECT id, name, reference, is_admin, is_live FROM v_user WHERE reference = ?"
return queryForUser(stmt, reference)
}
+func GetAnyUserByReference(reference string) (*User, error) {
+ stmt := "SELECT id, name, reference, is_admin, is_live FROM user WHERE reference = ?"
+ return queryForUser(stmt, reference)
+}
+
+func (u *User) SetLive(setting bool) error {
+ query := "UPDATE user SET is_live = ? WHERE reference = ?"
+ _, err := database.Exec(query, setting, u.Reference)
+ if err != nil {
+ return err
+ }
+ u.IsLive = setting
+ return err
+}
+
func CreateUser(username string, passHash []byte) (*User, error) {
- stmt := "INSERT INTO user (name, motto, reference, password_hash) VALUES (?, '', ?, ?)"
+ stmt := "INSERT INTO user (name, reference, password_hash) VALUES (?, ?, ?)"
reference, err := uuid.NewRandom()
if err != nil {
return nil, err
@@ -102,7 +118,7 @@ func CreateUser(username string, passHash []byte) (*User, error) {
}
func (u *User) GetPassHash() ([]byte, error) {
- stmt := "SELECT user.password_hash FROM user WHERE user.id = ?"
+ stmt := "SELECT password_hash FROM v_user WHERE id = ?"
var passHash string
err := database.QueryRow(stmt, u.Id).Scan(&passHash)
if err != nil {
@@ -112,7 +128,7 @@ func (u *User) GetPassHash() ([]byte, error) {
}
func (u *User) CountGifts() (int, error) {
- stmt := "SELECT COUNT(gift.id) AS gift_count FROM gift JOIN user ON gift.recipient_id = user.id LEFT JOIN user AS claimant ON gift.claimant_id = claimant.id WHERE gift.creator_id = user.id AND user.id = ?"
+ stmt := "SELECT COUNT(gift.id) AS gift_count FROM gift WHERE gift.creator_id = ?1 AND gift.recipient_id = ?1"
var giftCount int
err := database.QueryRow(stmt, u.Id).Scan(&giftCount)
if err != nil {
@@ -122,7 +138,7 @@ func (u *User) CountGifts() (int, error) {
}
func (u *User) GetGifts() ([]Gift, error) {
- stmt := "SELECT gift.id, gift.name, claimant.id, claimant.name, gift.sent FROM gift JOIN user ON gift.recipient_id = user.id LEFT JOIN user AS claimant ON gift.claimant_id = claimant.id WHERE gift.creator_id = user.id AND user.id = ?"
+ stmt := "SELECT gift.id, gift.name, gift.sent FROM gift WHERE gift.creator_id = ?1 AND gift.recipient_id = ?1"
rows, err := database.Query(stmt, u.Id)
if err != nil {
return nil, err
@@ -132,19 +148,15 @@ func (u *User) GetGifts() ([]Gift, error) {
for rows.Next() {
var id string
var name string
- var claimantId sql.NullString
- var claimantName sql.NullString
var sent bool
- err = rows.Scan(&id, &name, &claimantId, &claimantName, &sent)
+ err = rows.Scan(&id, &name, &sent)
if err != nil {
return nil, err
}
gift := Gift{
- Id: id,
- Name: name,
- ClaimantId: claimantId.String,
- ClaimantName: claimantName.String,
- Sent: sent,
+ Id: id,
+ Name: name,
+ Sent: sent,
}
gifts = append(gifts, gift)
}
@@ -158,15 +170,15 @@ func (u *User) GetGifts() ([]Gift, error) {
func (u *User) GetOtherUserGifts(otherUserReference string) ([]Gift, error) {
otherUser, err := GetUserByReference(otherUserReference)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("Failed to get other user: %w", err)
}
if otherUser.Id == u.Id {
return nil, fmt.Errorf("Not allowed to view own foreign wishlist")
}
- stmt := "SELECT gift.id, gift.name, claimant.id, claimant.name, gift.sent, gift.creator_id, creator.name, gift.recipient_id FROM gift JOIN user ON gift.recipient_id = user.id LEFT JOIN user AS claimant ON gift.claimant_id = claimant.id LEFT JOIN user AS creator ON gift.creator_id = creator.id WHERE user.id = ?"
+ stmt := "SELECT gift.id, gift.name, claimant.id, claimant.name, gift.sent, gift.creator_id, creator.name, gift.recipient_id FROM gift JOIN v_user AS user ON gift.recipient_id = user.id LEFT JOIN v_user AS claimant ON gift.claimant_id = claimant.id LEFT JOIN v_user AS creator ON gift.creator_id = creator.id WHERE user.id = ?"
rows, err := database.Query(stmt, otherUser.Id)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("Failed to execute query: %w", err)
}
defer rows.Close()
gifts := []Gift{}
@@ -181,7 +193,7 @@ func (u *User) GetOtherUserGifts(otherUserReference string) ([]Gift, error) {
var recipientId string
err = rows.Scan(&id, &name, &claimantId, &claimantName, &sent, &creatorId, &creatorName, &recipientId)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("Failed to scan row: %w", err)
}
gift := Gift{
Id: id,
@@ -197,13 +209,13 @@ func (u *User) GetOtherUserGifts(otherUserReference string) ([]Gift, error) {
}
err = rows.Err()
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("Rows returned an error: %w", err)
}
return gifts, nil
}
func (u *User) GetTodo() ([]Gift, error) {
- stmt := "SELECT gift.id, gift.name, gift.sent, recipient.name, recipient.reference FROM gift JOIN user ON gift.claimant_id = user.id JOIN user AS recipient ON gift.recipient_id = recipient.id WHERE user.id = ? ORDER BY gift.sent ASC, gift.name"
+ stmt := "SELECT gift.id, gift.name, gift.sent, recipient.name, recipient.reference FROM gift JOIN v_user AS user ON gift.claimant_id = user.id JOIN v_user AS recipient ON gift.recipient_id = recipient.id WHERE user.id = ? ORDER BY gift.sent ASC, gift.name"
rows, err := database.Query(stmt, u.Id)
if err != nil {
return nil, err
@@ -393,7 +405,7 @@ func (u *User) AddGiftToUser(otherUserReference string, giftName string) error {
}
func (u *User) GetGroups() ([]Group, error) {
- stmt := "SELECT [group].id, [group].name, [group].reference FROM [group] JOIN group_member ON group_member.group_id = [group].id JOIN user ON user.id = group_member.user_id WHERE user.id = ?"
+ stmt := "SELECT [group].id, [group].name, [group].reference FROM [group] JOIN group_member ON group_member.group_id = [group].id JOIN v_user AS user ON user.id = group_member.user_id WHERE user.id = ?"
rows, err := database.Query(stmt, u.Id)
if err != nil {
return nil, err
diff --git a/server/main.go b/server/main.go
index fd76a05..20ee877 100644
--- a/server/main.go
+++ b/server/main.go
@@ -55,6 +55,8 @@ func main() {
r.Json.Public.HandleFunc("GET /", routing.NotFoundJson)
r.Json.Private.Handle("GET /users", route.ExpectUser(route.UsersJson))
+ r.Json.Private.Handle("GET /users/{userReference}", route.ExpectUser(route.User))
+ r.Json.Private.Handle("POST /users/{userReference}", route.ExpectUser(route.UserPost))
r.Json.Private.Handle("GET /groups", route.ExpectUser(route.GroupsJson))
r.Json.Private.Handle("POST /groups/{groupReference}", route.ExpectUser(route.GroupPost))
r.Json.Private.Handle("GET /groups/{groupReference}", route.ExpectUser(route.Group))
diff --git a/server/routing/error.go b/server/routing/error.go
index cc0235e..91fa5d0 100644
--- a/server/routing/error.go
+++ b/server/routing/error.go
@@ -10,8 +10,8 @@ import (
func writeGeneralErrorJson(w http.ResponseWriter, status int, format string, a ...any) {
msg := fmt.Sprintf(format, a...)
log.Printf("General error: %s\n", msg)
+ w.Header().Add("Content-Type", "application/json")
w.WriteHeader(status)
escapedMsg := strings.ReplaceAll(msg, `"`, `\"`)
_, _ = w.Write([]byte(fmt.Sprintf(`{"GeneralError":"%s"}`, escapedMsg)))
- w.Header().Add("Content-Type", "application/json")
}
diff --git a/server/routing/foreign_wishlist.go b/server/routing/foreign_wishlist.go
index b552b4e..21ee556 100644
--- a/server/routing/foreign_wishlist.go
+++ b/server/routing/foreign_wishlist.go
@@ -14,9 +14,9 @@ type foreignWishlistProps struct {
Gifts []db.Gift
}
-func (ctx *Context) ForeignWishlist(user *db.User, w http.ResponseWriter, r *http.Request) {
+func (ctx *Context) ForeignWishlist(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
userReference := r.PathValue("userReference")
- if user.Reference == userReference {
+ if currentUser.Reference == userReference {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
@@ -29,12 +29,12 @@ func (ctx *Context) ForeignWishlist(user *db.User, w http.ResponseWriter, r *htt
error.Page(w, "User not found", http.StatusNotFound, err)
return
}
- gifts, err := user.GetOtherUserGifts(userReference)
+ gifts, err := currentUser.GetOtherUserGifts(userReference)
if err != nil {
error.Page(w, "An error occurred while fetching this user's wishlist :(", http.StatusInternalServerError, err)
return
}
- p := foreignWishlistProps{CurrentUserId: user.Id, CurrentUserName: user.Name, Username: otherUser.Name, Gifts: gifts}
+ p := foreignWishlistProps{CurrentUserId: currentUser.Id, CurrentUserName: currentUser.Name, Username: otherUser.Name, Gifts: gifts}
templates.Execute(w, "foreign_wishlist.gotmpl", p)
}
diff --git a/server/routing/groups.go b/server/routing/groups.go
index 75c60af..5db3cc4 100644
--- a/server/routing/groups.go
+++ b/server/routing/groups.go
@@ -15,9 +15,9 @@ type GroupProps struct {
CurrentUsername string
}
-func (ctx *Context) GroupPage(user *db.User, w http.ResponseWriter, r *http.Request) {
+func (ctx *Context) GroupPage(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
groupReference := r.PathValue("groupReference")
- group, err := user.GetGroupByReference(groupReference)
+ group, err := currentUser.GetGroupByReference(groupReference)
if err != nil {
error.Page(w, "An error occurred while fetching this group :(", http.StatusInternalServerError, err)
return
@@ -26,11 +26,11 @@ func (ctx *Context) GroupPage(user *db.User, w http.ResponseWriter, r *http.Requ
error.Page(w, "Group not found. (It might be because you're not a member)", http.StatusNotFound, nil)
return
}
- index := group.MemberIndex(user.Id)
+ index := group.MemberIndex(currentUser.Id)
group.Members = slices.Delete(group.Members, index, index+1)
p := GroupProps{
Group: group,
- CurrentUsername: user.Name,
+ CurrentUsername: currentUser.Name,
}
templates.Execute(w, "group_page.gotmpl", p)
}
@@ -120,8 +120,8 @@ func (ctx *Context) GroupPost(currentUser *db.User, w http.ResponseWriter, r *ht
_ = json.NewEncoder(w).Encode(group)
}
-func (ctx *Context) GroupsJson(user *db.User, w http.ResponseWriter, r *http.Request) {
- if !user.IsAdmin {
+func (ctx *Context) GroupsJson(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
+ if !currentUser.IsAdmin {
NotFoundJson(w, r)
return
}
@@ -135,8 +135,8 @@ func (ctx *Context) GroupsJson(user *db.User, w http.ResponseWriter, r *http.Req
_ = json.NewEncoder(w).Encode(groups)
}
-func (ctx *Context) Group(user *db.User, w http.ResponseWriter, r *http.Request) {
- if !user.IsAdmin {
+func (ctx *Context) Group(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
+ if !currentUser.IsAdmin {
NotFoundJson(w, r)
return
}
diff --git a/server/routing/home.go b/server/routing/home.go
index 46292c0..98e40d6 100644
--- a/server/routing/home.go
+++ b/server/routing/home.go
@@ -18,40 +18,40 @@ type HomeProps struct {
Groups []db.Group
}
-func (ctx *Context) Home(user *db.User, w http.ResponseWriter, r *http.Request) {
- gifts, err := user.GetGifts()
+func (ctx *Context) Home(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
+ gifts, err := currentUser.GetGifts()
if err != nil {
error.Page(w, "An error occurred while fetching your wishlist :(", http.StatusInternalServerError, err)
return
}
- todo, err := user.GetTodo()
+ todo, err := currentUser.GetTodo()
if err != nil {
error.Page(w, "An error occurred while fetching your wishlist :(", http.StatusInternalServerError, err)
return
}
- groups, err := user.GetGroups()
+ groups, err := currentUser.GetGroups()
if err != nil {
error.Page(w, "An error occurred while fetching your wishlist :(", http.StatusInternalServerError, err)
return
}
- p := HomeProps{Username: user.Name, Gifts: gifts, Todo: todo, Reference: user.Reference, HostUrl: env.HostUrl.String(), Groups: groups}
+ p := HomeProps{Username: currentUser.Name, Gifts: gifts, Todo: todo, Reference: currentUser.Reference, HostUrl: env.HostUrl.String(), Groups: groups}
templates.Execute(w, "home.gotmpl", p)
}
-func (ctx *Context) HomePost(user *db.User, w http.ResponseWriter, r *http.Request) {
+func (ctx *Context) HomePost(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
http.Error(w, "Couldn't parse form", http.StatusBadRequest)
return
}
switch r.Form.Get("intent") {
case "add_idea":
- ctx.WishlistAdd(user, w, r)
+ ctx.WishlistAdd(currentUser, w, r)
return
case "delete_idea":
- ctx.WishlistDelete(user, w, r)
+ ctx.WishlistDelete(currentUser, w, r)
return
default:
- ctx.TodoUpdate(user, w, r)
+ ctx.TodoUpdate(currentUser, w, r)
return
}
}
diff --git a/server/routing/todo.go b/server/routing/todo.go
index 554cbff..c86e8f0 100644
--- a/server/routing/todo.go
+++ b/server/routing/todo.go
@@ -6,7 +6,7 @@ import (
"net/http"
)
-func (ctx *Context) TodoUpdate(user *db.User, w http.ResponseWriter, r *http.Request) {
+func (ctx *Context) TodoUpdate(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@@ -14,14 +14,14 @@ func (ctx *Context) TodoUpdate(user *db.User, w http.ResponseWriter, r *http.Req
switch r.Form.Get("intent") {
case "unclaim_todo":
unclaims := r.Form["gift"]
- err := user.ClaimGifts([]string{}, unclaims)
+ err := currentUser.ClaimGifts([]string{}, unclaims)
if err != nil {
http.Error(w, "Failed to update claim...", http.StatusInternalServerError)
return
}
case "complete_todo":
claims := r.Form["gift"]
- err := user.CompleteGifts(claims)
+ err := currentUser.CompleteGifts(claims)
if err != nil {
log.Printf("Failed to complete gifts: %s\n", err)
http.Error(w, "Failed to complete gifts...", http.StatusInternalServerError)
@@ -29,6 +29,7 @@ func (ctx *Context) TodoUpdate(user *db.User, w http.ResponseWriter, r *http.Req
}
default:
http.Error(w, "Invalid intent", http.StatusBadRequest)
+ return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
diff --git a/server/routing/users.go b/server/routing/users.go
index b4c3220..b108f5f 100644
--- a/server/routing/users.go
+++ b/server/routing/users.go
@@ -6,8 +6,8 @@ import (
"net/http"
)
-func (ctx *Context) UsersJson(user *db.User, w http.ResponseWriter, r *http.Request) {
- if !user.IsAdmin {
+func (ctx *Context) UsersJson(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
+ if !currentUser.IsAdmin {
NotFoundJson(w, r)
return
}
@@ -20,3 +20,63 @@ func (ctx *Context) UsersJson(user *db.User, w http.ResponseWriter, r *http.Requ
_ = json.NewEncoder(w).Encode(users)
}
+
+func (ctx *Context) User(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
+ if !currentUser.IsAdmin {
+ NotFoundJson(w, r)
+ return
+ }
+
+ reference := r.PathValue("userReference")
+
+ user, err := db.GetUserByReference(reference)
+ if err != nil {
+ writeGeneralErrorJson(w, http.StatusInternalServerError, "Failed to get user: %s", err)
+ return
+ }
+ if user == nil {
+ writeGeneralErrorJson(w, http.StatusNotFound, "User not found")
+ return
+ }
+
+ _ = json.NewEncoder(w).Encode(user)
+}
+
+func (ctx *Context) UserPost(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
+ if !currentUser.IsAdmin {
+ NotFoundJson(w, r)
+ return
+ }
+ if err := r.ParseForm(); err != nil {
+ writeGeneralErrorJson(w, http.StatusInternalServerError, "Failed to parse form: %s", err)
+ return
+ }
+
+ reference := r.PathValue("userReference")
+ if reference == currentUser.Reference {
+ writeGeneralErrorJson(w, http.StatusForbidden, "You cannot delete yourself.")
+ return
+ }
+
+ user, err := db.GetAnyUserByReference(reference)
+ if err != nil {
+ writeGeneralErrorJson(w, http.StatusInternalServerError, "Failed to get user: %s", err)
+ return
+ }
+ if user == nil {
+ writeGeneralErrorJson(w, http.StatusNotFound, "User not found")
+ return
+ }
+
+ intent := r.Form.Get("intent")
+
+ if intent != "" {
+ err = user.SetLive(intent != "delete")
+ if err != nil {
+ writeGeneralErrorJson(w, http.StatusInternalServerError, "Failed to delete user: "+err.Error())
+ return
+ }
+ }
+
+ _ = json.NewEncoder(w).Encode(user)
+}
diff --git a/server/routing/wishlist.go b/server/routing/wishlist.go
index 08d9006..394a5b7 100644
--- a/server/routing/wishlist.go
+++ b/server/routing/wishlist.go
@@ -6,13 +6,13 @@ import (
"net/http"
)
-func (ctx *Context) WishlistAdd(user *db.User, w http.ResponseWriter, r *http.Request) {
+func (ctx *Context) WishlistAdd(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
newGiftName := r.Form.Get("gift_name")
- err := user.AddGift(newGiftName)
+ err := currentUser.AddGift(newGiftName)
if err != nil {
error.Page(w, "Failed to add gift.", http.StatusInternalServerError, err)
return
@@ -20,13 +20,13 @@ func (ctx *Context) WishlistAdd(user *db.User, w http.ResponseWriter, r *http.Re
http.Redirect(w, r, "/", http.StatusSeeOther)
}
-func (ctx *Context) WishlistDelete(user *db.User, w http.ResponseWriter, r *http.Request) {
+func (ctx *Context) WishlistDelete(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
targets := r.Form["gift"]
- err := user.RemoveGifts(targets...)
+ err := currentUser.RemoveGifts(targets...)
if err != nil {
error.Page(w, "Failed to remove gifts.", http.StatusInternalServerError, err)
return
@@ -34,7 +34,7 @@ func (ctx *Context) WishlistDelete(user *db.User, w http.ResponseWriter, r *http
http.Redirect(w, r, "/", http.StatusSeeOther)
}
-func (ctx *Context) ForeignWishlistPost(user *db.User, w http.ResponseWriter, r *http.Request) {
+func (ctx *Context) ForeignWishlistPost(currentUser *db.User, w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
error.Page(w, "Failed to parse form...", http.StatusBadRequest, err)
return
@@ -44,14 +44,14 @@ func (ctx *Context) ForeignWishlistPost(user *db.User, w http.ResponseWriter, r
case "claim":
claims := r.Form["unclaimed"]
unclaims := r.Form["claimed"]
- err := user.ClaimGifts(claims, unclaims)
+ err := currentUser.ClaimGifts(claims, unclaims)
if err != nil {
error.Page(w, "Failed to update claim...", http.StatusInternalServerError, err)
return
}
case "complete":
claims := r.Form["claimed"]
- err := user.CompleteGifts(claims)
+ err := currentUser.CompleteGifts(claims)
if err != nil {
error.Page(w, "Failed to complete gifts...", http.StatusInternalServerError, nil)
return
@@ -62,7 +62,7 @@ func (ctx *Context) ForeignWishlistPost(user *db.User, w http.ResponseWriter, r
error.Page(w, "Gift name not provided", http.StatusBadRequest, nil)
return
}
- err := user.AddGiftToUser(userReference, giftName)
+ err := currentUser.AddGiftToUser(userReference, giftName)
if err != nil {
error.Page(w, "Failed to add gift idea to other user...", http.StatusInternalServerError, err)
return
@@ -71,7 +71,7 @@ func (ctx *Context) ForeignWishlistPost(user *db.User, w http.ResponseWriter, r
claims := r.Form["unclaimed"]
unclaims := r.Form["claimed"]
gifts := append(claims, unclaims...)
- err := user.RemoveGifts(gifts...)
+ err := currentUser.RemoveGifts(gifts...)
if err != nil {
error.Page(w, "Failed to remove gift idea for other user...", http.StatusInternalServerError, err)
return
diff --git a/server/templates/home.gotmpl b/server/templates/home.gotmpl
index 6a87056..76108b5 100644
--- a/server/templates/home.gotmpl
+++ b/server/templates/home.gotmpl
@@ -83,7 +83,7 @@
-
{{else}}