Channels with realm basis

This commit is contained in:
LittleSheep 2024-05-05 01:04:14 +08:00
parent e6407bbe4d
commit 3a6b51da97
4 changed files with 106 additions and 19 deletions

View File

@ -1,6 +1,7 @@
package server package server
import ( import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database" "git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models" "git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/services" "git.solsynth.dev/hydrogen/messaging/pkg/services"
@ -10,7 +11,13 @@ import (
func getChannel(c *fiber.Ctx) error { func getChannel(c *fiber.Ctx) error {
alias := c.Params("channel") alias := c.Params("channel")
channel, err := services.GetChannelWithAlias(alias) var err error
var channel models.Channel
if val, ok := c.Locals("realm").(models.Realm); ok {
channel, err = services.GetChannelWithAlias(alias, val.ID)
} else {
channel, err = services.GetChannelWithAlias(alias)
}
if err != nil { if err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error()) return fiber.NewError(fiber.StatusNotFound, err.Error())
} }
@ -19,7 +26,13 @@ func getChannel(c *fiber.Ctx) error {
} }
func listChannel(c *fiber.Ctx) error { func listChannel(c *fiber.Ctx) error {
channels, err := services.ListChannel() var err error
var channels []models.Channel
if val, ok := c.Locals("realm").(models.Realm); ok {
channels, err = services.ListChannel(val.ID)
} else {
channels, err = services.ListChannel()
}
if err != nil { if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error()) return fiber.NewError(fiber.StatusBadRequest, err.Error())
} }
@ -64,7 +77,25 @@ func createChannel(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusBadRequest, err.Error()) return fiber.NewError(fiber.StatusBadRequest, err.Error())
} }
channel, err := services.NewChannel(user, data.Alias, data.Name, data.Description) var realm *models.Realm
if val, ok := c.Locals("realm").(models.Realm); ok {
if info, err := services.GetRealmMember(val.ID, user.ExternalID); err != nil {
return fmt.Errorf("you must be a part of that realm then can create channel related to it")
} else if info.GetPowerLevel() < 50 {
return fmt.Errorf("you must be a moderator of that realm then can create channel related to it")
} else {
realm = &val
}
}
var err error
var channel models.Channel
if realm != nil {
channel, err = services.NewChannel(user, data.Alias, data.Name, data.Description, realm.ID)
} else {
channel, err = services.NewChannel(user, data.Alias, data.Name, data.Description)
}
if err != nil { if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error()) return fiber.NewError(fiber.StatusBadRequest, err.Error())
} }
@ -86,11 +117,22 @@ func editChannel(c *fiber.Ctx) error {
return err return err
} }
tx := database.C.Where(&models.Channel{BaseModel: models.BaseModel{ID: uint(id)}})
if val, ok := c.Locals("realm").(models.Realm); ok {
if info, err := services.GetRealmMember(val.ID, user.ExternalID); err != nil {
return fmt.Errorf("you must be a part of that realm then can edit channel related to it")
} else if info.GetPowerLevel() < 50 {
return fmt.Errorf("you must be a moderator of that realm then can edit channel related to it")
} else {
tx = tx.Where("realm_id = ?", val.ID)
}
} else {
tx = tx.Where("account_id = ? AND realm_id IS NULL", user.ID)
}
var channel models.Channel var channel models.Channel
if err := database.C.Where(&models.Channel{ if err := tx.First(&channel).Error; err != nil {
BaseModel: models.BaseModel{ID: uint(id)},
AccountID: user.ID,
}).First(&channel).Error; err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error()) return fiber.NewError(fiber.StatusNotFound, err.Error())
} }
@ -106,11 +148,22 @@ func deleteChannel(c *fiber.Ctx) error {
user := c.Locals("principal").(models.Account) user := c.Locals("principal").(models.Account)
id, _ := c.ParamsInt("channelId", 0) id, _ := c.ParamsInt("channelId", 0)
tx := database.C.Where(&models.Channel{BaseModel: models.BaseModel{ID: uint(id)}})
if val, ok := c.Locals("realm").(models.Realm); ok {
if info, err := services.GetRealmMember(val.ID, user.ExternalID); err != nil {
return fmt.Errorf("you must be a part of that realm then can delete channel related to it")
} else if info.GetPowerLevel() < 50 {
return fmt.Errorf("you must be a moderator of that realm then can delete channel related to it")
} else {
tx = tx.Where("realm_id = ?", val.ID)
}
} else {
tx = tx.Where("account_id = ? AND realm_id IS NULL", user.ID)
}
var channel models.Channel var channel models.Channel
if err := database.C.Where(&models.Channel{ if err := tx.First(&channel).Error; err != nil {
BaseModel: models.BaseModel{ID: uint(id)},
AccountID: user.ID,
}).First(&channel).Error; err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error()) return fiber.NewError(fiber.StatusNotFound, err.Error())
} }

21
pkg/server/realms_api.go Normal file
View File

@ -0,0 +1,21 @@
package server
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"github.com/gofiber/fiber/v2"
)
func realmMiddleware(c *fiber.Ctx) error {
realmAlias := c.Params("realm")
if len(realmAlias) > 0 && realmAlias != "global" {
realm, err := services.GetRealmWithAlias(realmAlias)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("requested channel with realm, but realm was not found: %v", err))
} else {
c.Locals("realm", realm)
}
}
return c.Next()
}

View File

@ -75,7 +75,7 @@ func NewServer() {
api.Post("/attachments", authMiddleware, uploadAttachment) api.Post("/attachments", authMiddleware, uploadAttachment)
api.Delete("/attachments/:id", authMiddleware, deleteAttachment) api.Delete("/attachments/:id", authMiddleware, deleteAttachment)
channels := api.Group("/channels").Name("Channels API") channels := api.Group("/channels/:realm").Use(realmMiddleware).Name("Channels API")
{ {
channels.Get("/", listChannel) channels.Get("/", listChannel)
channels.Get("/:channel", getChannel) channels.Get("/:channel", getChannel)

View File

@ -27,11 +27,15 @@ func GetChannel(id uint) (models.Channel, error) {
return channel, nil return channel, nil
} }
func GetChannelWithAlias(alias string) (models.Channel, error) { func GetChannelWithAlias(alias string, realmId ...uint) (models.Channel, error) {
var channel models.Channel var channel models.Channel
if err := database.C.Where(models.Channel{ tx := database.C.Where(models.Channel{Alias: alias}).Preload("Account")
Alias: alias, if len(realmId) > 0 {
}).Preload("Account").First(&channel).Error; err != nil { tx = tx.Where("realm_id = ?", realmId)
} else {
tx = tx.Where("realm_id IS NULL")
}
if err := tx.First(&channel).Error; err != nil {
return channel, err return channel, err
} }
@ -74,9 +78,15 @@ func GetAvailableChannel(id uint, user models.Account) (models.Channel, models.C
return channel, member, nil return channel, member, nil
} }
func ListChannel() ([]models.Channel, error) { func ListChannel(realmId ...uint) ([]models.Channel, error) {
var channels []models.Channel var channels []models.Channel
if err := database.C.Preload("Account").Find(&channels).Error; err != nil { tx := database.C.Preload("Account")
if len(realmId) > 0 {
tx = tx.Where("realm_id = ?", realmId)
} else {
tx = tx.Where("realm_id IS NULL")
}
if err := tx.Find(&channels).Error; err != nil {
return channels, err return channels, err
} }
@ -112,7 +122,7 @@ func ListChannelIsAvailable(user models.Account) ([]models.Channel, error) {
return channels, nil return channels, nil
} }
func NewChannel(user models.Account, alias, name, description string) (models.Channel, error) { func NewChannel(user models.Account, alias, name, description string, realmId ...uint) (models.Channel, error) {
channel := models.Channel{ channel := models.Channel{
Alias: alias, Alias: alias,
Name: name, Name: name,
@ -122,6 +132,9 @@ func NewChannel(user models.Account, alias, name, description string) (models.Ch
{AccountID: user.ID}, {AccountID: user.ID},
}, },
} }
if len(realmId) > 0 {
channel.RealmID = &realmId[0]
}
err := database.C.Save(&channel).Error err := database.C.Save(&channel).Error