flag를 내재화함

This commit is contained in:
2023-06-20 11:07:53 +09:00
parent 09328575ad
commit 140da79f7f
8 changed files with 120 additions and 392 deletions

View File

@ -14,13 +14,13 @@ import (
"net/http"
"os"
"strings"
"sync"
"sync/atomic"
"time"
"unsafe"
common "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger"
"repositories.action2quare.com/ayo/maingate/flag"
"github.com/golang-jwt/jwt"
"go.mongodb.org/mongo-driver/bson"
@ -61,7 +61,7 @@ const (
)
func SessionTTL() time.Duration {
if *common.Devflag {
if *flag.Devflag {
return sessionTTLDev
}
@ -73,7 +73,7 @@ type mongoAuthCell struct {
}
func init() {
if *common.Devflag {
if *flag.Devflag {
hostname, _ := os.Hostname()
CollectionLink = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionLink)))
CollectionAuth = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionAuth)))
@ -129,33 +129,6 @@ func makeAuthCollection(mongoClient common.MongoClient, sessionTTL time.Duration
return authcoll
}
type apiTokenMap struct {
sync.Mutex
tokenToService map[string]string
}
func (tm *apiTokenMap) add(token string, serviceCode string) {
tm.Lock()
defer tm.Unlock()
tm.tokenToService[token] = serviceCode
}
func (tm *apiTokenMap) remove(token string) {
tm.Lock()
defer tm.Unlock()
delete(tm.tokenToService, token)
}
func (tm *apiTokenMap) get(token string) (code string, exists bool) {
tm.Lock()
defer tm.Unlock()
code, exists = tm.tokenToService[token]
return
}
type maingateConfig struct {
Mongo string `json:"maingate_mongodb_url"`
SessionTTL int64 `json:"maingate_session_ttl"`
@ -194,104 +167,16 @@ func (ga *globalAdmins) parse() {
ga.modtime = common.ConfigModTime()
}
type servicelist struct {
services unsafe.Pointer
}
func (sl *servicelist) init(total []*serviceDescription) error {
next := make(map[string]*serviceDescription)
for _, service := range total {
next[service.ServiceName] = service
}
atomic.StorePointer(&sl.services, unsafe.Pointer(&next))
return nil
}
func (sl *servicelist) add(s *serviceDescription) {
ptr := atomic.LoadPointer(&sl.services)
src := (*map[string]*serviceDescription)(ptr)
next := map[string]*serviceDescription{}
for k, v := range *src {
next[k] = v
}
next[s.ServiceName] = s
atomic.StorePointer(&sl.services, unsafe.Pointer(&next))
}
func (sl *servicelist) getByCode(code string) *serviceDescription {
ptr := atomic.LoadPointer(&sl.services)
src := *(*map[string]*serviceDescription)(ptr)
for _, v := range src {
if v.ServiceCode == code {
return v
}
}
return nil
}
func (sl *servicelist) get(sn any) *serviceDescription {
ptr := atomic.LoadPointer(&sl.services)
src := *(*map[string]*serviceDescription)(ptr)
switch sn := sn.(type) {
case string:
return src[sn]
case primitive.ObjectID:
for _, desc := range src {
if desc.Id == sn {
return desc
}
}
}
return nil
}
func (sl *servicelist) all() map[string]*serviceDescription {
ptr := atomic.LoadPointer(&sl.services)
src := (*map[string]*serviceDescription)(ptr)
next := map[string]*serviceDescription{}
for k, v := range *src {
next[k] = v
}
return next
}
func (sl *servicelist) remove(uid primitive.ObjectID) (out *serviceDescription) {
ptr := atomic.LoadPointer(&sl.services)
src := (*map[string]*serviceDescription)(ptr)
next := map[string]*serviceDescription{}
var targetkey string
out = nil
for k, v := range *src {
next[k] = v
if v.Id == uid {
targetkey = k
out = v
}
}
delete(next, targetkey)
atomic.StorePointer(&sl.services, unsafe.Pointer(&next))
return
}
// Maingate :
type Maingate struct {
maingateConfig
mongoClient common.MongoClient
auths *common.AuthCollection
services servicelist
auths *common.AuthCollection
//services servicelist
serviceptr unsafe.Pointer
admins unsafe.Pointer
apiTokenToService apiTokenMap
tokenEndpoints map[string]string
authorizationEndpoints map[string]string
userinfoEndpoint map[string]string
@ -318,12 +203,8 @@ func New(ctx context.Context) (*Maingate, error) {
}
mg := Maingate{
maingateConfig: config,
services: servicelist{},
admins: unsafe.Pointer(&admins),
apiTokenToService: apiTokenMap{
tokenToService: make(map[string]string),
},
maingateConfig: config,
admins: unsafe.Pointer(&admins),
tokenEndpoints: make(map[string]string),
authorizationEndpoints: make(map[string]string),
userinfoEndpoint: make(map[string]string),
@ -352,6 +233,11 @@ func New(ctx context.Context) (*Maingate, error) {
return &mg, nil
}
func (mg *Maingate) service() *serviceDescription {
valptr := atomic.LoadPointer(&mg.serviceptr)
return (*serviceDescription)(valptr)
}
func (mg *Maingate) Destructor() {
logger.Println("maingate.Destructor")
mg.mongoClient.Close()
@ -554,23 +440,19 @@ func whitelistKey(email string) string {
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error {
var allServices []*serviceDescription
logger.Println(CollectionService)
if err := mg.mongoClient.FindAllAs(CollectionService, bson.M{}, &allServices, options.Find().SetReturnKey(false)); err != nil {
if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil {
return err
}
for _, service := range allServices {
if err := service.prepare(mg); err != nil {
return err
}
}
logger.Println("RegisterHandlers...")
mg.services.init(allServices)
for _, service := range allServices {
logger.Println("ServiceCode:", service.ServiceCode)
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, service.ServiceCode, "/"), service)
if len(allServices) > 0 {
only := allServices[0]
only.prepare(mg)
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(only))
}
logger.Println("Service is registered :", mg.service().ServiceCode)
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, mg.service().ServiceCode, "/"), mg.service())
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "api/"), mg.api)
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "query/"), mg.query)
@ -595,16 +477,10 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
return
}
code, exists := mg.apiTokenToService.get(apitoken)
if !exists {
logger.Println("MG-X-API-TOKEN is invalid :", apitoken)
w.WriteHeader(http.StatusBadRequest)
return
apitokenObj, _ := primitive.ObjectIDFromHex(apitoken)
if mg.service().isValidToken(apitokenObj) {
convertedConfig["divisions"] = mg.service().Divisions
}
service := mg.services.getByCode(code)
convertedConfig["divisions"] = service.Divisions
enc := json.NewEncoder(w)
enc.Encode(convertedConfig)
})
@ -687,19 +563,13 @@ func (mg *Maingate) query(w http.ResponseWriter, r *http.Request) {
return
}
servicecode, exists := mg.apiTokenToService.get(apitoken)
if !exists {
apitokenObj, _ := primitive.ObjectIDFromHex(apitoken)
if !mg.service().isValidToken(apitokenObj) {
logger.Println("MG-X-API-TOKEN is invalid :", apitoken)
w.WriteHeader(http.StatusBadRequest)
return
}
if info.ServiceCode != servicecode {
logger.Println("session is not for this service :", info.ServiceCode, servicecode)
w.WriteHeader(http.StatusBadRequest)
return
}
bt, _ := json.Marshal(info)
w.Write(bt)
}