From bbae0e8fbb2994323f5b1c07e9df4818348a618a Mon Sep 17 00:00:00 2001 From: slawk0 Date: Sat, 8 Feb 2025 16:13:53 +0100 Subject: [PATCH] added rows close, get group members route --- database/contacts.go | 2 ++ database/groups.go | 54 ++++++++++++++++++++++++++++++++++++++++++++ database/messages.go | 2 ++ handlers/groups.go | 27 ++++++++++++++++++++++ model/model.go | 7 ++++++ router/router.go | 1 + 6 files changed, 93 insertions(+) diff --git a/database/contacts.go b/database/contacts.go index c70e1b4..44f6aee 100644 --- a/database/contacts.go +++ b/database/contacts.go @@ -289,6 +289,7 @@ func GetContacts(db *sql.DB, userID uuid.UUID) ([]*model.Contact, error) { if err != nil { return []*model.Contact{}, helpers.NewError(helpers.ErrInternal, "Failed to get contacts", fmt.Errorf("failed to get contacts: %w", err)) } + defer rows.Close() var contacts []*model.Contact for rows.Next() { @@ -330,6 +331,7 @@ func ContactSuggestion(db *sql.DB, contactUsername string) ([]string, error) { if err != nil && !errors.Is(err, sql.ErrNoRows) { return []string{}, helpers.NewError(helpers.ErrInternal, "Failed to get contact suggestions", fmt.Errorf("failed to get contact suggestions: %w", err)) } + defer rows.Close() var suggestions []string for rows.Next() { diff --git a/database/groups.go b/database/groups.go index 00911fb..c281f39 100644 --- a/database/groups.go +++ b/database/groups.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/google/uuid" "relay-server/helpers" + "relay-server/model" ) func CreateGroup(db *sql.DB, groupName string, userID uuid.UUID) (uuid.UUID, error) { @@ -64,6 +65,45 @@ func AddMemberToGroup(db *sql.DB, userID uuid.UUID, groupID uuid.UUID) (uuid.UUI return memberID, nil } +func GetMembers(db *sql.DB, groupID uuid.UUID) ([]*model.Member, error) { + query := ` + SELECT + a.user_id, + a.username, + CASE + WHEN ga.user_id IS NOT NULL THEN TRUE + ELSE FALSE + END AS isAdmin, + COALESCE(ga.is_owner, FALSE) AS isOwner + FROM Memberships m + JOIN Accounts a ON m.user_id = a.user_id + LEFT JOIN GroupAdmins ga ON m.user_id = ga.user_id AND m.conversation_id = ga.conversation_id + WHERE m.conversation_id = $1; + ` + + rows, err := db.Query(query, groupID) + if err != nil { + return []*model.Member{}, helpers.NewError(helpers.ErrInternal, "Failed to get members", fmt.Errorf("failed to get members: %w", err)) + } + defer rows.Close() + + var members []*model.Member + for rows.Next() { + var member model.Member + err = rows.Scan(&member.UserID, &member.Username, &member.IsAdmin, &member.IsOwner) + if err != nil { + return []*model.Member{}, helpers.NewError(helpers.ErrInternal, "Failed to get members", fmt.Errorf("failed to scan member: %w", err)) + } + members = append(members, &member) + } + + if err = rows.Err(); err != nil { + return []*model.Member{}, helpers.NewError(helpers.ErrInternal, "Failed to get members", fmt.Errorf("error iterating members: %w", err)) + } + + return members, nil +} + func IsAdmin(db *sql.DB, userID uuid.UUID, conversationID uuid.UUID) (bool, error) { query := ` SELECT COUNT(1) FROM GroupAdmins @@ -77,3 +117,17 @@ func IsAdmin(db *sql.DB, userID uuid.UUID, conversationID uuid.UUID) (bool, erro } return count > 0, nil } + +func IsMember(db *sql.DB, userID uuid.UUID, conversationID uuid.UUID) (bool, error) { + query := ` + SELECT COUNT(1) FROM Memberships + WHERE user_id = $1 + AND conversation_id = $2; + ` + var count int + err := db.QueryRow(query, userID, conversationID).Scan(&count) + if err != nil { + return false, helpers.NewError(helpers.ErrInternal, "Failed to check membership", fmt.Errorf("failed to check membership: %w", err)) + } + return count > 0, nil +} diff --git a/database/messages.go b/database/messages.go index d0133e0..ddcd274 100644 --- a/database/messages.go +++ b/database/messages.go @@ -35,6 +35,7 @@ func GetMessages(db *sql.DB, userID uuid.UUID, conversationID uuid.UUID, limit i if err != nil { return []*model.Message{}, helpers.NewError(helpers.ErrInternal, "Failed to get messages", fmt.Errorf("failed to get messages: %w", err)) } + defer rows.Close() for rows.Next() { message := &model.Message{} @@ -66,6 +67,7 @@ func GetMessages(db *sql.DB, userID uuid.UUID, conversationID uuid.UUID, limit i if err != nil { return []*model.Message{}, helpers.NewError(helpers.ErrInternal, "Failed to get messages", fmt.Errorf("failed to get messages: %w", err)) } + defer rows.Close() for rows.Next() { message := &model.Message{} diff --git a/handlers/groups.go b/handlers/groups.go index edf59df..9ec18a2 100644 --- a/handlers/groups.go +++ b/handlers/groups.go @@ -1,6 +1,7 @@ package handlers import ( + "fmt" "github.com/gofiber/fiber/v2" "github.com/google/uuid" "log" @@ -66,3 +67,29 @@ func AddMemberToGroup(c *fiber.Ctx) error { log.Println("Successfully added member to group") return c.Status(fiber.StatusOK).JSON(fiber.Map{"message": "Successfully added member to group"}) } + +func GetMembers(c *fiber.Ctx) error { + type params struct { + GroupID uuid.UUID `params:"groupID"` + } + var p params + + if err := c.ParamsParser(&p); err != nil { + return helpers.NewError(helpers.ErrInvalidInput, "Invalid params", err) + } + + isMember, err := database.IsMember(database.DB, p.GroupID, c.Locals("userID").(uuid.UUID)) + if err != nil { + return helpers.NewError(helpers.ErrInternal, "Failed to get members", fmt.Errorf("failed to check if user is a member: %w", err)) + } + if !isMember { + return helpers.NewError(helpers.ErrForbidden, "You are not a member of this group", nil) + } + + members, err := database.GetMembers(database.DB, p.GroupID) + if err != nil { + return err + } + + return c.Status(fiber.StatusOK).JSON(fiber.Map{"members": members}) +} diff --git a/model/model.go b/model/model.go index 6ff2f98..d539b07 100644 --- a/model/model.go +++ b/model/model.go @@ -40,3 +40,10 @@ type Message struct { type CreateGroupResponse struct { GroupID uuid.UUID `json:"group_id"` } + +type Member struct { + UserID uuid.UUID `json:"user_id"` + Username string `json:"username"` + IsAdmin bool `json:"is_admin"` + IsOwner bool `json:"is_owner"` +} diff --git a/router/router.go b/router/router.go index a94d20d..b80c0a6 100644 --- a/router/router.go +++ b/router/router.go @@ -35,4 +35,5 @@ func SetupRoutes(app *fiber.App) { groups := chat.Group("/groups", middleware.Protected(), logger.New()) groups.Post("/create", handlers.CreateGroup) groups.Post("/addMember", handlers.AddMemberToGroup) + groups.Get("/getMembers/:groupID", handlers.GetMembers) }