mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-04 04:30:05 +00:00
refactor: simplify server & service manipulation (#993)
* refactor: simplify server & service manipulation * update * fix * update for nat, ddns & notification * chore * update cron * update dependencies * use of function iterators * update default dns servers
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"maps"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -168,16 +169,9 @@ func batchDeleteAlertRule(c *gin.Context) (any, error) {
|
||||
func validateRule(c *gin.Context, r *model.AlertRule) error {
|
||||
if len(r.Rules) > 0 {
|
||||
for _, rule := range r.Rules {
|
||||
singleton.ServerLock.RLock()
|
||||
for s := range rule.Ignore {
|
||||
if server, ok := singleton.ServerList[s]; ok {
|
||||
if !server.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServerShared.CheckPermission(c, maps.Keys(rule.Ignore)) {
|
||||
return singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
if !rule.IsTransferDurationRule() {
|
||||
if rule.Duration < 3 {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -21,11 +22,10 @@ import (
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Cron]
|
||||
// @Router /cron [get]
|
||||
func listCron(c *gin.Context) ([]*model.Cron, error) {
|
||||
singleton.CronLock.RLock()
|
||||
defer singleton.CronLock.RUnlock()
|
||||
slist := singleton.CronShared.GetSortedList()
|
||||
|
||||
var cr []*model.Cron
|
||||
if err := copier.Copy(&cr, &singleton.CronList); err != nil {
|
||||
if err := copier.Copy(&cr, &slist); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cr, nil
|
||||
@@ -50,16 +50,9 @@ func createCron(c *gin.Context) (uint64, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
for _, sid := range cf.Servers {
|
||||
if server, ok := singleton.ServerList[sid]; ok {
|
||||
if !server.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServerShared.CheckPermission(c, slices.Values(cf.Servers)) {
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
cr.UserID = getUid(c)
|
||||
cr.TaskType = cf.TaskType
|
||||
@@ -78,7 +71,7 @@ func createCron(c *gin.Context) (uint64, error) {
|
||||
// 对于计划任务类型,需要更新CronJob
|
||||
var err error
|
||||
if cf.TaskType == model.CronTypeCronTask {
|
||||
if cr.CronJobID, err = singleton.Cron.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
|
||||
if cr.CronJobID, err = singleton.CronShared.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
@@ -87,8 +80,7 @@ func createCron(c *gin.Context) (uint64, error) {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddCron(&cr)
|
||||
singleton.UpdateCronList()
|
||||
singleton.CronShared.Update(&cr)
|
||||
return cr.ID, nil
|
||||
}
|
||||
|
||||
@@ -116,16 +108,9 @@ func updateCron(c *gin.Context) (any, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
for _, sid := range cf.Servers {
|
||||
if server, ok := singleton.ServerList[sid]; ok {
|
||||
if !server.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServerShared.CheckPermission(c, slices.Values(cf.Servers)) {
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
var cr model.Cron
|
||||
if err := singleton.DB.First(&cr, id).Error; err != nil {
|
||||
@@ -151,7 +136,7 @@ func updateCron(c *gin.Context) (any, error) {
|
||||
|
||||
// 对于计划任务类型,需要更新CronJob
|
||||
if cf.TaskType == model.CronTypeCronTask {
|
||||
if cr.CronJobID, err = singleton.Cron.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
|
||||
if cr.CronJobID, err = singleton.CronShared.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -160,8 +145,7 @@ func updateCron(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddCron(&cr)
|
||||
singleton.UpdateCronList()
|
||||
singleton.CronShared.Update(&cr)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -183,13 +167,10 @@ func manualTriggerCron(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.CronLock.RLock()
|
||||
cr, ok := singleton.Crons[id]
|
||||
cr, ok := singleton.CronShared.Get(id)
|
||||
if !ok {
|
||||
singleton.CronLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("task id %d does not exist", id)
|
||||
}
|
||||
singleton.CronLock.RUnlock()
|
||||
|
||||
if !cr.HasPermission(c) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
@@ -216,22 +197,14 @@ func batchDeleteCron(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.CronLock.RLock()
|
||||
for _, crID := range cr {
|
||||
if crn, ok := singleton.Crons[crID]; ok {
|
||||
if !crn.HasPermission(c) {
|
||||
singleton.CronLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.CronShared.CheckPermission(c, slices.Values(cr)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.CronLock.RUnlock()
|
||||
|
||||
if err := singleton.DB.Unscoped().Delete(&model.Cron{}, "id in (?)", cr).Error; err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDeleteCron(cr)
|
||||
singleton.UpdateCronList()
|
||||
singleton.CronShared.Delete(cr)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -24,10 +25,8 @@ import (
|
||||
func listDDNS(c *gin.Context) ([]*model.DDNSProfile, error) {
|
||||
var ddnsProfiles []*model.DDNSProfile
|
||||
|
||||
singleton.DDNSListLock.RLock()
|
||||
defer singleton.DDNSListLock.RUnlock()
|
||||
|
||||
if err := copier.Copy(&ddnsProfiles, &singleton.DDNSList); err != nil {
|
||||
list := singleton.DDNSShared.GetSortedList()
|
||||
if err := copier.Copy(&ddnsProfiles, &list); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -87,9 +86,7 @@ func createDDNS(c *gin.Context) (uint64, error) {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDDNSUpdate(&p)
|
||||
singleton.UpdateDDNSList()
|
||||
|
||||
singleton.DDNSShared.Update(&p)
|
||||
return p.ID, nil
|
||||
}
|
||||
|
||||
@@ -160,8 +157,7 @@ func updateDDNS(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDDNSUpdate(&p)
|
||||
singleton.UpdateDDNSList()
|
||||
singleton.DDNSShared.Update(&p)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -184,24 +180,15 @@ func batchDeleteDDNS(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.DDNSCacheLock.RLock()
|
||||
for _, pid := range ddnsConfigs {
|
||||
if p, ok := singleton.DDNSCache[pid]; ok {
|
||||
if !p.HasPermission(c) {
|
||||
singleton.DDNSCacheLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.DDNSShared.CheckPermission(c, slices.Values(ddnsConfigs)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.DDNSCacheLock.RUnlock()
|
||||
|
||||
if err := singleton.DB.Unscoped().Delete(&model.DDNSProfile{}, "id in (?)", ddnsConfigs).Error; err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDDNSDelete(ddnsConfigs)
|
||||
singleton.UpdateDDNSList()
|
||||
|
||||
singleton.DDNSShared.Delete(ddnsConfigs)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,7 @@ func createFM(c *gin.Context) (*model.CreateFMResponse, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
server := singleton.ServerList[id]
|
||||
singleton.ServerLock.RUnlock()
|
||||
server, _ := singleton.ServerShared.Get(id)
|
||||
if server == nil || server.TaskStream == nil {
|
||||
return nil, singleton.Localizer.ErrorT("server not found or not connected")
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/copier"
|
||||
|
||||
"github.com/nezhahq/nezha/model"
|
||||
"github.com/nezhahq/nezha/pkg/utils"
|
||||
"github.com/nezhahq/nezha/service/singleton"
|
||||
)
|
||||
|
||||
@@ -23,10 +25,9 @@ import (
|
||||
func listNAT(c *gin.Context) ([]*model.NAT, error) {
|
||||
var n []*model.NAT
|
||||
|
||||
singleton.NATListLock.RLock()
|
||||
defer singleton.NATListLock.RUnlock()
|
||||
slist := singleton.NATShared.GetSortedList()
|
||||
|
||||
if err := copier.Copy(&n, &singleton.NATList); err != nil {
|
||||
if err := copier.Copy(&n, &slist); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -52,14 +53,11 @@ func createNAT(c *gin.Context) (uint64, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
if server, ok := singleton.ServerList[nf.ServerID]; ok {
|
||||
if server, ok := singleton.ServerShared.Get(nf.ServerID); ok {
|
||||
if !server.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
uid := getUid(c)
|
||||
|
||||
@@ -74,8 +72,7 @@ func createNAT(c *gin.Context) (uint64, error) {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnNATUpdate(&n)
|
||||
singleton.UpdateNATList()
|
||||
singleton.NATShared.Update(&n)
|
||||
return n.ID, nil
|
||||
}
|
||||
|
||||
@@ -104,14 +101,11 @@ func updateNAT(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
if server, ok := singleton.ServerList[nf.ServerID]; ok {
|
||||
if server, ok := singleton.ServerShared.Get(nf.ServerID); ok {
|
||||
if !server.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
var n model.NAT
|
||||
if err = singleton.DB.First(&n, id).Error; err != nil {
|
||||
@@ -132,8 +126,7 @@ func updateNAT(c *gin.Context) (any, error) {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnNATUpdate(&n)
|
||||
singleton.UpdateNATList()
|
||||
singleton.NATShared.Update(&n)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -154,22 +147,17 @@ func batchDeleteNAT(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.NATCacheRwLock.RLock()
|
||||
for _, id := range n {
|
||||
if p, ok := singleton.NATCache[singleton.NATIDToDomain[id]]; ok {
|
||||
if !p.HasPermission(c) {
|
||||
singleton.NATCacheRwLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.NATShared.CheckPermission(c, utils.ConvertSeq(slices.Values(n),
|
||||
func(id uint64) string {
|
||||
return singleton.NATShared.GetDomain(id)
|
||||
})) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.NATCacheRwLock.RUnlock()
|
||||
|
||||
if err := singleton.DB.Unscoped().Delete(&model.NAT{}, "id in (?)", n).Error; err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnNATDelete(n)
|
||||
singleton.UpdateNATList()
|
||||
singleton.NATShared.Delete(n)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/copier"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/nezhahq/nezha/model"
|
||||
"github.com/nezhahq/nezha/service/singleton"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// List notification
|
||||
@@ -21,11 +23,10 @@ import (
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Notification]
|
||||
// @Router /notification [get]
|
||||
func listNotification(c *gin.Context) ([]*model.Notification, error) {
|
||||
singleton.NotificationSortedLock.RLock()
|
||||
defer singleton.NotificationSortedLock.RUnlock()
|
||||
slist := singleton.NotificationShared.GetSortedList()
|
||||
|
||||
var notifications []*model.Notification
|
||||
if err := copier.Copy(¬ifications, &singleton.NotificationListSorted); err != nil {
|
||||
if err := copier.Copy(¬ifications, &slist); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return notifications, nil
|
||||
@@ -75,8 +76,7 @@ func createNotification(c *gin.Context) (uint64, error) {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotification(&n)
|
||||
singleton.UpdateNotificationList()
|
||||
singleton.NotificationShared.Update(&n)
|
||||
return n.ID, nil
|
||||
}
|
||||
|
||||
@@ -137,8 +137,7 @@ func updateNotification(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotification(&n)
|
||||
singleton.UpdateNotificationList()
|
||||
singleton.NotificationShared.Update(&n)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -159,16 +158,9 @@ func batchDeleteNotification(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.NotificationsLock.RLock()
|
||||
for _, nid := range n {
|
||||
if ns, ok := singleton.NotificationMap[nid]; ok {
|
||||
if !ns.HasPermission(c) {
|
||||
singleton.NotificationsLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.NotificationShared.CheckPermission(c, slices.Values(n)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.NotificationsLock.RUnlock()
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Unscoped().Delete(&model.Notification{}, "id in (?)", n).Error; err != nil {
|
||||
@@ -184,7 +176,6 @@ func batchDeleteNotification(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDeleteNotification(n)
|
||||
singleton.UpdateNotificationList()
|
||||
singleton.NotificationShared.Delete(n)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -68,16 +68,9 @@ func createNotificationGroup(c *gin.Context) (uint64, error) {
|
||||
}
|
||||
ngf.Notifications = slices.Compact(ngf.Notifications)
|
||||
|
||||
singleton.NotificationsLock.RLock()
|
||||
for _, nid := range ngf.Notifications {
|
||||
if n, ok := singleton.NotificationMap[nid]; ok {
|
||||
if !n.HasPermission(c) {
|
||||
singleton.NotificationsLock.RUnlock()
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.NotificationShared.CheckPermission(c, slices.Values(ngf.Notifications)) {
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.NotificationsLock.RUnlock()
|
||||
|
||||
uid := getUid(c)
|
||||
|
||||
@@ -115,7 +108,7 @@ func createNotificationGroup(c *gin.Context) (uint64, error) {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotificationGroup(&ng, ngf.Notifications)
|
||||
singleton.NotificationShared.UpdateGroup(&ng, ngf.Notifications)
|
||||
return ng.ID, nil
|
||||
}
|
||||
|
||||
@@ -144,16 +137,9 @@ func updateNotificationGroup(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.NotificationsLock.RLock()
|
||||
for _, nid := range ngf.Notifications {
|
||||
if n, ok := singleton.NotificationMap[nid]; ok {
|
||||
if !n.HasPermission(c) {
|
||||
singleton.NotificationsLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.NotificationShared.CheckPermission(c, slices.Values(ngf.Notifications)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.NotificationsLock.RUnlock()
|
||||
|
||||
var ngDB model.NotificationGroup
|
||||
if err := singleton.DB.First(&ngDB, id).Error; err != nil {
|
||||
@@ -202,7 +188,7 @@ func updateNotificationGroup(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotificationGroup(&ngDB, ngf.Notifications)
|
||||
singleton.NotificationShared.UpdateGroup(&ngDB, ngf.Notifications)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -248,6 +234,6 @@ func batchDeleteNotificationGroup(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDeleteNotificationGroup(ngn)
|
||||
singleton.NotificationShared.DeleteGroup(ngn)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -26,11 +27,10 @@ import (
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Server]
|
||||
// @Router /server [get]
|
||||
func listServer(c *gin.Context) ([]*model.Server, error) {
|
||||
singleton.SortedServerLock.RLock()
|
||||
defer singleton.SortedServerLock.RUnlock()
|
||||
slist := singleton.ServerShared.GetSortedList()
|
||||
|
||||
var ssl []*model.Server
|
||||
if err := copier.Copy(&ssl, &singleton.SortedServerList); err != nil {
|
||||
if err := copier.Copy(&ssl, &slist); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ssl, nil
|
||||
@@ -59,16 +59,9 @@ func updateServer(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.DDNSCacheLock.RLock()
|
||||
for _, pid := range sf.DDNSProfiles {
|
||||
if p, ok := singleton.DDNSCache[pid]; ok {
|
||||
if !p.HasPermission(c) {
|
||||
singleton.DDNSCacheLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.DDNSShared.CheckPermission(c, slices.Values(sf.DDNSProfiles)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.DDNSCacheLock.RUnlock()
|
||||
|
||||
var s model.Server
|
||||
if err := singleton.DB.First(&s, id).Error; err != nil {
|
||||
@@ -104,11 +97,9 @@ func updateServer(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.ServerLock.Lock()
|
||||
s.CopyFromRunningServer(singleton.ServerList[s.ID])
|
||||
singleton.ServerList[s.ID] = &s
|
||||
singleton.ServerLock.Unlock()
|
||||
singleton.ReSortServer()
|
||||
rs, _ := singleton.ServerShared.Get(s.ID)
|
||||
s.CopyFromRunningServer(rs)
|
||||
singleton.ServerShared.Update(&s, "")
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -130,16 +121,9 @@ func batchDeleteServer(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
for _, sid := range servers {
|
||||
if s, ok := singleton.ServerList[sid]; ok {
|
||||
if !s.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServerShared.CheckPermission(c, slices.Values(servers)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Unscoped().Delete(&model.Server{}, "id in (?)", servers).Error; err != nil {
|
||||
@@ -168,9 +152,7 @@ func batchDeleteServer(c *gin.Context) (any, error) {
|
||||
singleton.DB.Unscoped().Delete(&model.Transfer{}, "server_id in (?)", servers)
|
||||
singleton.AlertsLock.Unlock()
|
||||
|
||||
singleton.OnServerDelete(servers)
|
||||
singleton.ReSortServer()
|
||||
|
||||
singleton.ServerShared.Delete(servers)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -194,9 +176,7 @@ func forceUpdateServer(c *gin.Context) (*model.ServerTaskResponse, error) {
|
||||
forceUpdateResp := new(model.ServerTaskResponse)
|
||||
|
||||
for _, sid := range forceUpdateServers {
|
||||
singleton.ServerLock.RLock()
|
||||
server := singleton.ServerList[sid]
|
||||
singleton.ServerLock.RUnlock()
|
||||
server, _ := singleton.ServerShared.Get(sid)
|
||||
if server != nil && server.TaskStream != nil {
|
||||
if !server.HasPermission(c) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
@@ -232,13 +212,10 @@ func getServerConfig(c *gin.Context) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
s, ok := singleton.ServerList[id]
|
||||
s, ok := singleton.ServerShared.Get(id)
|
||||
if !ok || s.TaskStream == nil {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return "", nil
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
if !s.HasPermission(c) {
|
||||
return "", singleton.Localizer.ErrorT("permission denied")
|
||||
@@ -285,12 +262,11 @@ func setServerConfig(c *gin.Context) (*model.ServerTaskResponse, error) {
|
||||
}
|
||||
|
||||
var resp model.ServerTaskResponse
|
||||
singleton.ServerLock.RLock()
|
||||
slist := singleton.ServerShared.GetList()
|
||||
servers := make([]*model.Server, 0, len(configForm.Servers))
|
||||
for _, sid := range configForm.Servers {
|
||||
if s, ok := singleton.ServerList[sid]; ok {
|
||||
if s, ok := slist[sid]; ok {
|
||||
if !s.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
if s.TaskStream == nil {
|
||||
@@ -300,7 +276,6 @@ func setServerConfig(c *gin.Context) (*model.ServerTaskResponse, error) {
|
||||
servers = append(servers, s)
|
||||
}
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var respMu sync.Mutex
|
||||
|
||||
@@ -67,16 +67,9 @@ func createServerGroup(c *gin.Context) (uint64, error) {
|
||||
}
|
||||
sgf.Servers = slices.Compact(sgf.Servers)
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
for _, sid := range sgf.Servers {
|
||||
if server, ok := singleton.ServerList[sid]; ok {
|
||||
if !server.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServerShared.CheckPermission(c, slices.Values(sgf.Servers)) {
|
||||
return 0, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
uid := getUid(c)
|
||||
|
||||
@@ -142,16 +135,9 @@ func updateServerGroup(c *gin.Context) (any, error) {
|
||||
}
|
||||
sg.Servers = slices.Compact(sg.Servers)
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
for _, sid := range sg.Servers {
|
||||
if server, ok := singleton.ServerList[sid]; ok {
|
||||
if !server.HasPermission(c) {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServerShared.CheckPermission(c, slices.Values(sg.Servers)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
var sgDB model.ServerGroup
|
||||
if err := singleton.DB.First(&sgDB, id).Error; err != nil {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"maps"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -55,11 +57,9 @@ func showService(c *gin.Context) (*model.ServiceResponse, error) {
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Service]
|
||||
// @Router /service [get]
|
||||
func listService(c *gin.Context) ([]*model.Service, error) {
|
||||
singleton.ServiceSentinelShared.ServicesLock.RLock()
|
||||
defer singleton.ServiceSentinelShared.ServicesLock.RUnlock()
|
||||
|
||||
var ss []*model.Service
|
||||
if err := copier.Copy(&ss, singleton.ServiceSentinelShared.ServiceList); err != nil {
|
||||
ssl := singleton.ServiceSentinelShared.GetSortedList()
|
||||
if err := copier.Copy(&ss, &ssl); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -83,9 +83,8 @@ func listServiceHistory(c *gin.Context) ([]*model.ServiceInfos, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
server, ok := singleton.ServerList[id]
|
||||
singleton.ServerLock.RUnlock()
|
||||
m := singleton.ServerShared.GetList()
|
||||
server, ok := m[id]
|
||||
if !ok || server == nil {
|
||||
return nil, singleton.Localizer.ErrorT("server not found")
|
||||
}
|
||||
@@ -104,21 +103,17 @@ func listServiceHistory(c *gin.Context) ([]*model.ServiceInfos, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.ServiceSentinelShared.ServicesLock.RLock()
|
||||
defer singleton.ServiceSentinelShared.ServicesLock.RUnlock()
|
||||
singleton.ServerLock.RLock()
|
||||
defer singleton.ServerLock.RUnlock()
|
||||
|
||||
var sortedServiceIDs []uint64
|
||||
resultMap := make(map[uint64]*model.ServiceInfos)
|
||||
for _, history := range serviceHistories {
|
||||
infos, ok := resultMap[history.ServiceID]
|
||||
service, _ := singleton.ServiceSentinelShared.Get(history.ServiceID)
|
||||
if !ok {
|
||||
infos = &model.ServiceInfos{
|
||||
ServiceID: history.ServiceID,
|
||||
ServerID: history.ServerID,
|
||||
ServiceName: singleton.ServiceSentinelShared.Services[history.ServiceID].Name,
|
||||
ServerName: singleton.ServerList[history.ServerID].Name,
|
||||
ServiceName: service.Name,
|
||||
ServerName: m[history.ServerID].Name,
|
||||
}
|
||||
resultMap[history.ServiceID] = infos
|
||||
sortedServiceIDs = append(sortedServiceIDs, history.ServiceID)
|
||||
@@ -158,9 +153,7 @@ func listServerWithServices(c *gin.Context) ([]uint64, error) {
|
||||
|
||||
var ret []uint64
|
||||
for _, id := range serverIdsWithService {
|
||||
singleton.ServerLock.RLock()
|
||||
server, ok := singleton.ServerList[id]
|
||||
singleton.ServerLock.RUnlock()
|
||||
server, ok := singleton.ServerShared.Get(id)
|
||||
if !ok || server == nil {
|
||||
return nil, singleton.Localizer.ErrorT("server not found")
|
||||
}
|
||||
@@ -232,7 +225,7 @@ func createService(c *gin.Context) (uint64, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := singleton.ServiceSentinelShared.OnServiceUpdate(m); err != nil {
|
||||
if err := singleton.ServiceSentinelShared.Update(&m); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -309,7 +302,7 @@ func updateService(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := singleton.ServiceSentinelShared.OnServiceUpdate(m); err != nil {
|
||||
if err := singleton.ServiceSentinelShared.Update(&m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -334,16 +327,9 @@ func batchDeleteService(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.ServiceSentinelShared.ServicesLock.RLock()
|
||||
for _, id := range ids {
|
||||
if ss, ok := singleton.ServiceSentinelShared.Services[id]; ok {
|
||||
if !ss.HasPermission(c) {
|
||||
singleton.ServiceSentinelShared.ServicesLock.RUnlock()
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServiceSentinelShared.CheckPermission(c, slices.Values(ids)) {
|
||||
return nil, singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
singleton.ServiceSentinelShared.ServicesLock.RUnlock()
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Unscoped().Delete(&model.Service{}, "id in (?)", ids).Error; err != nil {
|
||||
@@ -354,21 +340,14 @@ func batchDeleteService(c *gin.Context) (any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
singleton.ServiceSentinelShared.OnServiceDelete(ids)
|
||||
singleton.ServiceSentinelShared.Delete(ids)
|
||||
singleton.ServiceSentinelShared.UpdateServiceList()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func validateServers(c *gin.Context, ss *model.Service) error {
|
||||
singleton.ServerLock.RLock()
|
||||
defer singleton.ServerLock.RUnlock()
|
||||
|
||||
for s := range ss.SkipServers {
|
||||
if server, ok := singleton.ServerList[s]; ok {
|
||||
if !server.HasPermission(c) {
|
||||
return singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
}
|
||||
if !singleton.ServerShared.CheckPermission(c, maps.Keys(ss.SkipServers)) {
|
||||
return singleton.Localizer.ErrorT("permission denied")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -30,9 +30,7 @@ func createTerminal(c *gin.Context) (*model.CreateTerminalResponse, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
server := singleton.ServerList[createTerminalReq.ServerID]
|
||||
singleton.ServerLock.RUnlock()
|
||||
server, _ := singleton.ServerShared.Get(createTerminalReq.ServerID)
|
||||
if server == nil || server.TaskStream == nil {
|
||||
return nil, singleton.Localizer.ErrorT("server not found or not connected")
|
||||
}
|
||||
|
||||
@@ -158,14 +158,11 @@ var requestGroup singleflight.Group
|
||||
|
||||
func getServerStat(withPublicNote, authorized bool) ([]byte, error) {
|
||||
v, err, _ := requestGroup.Do(fmt.Sprintf("serverStats::%t", authorized), func() (interface{}, error) {
|
||||
singleton.SortedServerLock.RLock()
|
||||
defer singleton.SortedServerLock.RUnlock()
|
||||
|
||||
var serverList []*model.Server
|
||||
if authorized {
|
||||
serverList = singleton.SortedServerList
|
||||
serverList = singleton.ServerShared.GetSortedList()
|
||||
} else {
|
||||
serverList = singleton.SortedServerListForGuest
|
||||
serverList = singleton.ServerShared.GetSortedListForGuest()
|
||||
}
|
||||
|
||||
servers := make([]model.StreamServer, 0, len(serverList))
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestWs(t *testing.T) {
|
||||
onlineUsers := new(atomic.Uint64)
|
||||
onlineUsers.Add(1)
|
||||
if onlineUsers.Load() != 1 {
|
||||
t.Error("onlineUsers.Add(1) failed")
|
||||
}
|
||||
onlineUsers.Add(1)
|
||||
if onlineUsers.Load() != 2 {
|
||||
t.Error("onlineUsers.Add(1) failed")
|
||||
}
|
||||
onlineUsers.Add(^uint64(0))
|
||||
if onlineUsers.Load() != 1 {
|
||||
t.Error("onlineUsers.Add(^uint64(0)) failed")
|
||||
}
|
||||
onlineUsers.Add(^uint64(0))
|
||||
if onlineUsers.Load() != 0 {
|
||||
t.Error("onlineUsers.Add(^uint64(0)) failed")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user