Files
apinto/drivers/app/manager/manager.go
2025-05-14 17:31:09 +08:00

165 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package manager
import (
"strings"
"sync"
"github.com/eolinker/apinto/application"
"github.com/eolinker/eosc"
)
// 管理器可以通过driver快速获取驱动列表
var _ IManager = (*Manager)(nil)
type IManager interface {
Get(id string) (application.IAuth, bool)
GetApp(appId string) (application.IApp, bool)
List() []application.IAuthUser
ListByDriver(driver string) []application.IAuthUser
Set(app application.IApp, filters []application.IAuth, users map[string][]application.ITransformConfig)
Del(appID string)
Count() int
AnonymousApp() application.IApp
SetAnonymousApp(app application.IApp)
}
type Manager struct {
// filters map[string]application.IAuthUser
eosc.Untyped[string, application.IAuth]
apps eosc.Untyped[string, application.IApp]
appManager *AppManager
driverAlias map[string]string
drivers []string
locker sync.RWMutex
app application.IApp
}
func (m *Manager) GetApp(appId string) (application.IApp, bool) {
if !strings.HasSuffix(appId, "@app") {
appId = appId + "@app"
}
return m.apps.Get(appId)
}
func (m *Manager) AnonymousApp() application.IApp {
m.locker.RLock()
app := m.app
m.locker.RUnlock()
return app
}
func (m *Manager) SetAnonymousApp(app application.IApp) {
m.locker.Lock()
m.app = app
m.locker.Unlock()
}
func NewManager(driverAlias map[string]string, drivers []string) IManager {
return &Manager{Untyped: eosc.BuildUntyped[string, application.IAuth](), appManager: NewAppManager(), driverAlias: driverAlias, drivers: drivers, apps: eosc.BuildUntyped[string, application.IApp]()}
}
func (m *Manager) List() []application.IAuthUser {
filters := make([]application.IAuthUser, 0, len(m.drivers)*5)
for _, driver := range m.drivers {
filters = append(filters, m.getByDriver(driver)...)
}
return filters
}
func (m *Manager) ListByDriver(driver string) []application.IAuthUser {
tmp := driver
if v, ok := m.driverAlias[strings.ToLower(driver)]; ok {
tmp = v
}
return m.getByDriver(tmp)
}
func (m *Manager) getByDriver(driver string) []application.IAuthUser {
ids := m.appManager.GetByDriver(driver)
filters := make([]application.IAuthUser, 0, len(ids))
for _, id := range ids {
filter, has := m.Get(id)
if has {
filters = append(filters, filter)
}
}
return filters
}
func (m *Manager) all() []application.IAuthUser {
list := m.List()
filters := make([]application.IAuthUser, 0, len(list))
filters = append(filters, list...)
return filters
}
func (m *Manager) Set(app application.IApp, filters []application.IAuth, users map[string][]application.ITransformConfig) {
idMap := make(map[string][]string)
for _, filter := range filters {
f, has := m.Untyped.Get(filter.ID())
if !has {
f = filter
}
v, ok := users[f.ID()]
if !ok {
continue
}
f.Set(app, v)
m.Untyped.Set(filter.ID(), filter)
if _, ok := idMap[filter.Driver()]; !ok {
idMap[filter.Driver()] = make([]string, 0, len(filters))
}
idMap[filter.Driver()] = append(idMap[filter.Driver()], filter.ID())
}
idArr := make([]string, 0, len(idMap))
for driver, ids := range idMap {
m.appManager.Set(app.Id(), driver, ids)
idArr = append(idArr, ids...)
}
// 比较新旧id删除旧配置
old := m.appManager.GetByAppID(app.Id())
cs := compareArray(old, idArr)
for id := range cs {
filter, has := m.Untyped.Get(id)
if has {
filter.Del(app.Id())
if filter.UserCount() == 0 {
m.Untyped.Del(id)
}
}
}
m.apps.Set(app.Id(), app)
return
}
func compareArray[T comparable](o, n []T) map[T]struct{} {
m := make(map[T]struct{})
for _, i := range o {
m[i] = struct{}{}
}
for _, i := range n {
if _, ok := m[i]; ok {
delete(m, i)
}
}
return m
}
func (m *Manager) Del(appID string) {
ids := m.appManager.GetByAppID(appID)
for _, id := range ids {
filter, has := m.Untyped.Get(id)
if has {
filter.Del(appID)
if filter.UserCount() == 0 {
m.Untyped.Del(id)
}
}
}
m.appManager.DelByAppID(appID)
m.apps.Del(appID)
}