Compare commits

..

15 Commits

7 changed files with 331 additions and 477 deletions

View File

@ -161,18 +161,21 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
mg := caller.mg
logger.Println("blockAPI :", r.Method)
if r.Method == "GET" {
switch r.Method {
case "GET":
target, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
logger.Println("Get :", target, ok)
if !ok {
// 페이지네이션 해야할 듯
json.NewEncoder(w).Encode(mg.bl.all())
//json.NewEncoder(w).Encode(mg.bl.all())
} else if !target.IsZero() {
if blocked, ok := mg.bl.get(target); ok && blocked != nil {
var blocked []blockinfo
if err := caller.mg.mongoClient.FindAllAs(CollectionBlock, bson.M{
"accid": target,
}, &blocked); err == nil {
json.NewEncoder(w).Encode(blocked)
}
}
} else if r.Method == "PUT" {
case "PUT":
var targets struct {
Start primitive.DateTime
End primitive.DateTime
@ -189,22 +192,15 @@ func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
Meta: meta,
}
_, _, err := mg.mongoClient.Update(CollectionBlock, bson.M{
"_id": accid,
}, bson.M{
"$set": &bi,
}, options.Update().SetUpsert(true))
_, err := mg.mongoClient.Collection(CollectionBlock).InsertOne(r.Context(), bi)
if err != nil {
logger.Println("account is not blocked. err :", err)
} else {
logger.Println("account is blocked :", meta)
bi.Accid = accid
caller.mg.bl.add(&bi)
mg.sessionProvider.RevokeAll(accid)
}
}
} else if r.Method == "DELETE" {
case "DELETE":
id := r.URL.Query().Get("id")
if len(id) == 0 {
@ -215,29 +211,21 @@ func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
return err
}
_, _, err = mg.mongoClient.Update(CollectionBlock, bson.M{
"_id": idobj,
}, bson.M{
"$currentDate": bson.M{
"_ts": bson.M{"$type": "date"},
},
}, options.Update().SetUpsert(false))
if err != nil {
return err
}
caller.mg.bl.remove(idobj)
mg.mongoClient.Delete(CollectionBlock, bson.M{"_id": idobj})
}
return nil
}
func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) error {
mg := caller.mg
if r.Method == "GET" {
enc := json.NewEncoder(w)
enc.Encode(mg.wl.all())
} else if r.Method == "PUT" {
switch r.Method {
case "GET":
var all []whitelistmember
if err := mg.mongoClient.AllAs(CollectionWhitelist, &all); err == nil {
enc := json.NewEncoder(w)
enc.Encode(all)
}
case "PUT":
body, _ := io.ReadAll(r.Body)
var member whitelistmember
if err := json.Unmarshal(body, &member); err != nil {
@ -254,7 +242,7 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
if err != nil {
return err
}
} else if r.Method == "DELETE" {
case "DELETE":
id := r.URL.Query().Get("id")
if len(id) == 0 {
@ -396,43 +384,62 @@ func (caller apiCaller) userinfoAPI(w http.ResponseWriter, r *http.Request) erro
if r.Method == "GET" {
// 계정 조회
accid, _ := gocommon.ReadObjectIDFormValue(r.Form, "accid")
if len(accid) == 0 {
logger.Println("[userinfoAPI] accid is empty")
w.WriteHeader(http.StatusBadRequest)
return nil
}
all, err := mg.mongoClient.FindAll(CollectionAccount, bson.M{
"accid": accid,
}, options.Find().SetProjection(bson.M{"_id": 1, "accid": 1}))
if err != nil {
return err
}
var linkinfos []accountlinkinfo
for _, doc := range all {
id := doc["_id"].(primitive.ObjectID)
link, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
"_id": id,
}, options.FindOne().SetProjection(bson.M{"_id": 1, "platform": 1, "uid": 1}))
if len(accid) > 0 {
all, err := mg.mongoClient.FindAll(CollectionAccount, bson.M{
"accid": accid,
}, options.Find().SetProjection(bson.M{"_id": 1, "accid": 1}))
if err != nil {
logger.Error("link failed. FindOneAndUpdate link err:", err)
w.WriteHeader(http.StatusInternalServerError)
return err
}
var info accountlinkinfo
info.Platform = link["platform"].(string)
info.Uid = link["uid"].(string)
linkinfos = append(linkinfos, info)
var linkinfos []accountlinkinfo
for _, doc := range all {
id := doc["_id"].(primitive.ObjectID)
link, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
"_id": id,
}, options.FindOne().SetProjection(bson.M{"_id": 1, "platform": 1, "uid": 1}))
if err != nil {
logger.Error("link failed. FindOneAndUpdate link err:", err)
w.WriteHeader(http.StatusInternalServerError)
return err
}
var info accountlinkinfo
info.Platform = link["platform"].(string)
info.Uid = link["uid"].(string)
linkinfos = append(linkinfos, info)
}
enc := json.NewEncoder(w)
enc.Encode(linkinfos)
}
} else if r.Method == "POST" {
r.ParseMultipartForm(32 << 20)
var body struct {
Platform string
Uid []string
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
return err
}
enc := json.NewEncoder(w)
enc.Encode(linkinfos)
if len(body.Platform) > 0 && len(body.Uid) > 0 {
output := make(map[string]any)
for _, uid := range body.Uid {
link, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
"platform": body.Platform,
"uid": uid,
}, options.FindOne().SetProjection(bson.M{"_id": 1}))
if err != nil {
return err
}
output[uid] = link["_id"]
}
json.NewEncoder(w).Encode(output)
}
}
return nil

View File

@ -148,8 +148,6 @@ type Maingate struct {
//services servicelist
serviceptr unsafe.Pointer
admins unsafe.Pointer
wl memberContainerPtr[string, *whitelistmember]
bl memberContainerPtr[primitive.ObjectID, *blockinfo]
tokenEndpoints map[string]string
authorizationEndpoints map[string]string
@ -306,9 +304,12 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
"emailplatform": {{Key: "email", Value: 1}, {Key: "platform", Value: 1}},
}); err != nil {
// if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
// "emailplatform": {{Key: "email", Value: 1}, {Key: "platform", Value: 1}},
// }); err != nil {
// return logger.ErrorWithCallStack(err)
// }
if err = mg.mongoClient.DropIndex(CollectionLink, "emailplatform"); err != nil {
return logger.ErrorWithCallStack(err)
}
@ -342,7 +343,15 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
mg.mongoClient.DropIndex(CollectionBlock, "codeaccid")
}
if err = mg.mongoClient.MakeExpireIndex(CollectionBlock, int32(3)); err != nil {
if _, err := mg.mongoClient.Collection(CollectionBlock).Indexes().DropOne(context, "_ts_1"); err == nil {
// 인덱스가 방금 지워졌다.
// 전체 document 제거
logger.Println(mg.mongoClient.Collection(CollectionBlock).Drop(context))
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionBlock, map[string]bson.D{
"accidend": {{Key: "accid", Value: 1}, {Key: "end", Value: 1}},
}); err != nil {
return logger.ErrorWithCallStack(err)
}
@ -409,29 +418,12 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
}
}
var whites []*whitelistmember
if err := mg.mongoClient.AllAs(CollectionWhitelist, &whites, options.Find().SetReturnKey(false)); err != nil {
return logger.ErrorWithCallStack(err)
}
mg.wl.init(whites)
var blocks []*blockinfo
if err := mg.mongoClient.AllAs(CollectionBlock, &blocks); err != nil {
return logger.ErrorWithCallStack(err)
}
logger.Println("allblocks :", blocks)
mg.bl.init(blocks)
go mg.wl.watchCollection(context, CollectionWhitelist, mg.mongoClient)
go mg.bl.watchCollection(context, CollectionBlock, mg.mongoClient)
return nil
}
var portptr = flagx.Int("port", 80, "")
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error {
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) error {
var allServices []*serviceDescription
if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil {
return logger.ErrorWithCallStack(err)

View File

@ -1,159 +0,0 @@
package core
import (
"context"
"sync/atomic"
"time"
"unsafe"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger"
)
type memberContraints[K comparable] interface {
Key() K
Expired() bool
}
type memberContainerPtr[K comparable, T memberContraints[K]] struct {
ptr unsafe.Pointer
}
func (p *memberContainerPtr[K, T]) init(ms []T) {
next := map[K]T{}
for _, m := range ms {
next[m.Key()] = m
}
atomic.StorePointer(&p.ptr, unsafe.Pointer(&next))
}
func (p *memberContainerPtr[K, T]) add(m T) {
ptr := atomic.LoadPointer(&p.ptr)
src := (*map[K]T)(ptr)
next := map[K]T{}
for k, v := range *src {
next[k] = v
}
next[m.Key()] = m
atomic.StorePointer(&p.ptr, unsafe.Pointer(&next))
}
func (p *memberContainerPtr[K, T]) get(key K) (T, bool) {
ptr := atomic.LoadPointer(&p.ptr)
src := (*map[K]T)(ptr)
out, found := (*src)[key]
return out, found
}
func (p *memberContainerPtr[K, T]) remove(key K) {
ptr := atomic.LoadPointer(&p.ptr)
src := (*map[K]T)(ptr)
next := map[K]T{}
for k, v := range *src {
next[k] = v
}
delete(next, key)
atomic.StorePointer(&p.ptr, unsafe.Pointer(&next))
}
type memberPipelineDocument[K comparable, T memberContraints[K]] struct {
OperationType string `bson:"operationType"`
DocumentKey struct {
Id primitive.ObjectID `bson:"_id"`
} `bson:"documentKey"`
Member T `bson:"fullDocument"`
}
func (p *memberContainerPtr[K, T]) all() []T {
ptr := atomic.LoadPointer(&p.ptr)
src := (*map[K]T)(ptr)
out := make([]T, 0, len(*src))
for _, m := range *src {
if m.Expired() {
continue
}
out = append(out, m)
}
return out
}
func (p *memberContainerPtr[K, T]) watchCollection(parentctx context.Context, coll gocommon.CollectionName, mc gocommon.MongoClient) {
defer func() {
s := recover()
if s != nil {
logger.Error(s)
}
}()
matchStage := bson.D{
{
Key: "$match", Value: bson.D{
{Key: "operationType", Value: bson.D{
{Key: "$in", Value: bson.A{
"update",
"insert",
}},
}},
},
}}
projectStage := bson.D{
{
Key: "$project", Value: bson.D{
{Key: "documentKey", Value: 1},
{Key: "fullDocument", Value: 1},
},
},
}
var stream *mongo.ChangeStream
var err error
var ctx context.Context
for {
if stream == nil {
stream, err = mc.Watch(coll, mongo.Pipeline{matchStage, projectStage})
if err != nil {
logger.Error("watchCollection watch failed :", err)
time.Sleep(time.Minute)
continue
}
ctx = context.TODO()
}
changed := stream.TryNext(ctx)
if ctx.Err() != nil {
logger.Error("watchCollection stream.TryNext failed. process should be restarted! :", ctx.Err().Error())
break
}
if changed {
var data memberPipelineDocument[K, T]
if err := stream.Decode(&data); err == nil {
p.add(data.Member)
} else {
logger.Error("watchCollection stream.Decode failed :", err)
}
} else if stream.Err() != nil || stream.ID() == 0 {
select {
case <-ctx.Done():
logger.Println("watchCollection is done")
stream.Close(ctx)
return
case <-time.After(time.Second):
logger.Error("watchCollection stream error :", stream.Err())
stream.Close(ctx)
stream = nil
}
} else {
time.Sleep(time.Second)
}
}
}

View File

@ -1,7 +1,6 @@
package core
import (
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
@ -23,26 +22,23 @@ import (
)
type blockinfo struct {
Id primitive.ObjectID `bson:"_id" json:"_id"`
Start primitive.DateTime `bson:"start" json:"start"`
End primitive.DateTime `bson:"_ts" json:"_ts"`
Accid primitive.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
End primitive.DateTime `bson:"end" json:"end"`
Accid primitive.ObjectID `bson:"accid,omitempty" json:"accid,omitempty"`
Meta primitive.M `bson:"meta,omitempty" json:"meta,omitempty"`
}
type whitelistmember struct {
Id primitive.ObjectID `bson:"_id" json:"_id"`
Email string `bson:"email" json:"email"`
Alias string `bson:"alias" json:"alias"`
Platform string `bson:"platform" json:"platform"`
Desc string `bson:"desc" json:"desc"`
ExpiredAt primitive.DateTime `bson:"_ts,omitempty" json:"_ts,omitempty"`
}
func (wh *whitelistmember) Key() string {
if strings.HasPrefix(wh.Email, "*@") {
// 도메인 전체 허용
return wh.Email[2:]
}
return wh.Email
return wh.Alias
}
func (wh *whitelistmember) Expired() bool {
@ -104,8 +100,6 @@ type serviceDescription struct {
VersionSplits map[string]string `bson:"version_splits" json:"version_splits"`
sessionProvider session.Provider
wl *memberContainerPtr[string, *whitelistmember]
bl *memberContainerPtr[primitive.ObjectID, *blockinfo]
mongoClient gocommon.MongoClient
sessionTTL time.Duration
@ -269,9 +263,6 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
}
}
}
sh.wl = &mg.wl
sh.bl = &mg.bl
sh.serviceSerialized, _ = json.Marshal(sh)
return nil
@ -308,7 +299,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
bfinfo, err := sh.getUserBrowserInfo(r)
if err != nil {
logger.Error("getUserBrowserInfo failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -317,7 +308,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
if !guestlink {
_, err = sh.readProfile(oldType, oldId, bfinfo)
if err != nil {
logger.Error("readProfile(old) failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -327,7 +318,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
oldType, oldId, err = sh.getProviderInfo(oldType, oldId)
if err != nil {
logger.Error("getProviderInfo failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -350,9 +341,10 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
return
}
email, err := sh.readProfile(newType, newId, bfinfo)
//email, err := sh.readProfile(newType, newId, bfinfo)
_, err = sh.readProfile(newType, newId, bfinfo)
if err != nil {
logger.Error("readProfile(new) failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -365,14 +357,14 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
newType, newId, err = sh.getProviderInfo(newType, newId)
if err != nil {
logger.Error("getProviderInfo failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
found, err := sh.mongoClient.FindOne(CollectionLink, bson.M{"platform": newType, "uid": newId}, options.FindOne())
if err != nil {
logger.Error("link failed. FindOne err:", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -389,11 +381,11 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
}, bson.M{
"$setOnInsert": bson.M{
"create": createtime,
"email": email,
//"email": email,
},
}, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(true).SetProjection(bson.M{"_id": 1}))
if err != nil {
logger.Error("link failed. FindOneAndUpdate link err:", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -407,7 +399,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
},
}, options.Update().SetUpsert(true))
if err != nil {
logger.Error("link failed. Update ServiceName err :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -455,6 +447,7 @@ func (sh *serviceDescription) unlink(w http.ResponseWriter, r *http.Request) {
sType := queryvals.Get("stype")
sId := queryvals.Get("sid")
sk := queryvals.Get("sk")
targetType := queryvals.Get("ttype")
authInfo, err := sh.sessionProvider.Query(sk)
if err != nil {
@ -471,55 +464,60 @@ func (sh *serviceDescription) unlink(w http.ResponseWriter, r *http.Request) {
// fmt.Println(authInfo.Uid)
// fmt.Println("=================")
sType, sId, err = sh.getProviderInfo(sType, sId)
if err != nil {
logger.Println("getProviderInfo failed :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
if authInfo.Uid != sId || authInfo.Platform != sType {
logger.Println("unlink failed. session key is not correct :", authInfo, queryvals)
w.WriteHeader(http.StatusBadRequest)
return
}
numRecord, err := sh.mongoClient.Collection(CollectionAccount).CountDocuments(context.Background(), bson.M{
accDocs, err := sh.mongoClient.FindAll(CollectionAccount, bson.M{
"accid": authInfo.Account,
}, options.Count().SetLimit(2))
}, options.Find().SetProjection(bson.M{
"_id": 1,
}))
if err != nil {
logger.Error("unlink failed, fail to count accounts :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
}
if numRecord <= 1 {
if len(accDocs) <= 1 {
logger.Println("unlink failed. At least one link must be maintained. :", r.URL.Query())
w.WriteHeader(http.StatusBadRequest)
return
}
sType, sId, err = sh.getProviderInfo(sType, sId)
if err != nil {
logger.Error("getProviderInfo failed :", err)
w.WriteHeader(http.StatusBadRequest)
var ids primitive.A
for _, accDoc := range accDocs {
ids = append(ids, accDoc["_id"].(primitive.ObjectID))
}
link, err := sh.mongoClient.FindOne(CollectionLink, bson.M{
"platform": sType,
"uid": sId,
}, options.FindOne().SetProjection(bson.M{"_id": 1}))
link, err := sh.mongoClient.FindOneAndDelete(CollectionLink, bson.M{
"platform": targetType,
"_id": bson.M{"$in": ids},
}, options.FindOneAndDelete().SetProjection(bson.M{"_id": 1}))
if err != nil {
logger.Error("link failed. FindOneAndUpdate link err:", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
newid, err := sh.mongoClient.FindOneAndDelete(CollectionAccount, bson.M{
preid, err := sh.mongoClient.FindOneAndDelete(CollectionAccount, bson.M{
"_id": link["_id"].(primitive.ObjectID),
}, options.FindOneAndDelete().SetProjection(bson.M{"_id": 1}))
if err != nil {
logger.Error("unlink failed. Delete ServiceName err :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
// newid가 있어야 한다. 그래야 기존 서비스 계정이 없는 상태이다.
if newid == nil {
// 이미 계정이 있네?
if preid == nil {
logger.Println("unlink failed. service account not found:", r.URL.Query())
w.WriteHeader(http.StatusBadRequest)
return
@ -528,7 +526,7 @@ func (sh *serviceDescription) unlink(w http.ResponseWriter, r *http.Request) {
logger.Println("unlink success :", r.URL.Query())
}
// == 연결된 계정 정보(숫자) 전달하는 API
// == 연결된 계정 정보(platform) 전달하는 API
func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
defer func() {
s := recover()
@ -562,6 +560,13 @@ func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
// fmt.Println(authInfo.Uid)
// fmt.Println("=================")
sType, sId, err = sh.getProviderInfo(sType, sId)
if err != nil {
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
//if oldAuth.Token != oldToken || oldAuth.Uid != oldId || oldAuth.Platform != oldType {
if authInfo.Uid != sId || authInfo.Platform != sType {
logger.Println("linkinfo failed. session key is not correct :", authInfo, queryvals)
@ -569,19 +574,46 @@ func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
return
}
numRecord, err := sh.mongoClient.Collection(CollectionAccount).CountDocuments(context.Background(), bson.M{
"accid": authInfo.Account,
}, options.Count().SetLimit(sh.MaximumNumLinkAccount))
platformName := "platform"
accDocs, err := sh.mongoClient.FindAll(CollectionAccount, bson.M{"accid": authInfo.Account}, options.Find().SetLimit(sh.MaximumNumLinkAccount).SetProjection(bson.M{
"_id": 1,
}))
if err != nil {
logger.Error("linkinfo failed. CountDocuments err :", err)
w.WriteHeader(http.StatusBadRequest)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
logger.Println("linkinfo :", numRecord)
w.Write([]byte(fmt.Sprintf(`{"num_linked_account":"%d"}`, numRecord)))
var ids primitive.A
for _, accDoc := range accDocs {
ids = append(ids, accDoc["_id"].(primitive.ObjectID))
}
links, err := sh.mongoClient.FindAll(CollectionLink, bson.M{
"_id": bson.M{"$in": ids},
}, options.Find().SetLimit(sh.MaximumNumLinkAccount).SetProjection(bson.M{
platformName: 1,
}))
if err != nil {
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
var linkstrs []string
for _, link := range links {
linkstrs = append(linkstrs, link[platformName].(string))
}
linkbytes, err := json.Marshal(linkstrs)
if err != nil {
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
logger.Println("linkinfo :", linkstrs)
w.Write(linkbytes)
}
// == 계정 이메일 조회
@ -599,16 +631,22 @@ func (sh *serviceDescription) emailinfo(w http.ResponseWriter, r *http.Request)
}
queryvals := r.URL.Query()
sk := queryvals.Get("sk")
reqauthtype := queryvals.Get("type")
uid := queryvals.Get("id")
authInfo, err := sh.sessionProvider.Query(sk)
bfinfo, err := sh.getUserBrowserInfo(r)
if err != nil {
logger.Println("sessionProvider.Query return err :", err)
w.WriteHeader(http.StatusInternalServerError)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
email := authInfo.Email
email, err := sh.readProfile(reqauthtype, uid, bfinfo)
if err != nil {
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
if strings.HasPrefix(email, "__dummy_") && strings.HasSuffix(email, "temp__") {
email = ""
@ -624,22 +662,12 @@ func (sh *serviceDescription) emailinfo(w http.ResponseWriter, r *http.Request)
//logger.Println("Email :", email)
w.Write([]byte(fmt.Sprintf(`{"email":"%s"}`, email)))
}
func (sh *serviceDescription) authorize_dev(w http.ResponseWriter, r *http.Request) {
if r.Method == "DELETE" {
sk := r.Header.Get("AS-X-SESSION")
if authinfo, err := sh.sessionProvider.Query(sk); err == nil {
bt := r.Header.Get("AS-X-BLOCK")
if len(bt) > 0 {
dur, _ := strconv.ParseInt(bt, 10, 0)
sh.bl.add(&blockinfo{
Start: primitive.NewDateTimeFromTime(time.Now().UTC()),
End: primitive.NewDateTimeFromTime(time.Now().UTC().Add(time.Second * time.Duration(dur))),
Accid: authinfo.Account,
})
}
sh.sessionProvider.RevokeAll(authinfo.Account)
}
@ -665,7 +693,6 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
queryvals := r.URL.Query()
reqauthtype := queryvals.Get("type")
uid := queryvals.Get("id")
sk := queryvals.Get("sk")
checksum := r.Header.Get("AS-X-CHECKSUM")
if len(checksum) > 0 || sh.mustUseChecksum {
@ -673,7 +700,7 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
cookie := r.Header.Get("Cookie")
h := md5.New()
h.Write([]byte(cookie + nonce + sk))
h.Write([]byte(cookie + nonce))
if checksum != hex.EncodeToString(h.Sum(nil)) {
w.WriteHeader(http.StatusBadRequest)
@ -681,47 +708,27 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
}
}
if len(sk) > 0 {
success, err := sh.sessionProvider.Touch(sk)
if err != nil {
logger.Error("authorize failed. sessionProvider.Touch err:", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
// !success일 때 빈 body를 보내면 클라이언트는 로그아웃 된다.
if success {
json.NewEncoder(w).Encode(map[string]any{
"sk": sk,
"expirein": sh.sessionTTL.Seconds(),
})
} else {
w.WriteHeader(http.StatusUnauthorized)
}
return
}
var email string
if !*noauth && (*authtype == "on" || *authtype == "both") {
if len(reqauthtype) > 0 {
//email, err := sh.readProfile(authtype, uid, accesstoken)
bfinfo, err := sh.getUserBrowserInfo(r)
if err != nil {
logger.Error("getUserBrowserInfo failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
email, err = sh.readProfile(reqauthtype, uid, bfinfo)
if err != nil {
logger.Error("readProfile failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
newType, newId, err := sh.getProviderInfo(reqauthtype, uid)
if err != nil {
logger.Error("getProviderInfo failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -750,11 +757,11 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
}, bson.M{
"$setOnInsert": bson.M{
"create": createtime,
"email": email,
//"email": email,
},
}, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(true).SetProjection(bson.M{"_id": 1, "_ts": 1}))
if err != nil {
logger.Error("authorize failed :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -770,7 +777,7 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
},
}, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(true).SetProjection(bson.M{"accid": 1, "create": 1}))
if err != nil {
logger.Error("authorize failed. Update sh.ServiceName err:", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -779,7 +786,8 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
oldcreate := account["create"].(primitive.DateTime)
newaccount := oldcreate == createtime
if bi, ok := sh.bl.get(accid); ok {
var bi blockinfo
if err := sh.mongoClient.FindOneAs(CollectionBlock, bson.M{"accid": accid, "end": bson.M{"$gt": time.Now().UTC()}}, &bi); err == nil {
// 블럭된 계정. 블락 정보를 알려준다.
w.Header().Add("MG-ACCOUNTBLOCK-START", strconv.FormatInt(bi.Start.Time().Unix(), 10))
w.Header().Add("MG-ACCOUNTBLOCK-END", strconv.FormatInt(bi.End.Time().Unix(), 10))
@ -787,14 +795,19 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
return
}
sk, err = sh.sessionProvider.New(&session.Authorization{
alias := r.Header.Get("AS-X-ALIAS")
if len(alias) == 0 {
alias = email
}
sk, err := sh.sessionProvider.New(&session.Authorization{
Account: accid,
Platform: reqauthtype,
Uid: uid,
Email: email,
Alias: alias,
})
if err != nil {
logger.Error("authorize failed. sessionProvider.New err:", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -863,7 +876,7 @@ func (sh *serviceDescription) delacc(w http.ResponseWriter, r *http.Request) {
if !*devflag || len(sType) != 0 {
sType, sId, err = sh.getProviderInfo(sType, sId)
if err != nil {
logger.Error("delacc failed. getProviderInfo err :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -877,7 +890,7 @@ func (sh *serviceDescription) delacc(w http.ResponseWriter, r *http.Request) {
linkidMap, err := sh.mongoClient.FindAll(CollectionAccount, bson.M{"accid": authInfo.Account}, options.Find().SetProjection(bson.M{"_id": 1}))
if err != nil {
logger.Error("delacc failed. FindAll account err :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -908,7 +921,7 @@ func (sh *serviceDescription) delacc(w http.ResponseWriter, r *http.Request) {
delfilter["platform"] = sType
targetLinkId, err := sh.mongoClient.FindAll(CollectionLink, delfilter, options.Find().SetProjection(bson.M{"_id": 1}))
if len(targetLinkId) != 1 {
logger.Error("delacc failed. FindAll link err :", err)
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -917,15 +930,25 @@ func (sh *serviceDescription) delacc(w http.ResponseWriter, r *http.Request) {
delop = primitive.M{"$unset": primitive.M{"_ts": true}}
}
updated, _, err := sh.mongoClient.Update(CollectionAccount, delfilter, delop, options.Update().SetUpsert(false))
if !updated || err != nil {
logger.Error("delacc failed. Update CollectionAccount timestamp err :", err)
if err != nil {
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if !updated {
logger.Error("delacc failed. Update CollectionAccount timestamp. undated is false")
w.WriteHeader(http.StatusInternalServerError)
return
}
updated, _, err = sh.mongoClient.Update(CollectionLink, delfilter, delop, options.Update().SetUpsert(false))
if !updated || err != nil {
logger.Error("delacc failed. Update CollectionLink timestamp err :", err)
if err != nil {
logger.ErrorWithCallStack(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if !updated {
logger.Error("delacc failed. Update CollectionLink timestamp. updated is false")
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -1023,7 +1046,11 @@ func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request)
divname := queryvals.Get("div")
divname = strings.Trim(divname, `"`)
div := sh.Divisions[divname]
div, ok := sh.Divisions[divname]
if !ok {
div = sh.Divisions["default"]
}
var addrresp []byte
if div != nil {
logger.Println("/addr :", divname, div.State)
@ -1041,12 +1068,14 @@ func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request)
return
}
wm := &whitelistmember{Email: authInfo.Email, Platform: authInfo.Platform}
if _, ok := sh.wl.get(wm.Key()); ok {
wm := &whitelistmember{Alias: authInfo.Alias, Platform: authInfo.Platform}
doc, err := sh.mongoClient.FindOne(CollectionWhitelist, bson.M{"alias": wm.Key()})
if err == nil && doc != nil {
// qa 권한이면 입장 가능
addrresp = div.urlsSerialized
} else if div.Maintenance != nil {
// 권한이 없으므로 공지
addrresp = []byte(fmt.Sprintf(`{"notice":"%s"}`, div.Maintenance.link))
} else {
logger.Println("div.Maintenance is nil :", divname)
}
@ -1067,8 +1096,5 @@ func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request)
logger.Println("check maingate database 'service.divisions' :", config.Mongo)
w.WriteHeader(http.StatusBadRequest)
}
} else {
logger.Println("??? :", r.URL.Path)
w.WriteHeader(http.StatusBadRequest)
}
}

View File

@ -3,13 +3,13 @@ package core
import (
"context"
"encoding/hex"
"net/http"
"os"
"path"
"sync/atomic"
"time"
"unsafe"
"repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger"
"go.mongodb.org/mongo-driver/bson"
@ -34,7 +34,7 @@ type filePipelineDocument struct {
File *FileDocumentDesc `bson:"fullDocument"`
}
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
defer func() {
s := recover()
if s != nil {
@ -119,7 +119,7 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *htt
}
}
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
defer func() {
s := recover()
if s != nil {

62
go.mod
View File

@ -1,34 +1,38 @@
module repositories.action2quare.com/ayo/maingate
go 1.19
go 1.22.1
require (
firebase.google.com/go v3.13.0+incompatible
github.com/golang-jwt/jwt v3.2.2+incompatible
go.mongodb.org/mongo-driver v1.11.7
google.golang.org/api v0.128.0
repositories.action2quare.com/ayo/gocommon v0.0.0-20240517005942-6a98802e24e5
google.golang.org/api v0.157.0
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86
)
require (
cloud.google.com/go v0.110.2 // indirect
cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go v0.111.0 // indirect
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/firestore v1.10.0 // indirect
cloud.google.com/go/iam v1.1.1 // indirect
cloud.google.com/go/longrunning v0.5.1 // indirect
cloud.google.com/go/firestore v1.14.0 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/longrunning v0.5.4 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/klauspost/compress v1.16.6 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect
@ -38,18 +42,22 @@ require (
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/oauth2 v0.9.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/grpc v1.56.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
)

160
go.sum
View File

@ -1,34 +1,27 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM=
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/firestore v1.10.0 h1:FG5C49ukKKqyljY+XNRZGae1HZaiVe7aoqi2BipnBuM=
cloud.google.com/go/firestore v1.10.0/go.mod h1:eAeoQCV8F35Mcy4k8ZrQbcSYZOayIwoiU7ZJ6xzH1+o=
cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw=
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg=
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -37,11 +30,16 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
@ -52,16 +50,13 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -78,19 +73,17 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
@ -112,17 +105,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@ -141,15 +131,24 @@ go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJv
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -157,55 +156,48 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs=
golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -215,35 +207,29 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg=
google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750=
google.golang.org/api v0.157.0 h1:ORAeqmbrrozeyw5NjnMxh7peHO0UzV4wWYSwZeCUb20=
google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao=
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.56.0 h1:+y7Bs8rtMd07LeXmL3NxcTLn7mUkbKZqEpPhMNkwJEE=
google.golang.org/grpc v1.56.0/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -255,22 +241,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240425023707-60c95c2e0edf h1:V2L6UlyKwzzKudU940AowVjGwzBhNBAQirYdPa13JhE=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240425023707-60c95c2e0edf/go.mod h1:Gb418rT96M3K7L/XMPzp8IJj4UXVunq7dZzrxsMBz/8=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240517005227-40d025ad4d78 h1:1chjh1LkfxQBjBt0MDVKp/EFq+PhXDEDRnrgOaL6NAU=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240517005227-40d025ad4d78/go.mod h1:Gb418rT96M3K7L/XMPzp8IJj4UXVunq7dZzrxsMBz/8=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240517005942-6a98802e24e5 h1:XF1JdiBshuGmCtNIcJ9Vqt1CsfWBO+IakP5jJWutL58=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240517005942-6a98802e24e5/go.mod h1:Gb418rT96M3K7L/XMPzp8IJj4UXVunq7dZzrxsMBz/8=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86 h1:vP0mVST68cw14fI/af3Xp1ZQoYjkNGK4S0zji1BVfSI=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86/go.mod h1:XA8+hQtUNh956T+kAbJKkUtMl5HUWj83knvdBvvPS5s=