diff --git a/core/admin.go b/core/admin.go index 8f87b2a..0667389 100644 --- a/core/admin.go +++ b/core/admin.go @@ -5,7 +5,7 @@ type Admin struct { } func (s *Session) Admin() *Admin { - if s.User.IsAdmin { + if s.User().IsAdmin { return &Admin{s} } else { return nil diff --git a/core/api.snap.txt b/core/api.snap.txt index cdf2b38..04aafcd 100644 --- a/core/api.snap.txt +++ b/core/api.snap.txt @@ -45,7 +45,7 @@ func GetGroupByReference(reference string) (*Group, error) func (g *Group) MemberIndex(userId string) int type Session struct { - User + // Has unexported fields. } func Login(username, password string) (*Session, error) @@ -74,6 +74,8 @@ func (s *Session) RevokeWishes(ids ...string) error func (u *Session) SuggestWishForUser(otherUserReference string, wishName string) error +func (s *Session) User() User + type User struct { Id string NormalName string diff --git a/core/group.go b/core/group.go index 230c475..2b09c7f 100644 --- a/core/group.go +++ b/core/group.go @@ -72,7 +72,7 @@ func queryManyGroupMembers(groupId string) ([]User, error) { func (s *Session) GetGroupByReference(reference string) (*Group, error) { stmt := "SELECT [group].id, [group].name, [group].reference FROM [group] JOIN group_member ON [group].id == group_member.group_id WHERE [group].reference = ? AND group_member.user_id = ?;" - return queryOneGroup(stmt, reference, s.User.Id) + return queryOneGroup(stmt, reference, s.User().Id) } func GetGroupByReference(reference string) (*Group, error) { @@ -126,5 +126,5 @@ func (a *Admin) RemoveUserFromGroup(userId, groupId string) error { // Get the groups the session user belongs to func (u *Session) GetGroups() ([]Group, error) { 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 = ?" - return queryManyGroups(stmt, u.Id) + return queryManyGroups(stmt, u.User().Id) } diff --git a/core/group_test.go b/core/group_test.go index de96b63..e2b7ba6 100644 --- a/core/group_test.go +++ b/core/group_test.go @@ -26,7 +26,7 @@ func TestCantSeeSelfInGroup(t *testing.T) { group, err := s.Admin().CreateGroup(" My Friends ", " my-friends ") fixtures.FailIfErr(t, err, "Failed to create group") - err = s.Admin().AddUserToGroup(s.User.Id, group.Id) + err = s.Admin().AddUserToGroup(s.User().Id, group.Id) fixtures.FailIfErr(t, err, "Failed to add self to group") err = s.Admin().AddUserToGroup(caleb.Id, group.Id) diff --git a/core/session.go b/core/session.go index 1a7445b..2e6eab6 100644 --- a/core/session.go +++ b/core/session.go @@ -3,7 +3,12 @@ package lishwist import "fmt" type Session struct { - User + user User +} + +// Returns a copy of the user associated with this session +func (s *Session) User() User { + return s.user } func SessionFromUsername(username string) (*Session, error) { diff --git a/core/wish.go b/core/wish.go index 3b7dffb..f7688d1 100644 --- a/core/wish.go +++ b/core/wish.go @@ -24,7 +24,7 @@ type Wish struct { func (s *Session) GetWishes() ([]Wish, error) { stmt := "SELECT wish.id, wish.name, wish.sent FROM wish WHERE wish.creator_id = ?1 AND wish.recipient_id = ?1" - rows, err := db.Connection.Query(stmt, s.User.Id) + rows, err := db.Connection.Query(stmt, s.User().Id) if err != nil { return nil, fmt.Errorf("Query execution failed: %w", err) } @@ -54,17 +54,17 @@ func (s *Session) GetWishes() ([]Wish, error) { func (s *Session) MakeWish(name string) error { stmt := "INSERT INTO wish (name, recipient_id, creator_id) VALUES (?, ?, ?)" - _, err := db.Connection.Exec(stmt, strings.TrimSpace(name), s.User.Id, s.User.Id) + _, err := db.Connection.Exec(stmt, strings.TrimSpace(name), s.User().Id, s.User().Id) if err != nil { return fmt.Errorf("Query execution failed: %w", err) } return nil } -func (u *Session) deleteWishes(tx *sql.Tx, ids []string) error { +func (s *Session) deleteWishes(tx *sql.Tx, ids []string) error { stmt := "DELETE FROM wish WHERE wish.creator_id = ? AND wish.id = ?" for _, id := range ids { - r, err := tx.Exec(stmt, u.Id, id) + r, err := tx.Exec(stmt, s.User().Id, id) if err != nil { return err } @@ -107,7 +107,7 @@ func (s *Session) GetOthersWishes(userReference string) ([]Wish, error) { if err != nil { return nil, fmt.Errorf("Failed to get other user: %w", err) } - if otherUser.Id == s.User.Id { + if otherUser.Id == s.User().Id { return nil, errors.New("Use (s *Session) GetWishes() to view your own wishes") } stmt := "SELECT wish.id, wish.name, claimant.id, claimant.name, wish.sent, wish.creator_id, creator.name, wish.recipient_id FROM wish JOIN v_user AS user ON wish.recipient_id = user.id LEFT JOIN v_user AS claimant ON wish.claimant_id = claimant.id LEFT JOIN v_user AS creator ON wish.creator_id = creator.id WHERE user.id = ?" @@ -164,7 +164,7 @@ func (s *Session) executeClaims(tx *sql.Tx, claims, unclaims []string) error { claimStmt := "UPDATE wish SET claimant_id = ? WHERE id = ?" unclaimStmt := "UPDATE wish SET claimant_id = NULL WHERE id = ?" for _, id := range claims { - r, err := tx.Exec(claimStmt, s.Id, id) + r, err := tx.Exec(claimStmt, s.User().Id, id) if err != nil { return err } @@ -264,7 +264,7 @@ func (u *Session) SuggestWishForUser(otherUserReference string, wishName string) return err } stmt := "INSERT INTO wish (name, recipient_id, creator_id) VALUES (?, ?, ?)" - _, err = db.Connection.Exec(stmt, wishName, otherUser.Id, u.Id) + _, err = db.Connection.Exec(stmt, wishName, otherUser.Id, u.User().Id) if err != nil { return err } diff --git a/http/routing/foreign_wishlist.go b/http/routing/foreign_wishlist.go index 366b508..a2c4136 100644 --- a/http/routing/foreign_wishlist.go +++ b/http/routing/foreign_wishlist.go @@ -18,7 +18,8 @@ type foreignWishlistProps struct { func ForeignWishlist(app *lishwist.Session, h http.Header, r *http.Request) rsvp.Response { userReference := r.PathValue("userReference") - if app.User.Reference == userReference { + user := app.User() + if user.Reference == userReference { return rsvp.Found("/", "You're not allowed to view your own wishlist!") } otherUser, err := lishwist.GetUserByReference(userReference) @@ -31,10 +32,10 @@ func ForeignWishlist(app *lishwist.Session, h http.Header, r *http.Request) rsvp } wishes, err := app.GetOthersWishes(userReference) if err != nil { - log.Printf("%q couldn't get wishes of other user %q: %s\n", app.User.Name, otherUser.Name, err) + log.Printf("%q couldn't get wishes of other user %q: %s\n", user.Name, otherUser.Name, err) return response.Error(http.StatusInternalServerError, "An error occurred while fetching this user :(") } - p := foreignWishlistProps{CurrentUserId: app.User.Id, CurrentUserName: app.User.Name, Username: otherUser.Name, Gifts: wishes} + p := foreignWishlistProps{CurrentUserId: user.Id, CurrentUserName: user.Name, Username: otherUser.Name, Gifts: wishes} return response.Data("foreign_wishlist.gotmpl", p) } diff --git a/http/routing/groups.go b/http/routing/groups.go index cdf061e..33f8749 100644 --- a/http/routing/groups.go +++ b/http/routing/groups.go @@ -25,19 +25,21 @@ func AdminGroup(app *lishwist.Session, h http.Header, r *http.Request) rsvp.Resp if group == nil { return response.Error(http.StatusNotFound, "Group not found") } - if !app.User.IsAdmin { - index := group.MemberIndex(app.User.Id) + user := app.User() + if !user.IsAdmin { + index := group.MemberIndex(user.Id) group.Members = slices.Delete(group.Members, index, index+1) } p := GroupProps{ Group: group, - CurrentUsername: app.User.Name, + CurrentUsername: user.Name, } return response.Data("group_page.gotmpl", p) } func Group(app *lishwist.Session, h http.Header, r *http.Request) rsvp.Response { - if app.User.IsAdmin { + user := app.User() + if user.IsAdmin { return AdminGroup(app, h, r) } groupReference := r.PathValue("groupReference") @@ -49,11 +51,11 @@ func Group(app *lishwist.Session, h http.Header, r *http.Request) rsvp.Response if group == nil { return response.Error(http.StatusNotFound, "Group not found. (It might be because you're not a member)") } - index := group.MemberIndex(app.User.Id) + index := group.MemberIndex(user.Id) group.Members = slices.Delete(group.Members, index, index+1) p := GroupProps{ Group: group, - CurrentUsername: app.User.Name, + CurrentUsername: user.Name, } return response.Data("group_page.gotmpl", p) } diff --git a/http/routing/home.go b/http/routing/home.go index 7c68e01..589b746 100644 --- a/http/routing/home.go +++ b/http/routing/home.go @@ -26,7 +26,8 @@ func Home(app *lishwist.Session, h http.Header, r *http.Request) rsvp.Response { log.Printf("Failed to get gifts: %s\n", err) return response.Error(http.StatusInternalServerError, "An error occurred while fetching your wishlist :(") } - todo, err := app.GetTodo() + user := app.User() + todo, err := user.GetTodo() if err != nil { log.Printf("Failed to get todo: %s\n", err) return response.Error(http.StatusInternalServerError, "An error occurred while fetching your wishlist :(") @@ -36,7 +37,7 @@ func Home(app *lishwist.Session, h http.Header, r *http.Request) rsvp.Response { log.Printf("Failed to get groups: %s\n", err) return response.Error(http.StatusInternalServerError, "An error occurred while fetching your wishlist :(") } - p := HomeProps{Username: app.User.Name, Gifts: gifts, Todo: todo, Reference: app.User.Reference, HostUrl: env.HostUrl.String(), Groups: groups} + p := HomeProps{Username: user.Name, Gifts: gifts, Todo: todo, Reference: user.Reference, HostUrl: env.HostUrl.String(), Groups: groups} return response.Data("home.gotmpl", p) } diff --git a/http/routing/login.go b/http/routing/login.go index 05fcbb4..5021e67 100644 --- a/http/routing/login.go +++ b/http/routing/login.go @@ -70,9 +70,10 @@ func LoginPost(session *response.Session, h http.Header, r *http.Request) rsvp.R } } + user := app.User() session.SetID("") session.SetValue("authorized", true) - session.SetValue("username", app.User.Name) + session.SetValue("username", user.Name) return rsvp.SeeOther(r.URL.Path, "Login successful!") } diff --git a/http/routing/users.go b/http/routing/users.go index f1d509b..0ab648f 100644 --- a/http/routing/users.go +++ b/http/routing/users.go @@ -53,7 +53,7 @@ func UserPost(app *lishwist.Session, h http.Header, r *http.Request) rsvp.Respon } reference := r.PathValue("userReference") - if reference == app.User.Reference { + if reference == app.User().Reference { return response.Error(http.StatusForbidden, "You cannot delete yourself.") }