Feat: impl admin api

pull/21/head
zijiren233 2 years ago
parent aa6fa5411f
commit 94823a3d96

@ -37,6 +37,13 @@ func GetSettingItemValue(name string) (string, error) {
return value, err return value, err
} }
func SetSettingItemValue(name, value string) error { func FirstOrCreateSettingItemValue(s *model.Setting) error {
return db.Model(&model.Setting{}).Where("name = ?", name).Assign("value", value).FirstOrCreate(&model.Setting{}).Error return db.Where("name = ?", s.Name).Attrs(model.Setting{
Value: s.Value,
Type: s.Type,
}).FirstOrCreate(s).Error
}
func UpdateSettingItemValue(name, value string) error {
return db.Model(&model.Setting{}).Where("name = ?", name).Update("value", value).Error
} }

@ -11,20 +11,26 @@ func Init(size int) error {
LRU(). LRU().
Build() Build()
si, err := db.GetSettingItems() err := initSettings(ToSettings(BoolSettings)...)
if err != nil { if err != nil {
panic(err) return err
} }
for _, si2 := range si {
switch si2.Type { return nil
case model.SettingTypeBool: }
b, ok := boolSettings[si2.Name]
if ok { func initSettings(i ...Setting) error {
b.value = si2.Value for _, b := range i {
} s := &model.Setting{
Name: b.Name(),
Value: b.Raw(),
Type: model.SettingTypeBool,
}
err := db.FirstOrCreateSettingItemValue(s)
if err != nil {
return err
} }
b.SetRaw(s.Value)
} }
cleanReg()
return nil return nil
} }

@ -5,17 +5,26 @@ import (
"github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/model"
) )
var boolSettings map[string]*Bool var BoolSettings map[string]BoolSetting
type Setting interface { type Setting interface {
Name() string Name() string
SetRaw(string)
Raw() string Raw() string
Type() model.SettingType Type() model.SettingType
} }
func ToSettings[s Setting](settings map[string]s) []Setting {
var ss []Setting
for _, v := range settings {
ss = append(ss, v)
}
return ss
}
type BoolSetting interface { type BoolSetting interface {
Setting Setting
Set(value bool) error Set(bool) error
Get() (bool, error) Get() (bool, error)
} }
@ -35,13 +44,26 @@ func (b *Bool) Name() string {
return b.name return b.name
} }
func (b *Bool) SetRaw(s string) {
if b.value == s {
return
}
b.value = s
}
func (b *Bool) Set(value bool) error { func (b *Bool) Set(value bool) error {
if value { if value {
if b.value == "1" {
return nil
}
b.value = "1" b.value = "1"
} else { } else {
if b.value == "0" {
return nil
}
b.value = "0" b.value = "0"
} }
return db.SetSettingItemValue(b.name, b.value) return db.UpdateSettingItemValue(b.name, b.value)
} }
func (b *Bool) Get() (bool, error) { func (b *Bool) Get() (bool, error) {
@ -57,36 +79,40 @@ func (b *Bool) Type() model.SettingType {
} }
type Int64Setting interface { type Int64Setting interface {
Set(value int64) error Set(int64) error
Get() (int64, error) Get() (int64, error)
Raw() string Raw() string
} }
type Float64Setting interface { type Float64Setting interface {
Set(value float64) error Set(float64) error
Get() (float64, error) Get() (float64, error)
Raw() string Raw() string
} }
type StringSetting interface { type StringSetting interface {
Set(value string) error Set(string) error
Get() (string, error) Get() (string, error)
Raw() string Raw() string
} }
func cleanReg() {
boolSettings = nil
}
func newRegBoolSetting(k, v string) BoolSetting { func newRegBoolSetting(k, v string) BoolSetting {
b := NewBool(k, v) b := NewBool(k, v)
if boolSettings == nil { if BoolSettings == nil {
boolSettings = make(map[string]*Bool) BoolSettings = make(map[string]BoolSetting)
} }
boolSettings[k] = b BoolSettings[k] = b
return b return b
} }
func GetSettingType(name string) (model.SettingType, bool) {
s, ok := BoolSettings[name]
if !ok {
return "", false
}
return s.Type(), true
}
var ( var (
DisableCreateRoom = newRegBoolSetting("disable_create_room", "0") DisableCreateRoom = newRegBoolSetting("disable_create_room", "0")
) )

@ -1,7 +1,33 @@
package handlers package handlers
import "github.com/gin-gonic/gin" import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op"
"github.com/synctv-org/synctv/server/model"
)
func AdminSettings(ctx *gin.Context) { func AdminSettings(ctx *gin.Context) {
// user := ctx.MustGet("user").(*op.User)
req := model.AdminSettingsReq{}
if err := req.Decode(ctx); err != nil {
ctx.AbortWithError(http.StatusBadRequest, err)
return
}
for k, v := range req {
t, ok := op.GetSettingType(k)
if !ok {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp(fmt.Sprintf("setting %s not found", k)))
return
}
switch t {
case dbModel.SettingTypeBool:
op.BoolSettings[k].Set(v == "1")
}
}
} }

@ -38,8 +38,10 @@ func Init(e *gin.Engine) {
} }
{ {
// TODO: admin api implement admin := api.Group("/admin")
// admin := api.Group("/admin") admin.Use(middlewares.AuthAdminMiddleware)
admin.POST("/settings", AdminSettings)
} }
{ {

@ -2,6 +2,7 @@ package middlewares
import ( import (
"errors" "errors"
"net/http"
"strings" "strings"
"time" "time"
@ -111,6 +112,17 @@ func AuthUser(Authorization string) (*op.User, error) {
return u, nil return u, nil
} }
func AuthAdmin(Authorization string) (*op.User, error) {
u, err := AuthUser(Authorization)
if err != nil {
return nil, err
}
if !u.IsAdmin() {
return nil, errors.New("user is not admin")
}
return u, nil
}
func NewAuthUserToken(user *op.User) (string, error) { func NewAuthUserToken(user *op.User) (string, error) {
if user.IsBanned() { if user.IsBanned() {
return "", errors.New("user banned") return "", errors.New("user banned")
@ -154,7 +166,7 @@ func NewAuthRoomToken(user *op.User, room *op.Room) (string, error) {
func AuthRoomMiddleware(ctx *gin.Context) { func AuthRoomMiddleware(ctx *gin.Context) {
user, room, err := AuthRoom(ctx.GetHeader("Authorization")) user, room, err := AuthRoom(ctx.GetHeader("Authorization"))
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(401, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.NewApiErrorResp(err))
return return
} }
@ -166,7 +178,18 @@ func AuthRoomMiddleware(ctx *gin.Context) {
func AuthUserMiddleware(ctx *gin.Context) { func AuthUserMiddleware(ctx *gin.Context) {
user, err := AuthUser(ctx.GetHeader("Authorization")) user, err := AuthUser(ctx.GetHeader("Authorization"))
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(401, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.NewApiErrorResp(err))
return
}
ctx.Set("user", user)
ctx.Next()
}
func AuthAdminMiddleware(ctx *gin.Context) {
user, err := AuthAdmin(ctx.GetHeader("Authorization"))
if err != nil {
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorResp(err))
return return
} }

@ -0,0 +1,16 @@
package model
import (
"github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
)
type AdminSettingsReq map[string]string
func (asr *AdminSettingsReq) Validate() error {
return nil
}
func (asr *AdminSettingsReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(asr)
}
Loading…
Cancel
Save