Feat: user max room count

This commit is contained in:
zijiren233 2023-11-12 22:28:04 +08:00
parent 465c45cffd
commit 5de12cfae5
7 changed files with 55 additions and 66 deletions

View File

@ -42,27 +42,41 @@ func WithStatus(status model.RoomStatus) CreateRoomConfig {
}
}
func CreateRoom(name, password string, conf ...CreateRoomConfig) (*model.Room, error) {
var hashedPassword []byte
if password != "" {
var err error
hashedPassword, err = bcrypt.GenerateFromPassword(stream.StringToBytes(password), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
}
// if maxCount is 0, it will be ignored
func CreateRoom(name, password string, maxCount int64, conf ...CreateRoomConfig) (*model.Room, error) {
r := &model.Room{
Name: name,
HashedPassword: hashedPassword,
Name: name,
}
for _, c := range conf {
c(r)
}
err := db.Create(r).Error
if err != nil && errors.Is(err, gorm.ErrDuplicatedKey) {
return r, errors.New("room already exists")
if password != "" {
var err error
r.HashedPassword, err = bcrypt.GenerateFromPassword(stream.StringToBytes(password), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
}
return r, err
tx := db.Begin()
if maxCount != 0 {
var count int64
tx.Model(&model.Room{}).Where("creator_id = ?", r.CreatorID).Count(&count)
if count >= maxCount {
tx.Rollback()
return nil, errors.New("room count is over limit")
}
}
err := tx.Create(r).Error
if err != nil {
tx.Rollback()
if errors.Is(err, gorm.ErrDuplicatedKey) {
return r, errors.New("room already exists")
}
return r, err
}
tx.Commit()
return r, nil
}
func GetRoomByID(id string) (*model.Room, error) {

View File

@ -14,8 +14,8 @@ import (
var roomCache *synccache.SyncCache[string, *Room]
func CreateRoom(name, password string, conf ...db.CreateRoomConfig) (*Room, error) {
r, err := db.CreateRoom(name, password, conf...)
func CreateRoom(name, password string, maxCount int64, conf ...db.CreateRoomConfig) (*Room, error) {
r, err := db.CreateRoom(name, password, maxCount, conf...)
if err != nil {
return nil, err
}

View File

@ -12,7 +12,7 @@ type User struct {
model.User
}
func (u *User) CreateRoom(name, password string, conf ...db.CreateRoomConfig) (*model.Room, error) {
func (u *User) CreateRoom(name, password string, conf ...db.CreateRoomConfig) (*Room, error) {
if u.IsBanned() {
return nil, errors.New("user banned")
}
@ -28,7 +28,13 @@ func (u *User) CreateRoom(name, password string, conf ...db.CreateRoomConfig) (*
conf = append(conf, db.WithStatus(model.RoomStatusActive))
}
}
return db.CreateRoom(name, password, append(conf, db.WithCreator(&u.User))...)
var maxCount int64
if !u.IsAdmin() {
maxCount = settings.UserMaxRoomCount.Get()
}
return CreateRoom(name, password, maxCount, append(conf, db.WithCreator(&u.User))...)
}
func (u *User) NewMovie(movie *model.BaseMovie) *model.Movie {

View File

@ -29,8 +29,9 @@ type Int64 struct {
func NewInt64(name string, value int64, group model.SettingGroup) *Int64 {
i := &Int64{
setting: setting{
name: name,
group: group,
name: name,
group: group,
settingType: model.SettingTypeInt64,
},
defaultValue: value,
value: value,

View File

@ -3,6 +3,7 @@ package settings
import (
"fmt"
json "github.com/json-iterator/go"
log "github.com/sirupsen/logrus"
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model"
@ -34,49 +35,17 @@ func SetValue(name string, value any) error {
}
func SetSettingValue(s Setting, value any) error {
switch s.Type() {
case model.SettingTypeBool:
i, ok := s.(BoolSetting)
if !ok {
log.Fatalf("setting %s is not bool", s.Name())
}
v, ok := value.(bool)
if !ok {
return fmt.Errorf("setting %s, value %v is not bool", s.Name(), value)
}
i.Set(v)
case model.SettingTypeInt64:
i, ok := s.(Int64Setting)
if !ok {
log.Fatalf("setting %s is not int64", s.Name())
}
v, ok := value.(int64)
if !ok {
return fmt.Errorf("setting %s, value %v is not int64", s.Name(), value)
}
i.Set(v)
case model.SettingTypeFloat64:
i, ok := s.(Float64Setting)
if !ok {
log.Fatalf("setting %s is not float64", s.Name())
}
v, ok := value.(float64)
if !ok {
return fmt.Errorf("setting %s, value %v is not float64", s.Name(), value)
}
i.Set(v)
case model.SettingTypeString:
i, ok := s.(StringSetting)
if !ok {
log.Fatalf("setting %s is not string", s.Name())
}
v, ok := value.(string)
if !ok {
return fmt.Errorf("setting %s, value %v is not string", s.Name(), value)
}
i.Set(v)
switch s := s.(type) {
case BoolSetting:
return s.Set(json.Wrap(value).ToBool())
case Int64Setting:
return s.Set(json.Wrap(value).ToInt64())
case Float64Setting:
return s.Set(json.Wrap(value).ToFloat64())
case StringSetting:
return s.Set(json.Wrap(value).ToString())
default:
log.Fatalf("unknown setting type: %s", s.Type())
log.Fatalf("unknown setting %s type: %s", s.Name(), s.Type())
}
return nil
}

View File

@ -11,6 +11,7 @@ var (
RoomMustNeedPwd = newBoolSetting("room_must_need_pwd", false, model.SettingGroupRoom)
CreateRoomNeedReview = newBoolSetting("create_room_need_review", false, model.SettingGroupRoom)
RoomTTL = newInt64Setting("room_ttl", int64(time.Hour*48), model.SettingGroupRoom)
UserMaxRoomCount = newInt64Setting("user_max_room_count", 3, model.SettingGroupRoom)
)
var (

View File

@ -44,14 +44,12 @@ func CreateRoom(ctx *gin.Context) {
return
}
r, err := user.CreateRoom(req.RoomName, req.Password, db.WithSetting(req.Setting))
room, err := user.CreateRoom(req.RoomName, req.Password, db.WithSetting(req.Setting))
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
room, _ := op.LoadOrInitRoomByID(r.ID)
token, err := middlewares.NewAuthRoomToken(user, room)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))