diff --git a/go.mod b/go.mod index 4dd5587..7172386 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.solsynth.dev/hydrogen/messaging go 1.21.6 require ( - git.solsynth.dev/hydrogen/identity v0.0.0-20240331080359-e8aac7bb6627 + git.solsynth.dev/hydrogen/identity v0.0.0-20240406034845-44d2ec9c4ace github.com/go-playground/validator/v10 v10.17.0 github.com/gofiber/fiber/v2 v2.52.4 github.com/gofiber/template/html/v2 v2.1.1 diff --git a/go.sum b/go.sum index 41f6731..d6b24ab 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ git.solsynth.dev/hydrogen/identity v0.0.0-20240320131628-6ac77f36957f h1:6vRGU5b git.solsynth.dev/hydrogen/identity v0.0.0-20240320131628-6ac77f36957f/go.mod h1:rmh5biOQLvoIE2iRFbOfD0TITMP1orYpqzhUw50Z4ck= git.solsynth.dev/hydrogen/identity v0.0.0-20240331080359-e8aac7bb6627 h1:BUhDqy/Whw1yVbDpmGk7clzRAC1jo+AOsCwuwhCVwkg= git.solsynth.dev/hydrogen/identity v0.0.0-20240331080359-e8aac7bb6627/go.mod h1:GxcduEpQWQ2mO37A9uRtseS680uMLi957GDywRBAJHg= +git.solsynth.dev/hydrogen/identity v0.0.0-20240406034845-44d2ec9c4ace h1:bXbBjM56vA3BxfyuD0IrlJabpVx5bLi4qCv3/RsPa1c= +git.solsynth.dev/hydrogen/identity v0.0.0-20240406034845-44d2ec9c4ace/go.mod h1:GxcduEpQWQ2mO37A9uRtseS680uMLi957GDywRBAJHg= github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= diff --git a/pkg/grpc/client.go b/pkg/grpc/client.go index ca3f014..c882dc8 100644 --- a/pkg/grpc/client.go +++ b/pkg/grpc/client.go @@ -8,6 +8,7 @@ import ( "google.golang.org/grpc" ) +var Friendships idpb.FriendshipsClient var Notify idpb.NotifyClient var Auth idpb.AuthClient @@ -16,6 +17,7 @@ func ConnectPassport() error { if conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())); err != nil { return err } else { + Friendships = idpb.NewFriendshipsClient(conn) Notify = idpb.NewNotifyClient(conn) Auth = idpb.NewAuthClient(conn) } diff --git a/pkg/server/channel_members_api.go b/pkg/server/channel_members_api.go index 892c255..8852abf 100644 --- a/pkg/server/channel_members_api.go +++ b/pkg/server/channel_members_api.go @@ -44,7 +44,7 @@ func inviteChannel(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusNotFound, err.Error()) } - if err := services.AddChannelMember(account, channel); err != nil { + if err := services.InviteChannelMember(account, channel); err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) } else { return c.SendStatus(fiber.StatusOK) @@ -84,3 +84,31 @@ func kickChannel(c *fiber.Ctx) error { return c.SendStatus(fiber.StatusOK) } } + +func leaveChannel(c *fiber.Ctx) error { + user := c.Locals("principal").(models.Account) + channelId, _ := c.ParamsInt("channelId", 0) + + var data struct { + AccountName string `json:"account_name" validate:"required"` + } + + if err := BindAndValidate(c, &data); err != nil { + return err + } + + var channel models.Channel + if err := database.C.Where(&models.Channel{ + BaseModel: models.BaseModel{ID: uint(channelId)}, + }).First(&channel).Error; err != nil { + return fiber.NewError(fiber.StatusNotFound, err.Error()) + } else if user.ID == channel.AccountID { + return fiber.NewError(fiber.StatusBadRequest, "you cannot leave your own channel") + } + + if err := services.RemoveChannelMember(user, channel); err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } else { + return c.SendStatus(fiber.StatusOK) + } +} diff --git a/pkg/server/startup.go b/pkg/server/startup.go index 4b92bc5..ff47e44 100644 --- a/pkg/server/startup.go +++ b/pkg/server/startup.go @@ -88,6 +88,7 @@ func NewServer() { channels.Get("/:channelId/members", listChannelMembers) channels.Post("/:channelId/invite", authMiddleware, inviteChannel) channels.Post("/:channelId/kick", authMiddleware, kickChannel) + channels.Post("/:channelId/leave", authMiddleware, leaveChannel) channels.Get("/:channel/messages", listMessage) channels.Post("/:channel/messages", authMiddleware, newTextMessage) diff --git a/pkg/services/accounts.go b/pkg/services/accounts.go index 7f6980d..048254d 100644 --- a/pkg/services/accounts.go +++ b/pkg/services/accounts.go @@ -10,6 +10,17 @@ import ( "github.com/spf13/viper" ) +func GetAccountFriend(userId, relatedId uint, status int) (*proto.FriendshipResponse, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + return grpc.Friendships.GetFriendship(ctx, &proto.FriendshipTwoSideLookupRequest{ + AccountId: uint64(userId), + RelatedId: uint64(relatedId), + Status: uint32(status), + }) +} + func NotifyAccount(user models.Account, subject, content string, realtime bool, links ...*proto.NotifyLink) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() diff --git a/pkg/services/channels.go b/pkg/services/channels.go index 3a83014..80703af 100644 --- a/pkg/services/channels.go +++ b/pkg/services/channels.go @@ -132,6 +132,20 @@ func ListChannelMember(channelId uint) ([]models.ChannelMember, error) { return members, nil } +func InviteChannelMember(user models.Account, target models.Channel) error { + if _, err := GetAccountFriend(user.ID, target.AccountID, 1); err != nil { + return fmt.Errorf("you only can invite your friends to your channel") + } + + member := models.ChannelMember{ + ChannelID: target.ID, + AccountID: user.ID, + } + + err := database.C.Save(&member).Error + return err +} + func AddChannelMember(user models.Account, target models.Channel) error { member := models.ChannelMember{ ChannelID: target.ID, @@ -139,7 +153,6 @@ func AddChannelMember(user models.Account, target models.Channel) error { } err := database.C.Save(&member).Error - return err }