Passport/pkg/internal/services/realms.go

167 lines
4.2 KiB
Go

package services
import (
"errors"
"fmt"
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
"github.com/samber/lo"
"gorm.io/gorm"
"strconv"
)
func ListCommunityRealm() ([]models.Realm, error) {
var realms []models.Realm
if err := database.C.Where(&models.Realm{
IsCommunity: true,
}).Find(&realms).Error; err != nil {
return realms, err
}
return realms, nil
}
func ListOwnedRealm(user models.Account) ([]models.Realm, error) {
var realms []models.Realm
if err := database.C.Where(&models.Realm{AccountID: user.ID}).Find(&realms).Error; err != nil {
return realms, err
}
return realms, nil
}
func ListAvailableRealm(user models.Account) ([]models.Realm, error) {
var realms []models.Realm
var members []models.RealmMember
if err := database.C.Where(&models.RealmMember{
AccountID: user.ID,
}).Find(&members).Error; err != nil {
return realms, err
}
idx := lo.Map(members, func(item models.RealmMember, index int) uint {
return item.RealmID
})
if err := database.C.Where("id IN ?", idx).Find(&realms).Error; err != nil {
return realms, err
}
return realms, nil
}
func GetRealmWithAlias(alias string) (models.Realm, error) {
tx := database.C.Where("alias = ?", alias)
numericId, err := strconv.Atoi(alias)
if err == nil {
tx.Or("id = ?", numericId)
}
var realm models.Realm
if err := tx.First(&realm).Error; err != nil {
return realm, err
}
return realm, nil
}
func NewRealm(realm models.Realm, user models.Account) (models.Realm, error) {
realm.Members = []models.RealmMember{
{AccountID: user.ID, PowerLevel: 100},
}
err := database.C.Save(&realm).Error
return realm, err
}
func CountRealmMember(realmId uint) (int64, error) {
var count int64
if err := database.C.Where(&models.RealmMember{
RealmID: realmId,
}).Model(&models.RealmMember{}).Count(&count).Error; err != nil {
return 0, err
} else {
return count, nil
}
}
func ListRealmMember(realmId uint, take int, offset int) ([]models.RealmMember, error) {
var members []models.RealmMember
if err := database.C.
Limit(take).Offset(offset).
Where(&models.RealmMember{RealmID: realmId}).
Preload("Account").
Find(&members).Error; err != nil {
return members, err
}
return members, nil
}
func GetRealmMember(userId uint, realmId uint) (models.RealmMember, error) {
var member models.RealmMember
if err := database.C.Where(&models.RealmMember{
AccountID: userId,
RealmID: realmId,
}).Find(&member).Error; err != nil {
return member, err
}
return member, nil
}
func AddRealmMember(user models.Account, affected models.Account, target models.Realm) error {
var member models.RealmMember
if err := database.C.Where(&models.RealmMember{
AccountID: affected.ID,
RealmID: target.ID,
}).First(&member).Error; err == nil || !errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("the user is already in the realm")
}
if !target.IsPublic && !target.IsCommunity {
if member, err := GetRealmMember(user.ID, target.ID); err != nil {
return fmt.Errorf("only realm member can add people: %v", err)
} else if member.PowerLevel < 50 {
return fmt.Errorf("only realm moderator can add member")
}
rel, err := GetRelationWithTwoNode(affected.ID, user.ID)
if err != nil || HasPermNodeWithDefault(
rel.PermNodes,
"RealmAdd",
true,
rel.Status == models.RelationshipFriend,
) {
return fmt.Errorf("you unable to add this user to your realm")
}
}
member = models.RealmMember{
RealmID: target.ID,
AccountID: affected.ID,
}
err := database.C.Save(&member).Error
return err
}
func RemoveRealmMember(user models.Account, affected models.RealmMember, target models.Realm) error {
if user.ID != affected.AccountID {
if member, err := GetRealmMember(user.ID, target.ID); err != nil {
return fmt.Errorf("only realm member can remove other member: %v", err)
} else if member.PowerLevel < 50 {
return fmt.Errorf("only realm moderator can kick member")
}
}
return database.C.Delete(&affected).Error
}
func EditRealm(realm models.Realm) (models.Realm, error) {
err := database.C.Save(&realm).Error
return realm, err
}
func DeleteRealm(realm models.Realm) error {
return database.C.Delete(&realm).Error
}