Compare commits
5 Commits
master
...
ddc34aef55
| Author | SHA1 | Date | |
|---|---|---|---|
| ddc34aef55 | |||
| aef7282556 | |||
| 2369d52a11 | |||
| 23d5281481 | |||
| c2330ad52b |
@ -1,37 +0,0 @@
|
||||
// Import the functions you need from the SDKs you need
|
||||
import { initializeApp } from './firebase-app.js';
|
||||
import { getAnalytics, logEvent } from './firebase-analytics.js';
|
||||
|
||||
// TODO: Add SDKs for Firebase products that you want to use
|
||||
// https://firebase.google.com/docs/web/setup#available-libraries
|
||||
|
||||
// Your web app's Firebase configuration
|
||||
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
|
||||
const firebaseConfig = {
|
||||
apiKey: "{{.FBA_apiKey}}",
|
||||
authDomain: "{{.FBA_authDomain}}",
|
||||
databaseURL: "{{.FBA_databaseURL}}",
|
||||
projectId: "{{.FBA_projectId}}",
|
||||
storageBucket: "{{.FBA_storageBucket}}",
|
||||
messagingSenderId: "{{.FBA_messagingSenderId}}",
|
||||
appId: "{{.FBA_appId}}",
|
||||
measurementId: "{{.FBA_measurementId}}"
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Initialize Firebase
|
||||
const app = initializeApp(firebaseConfig);
|
||||
const analytics = getAnalytics(app);
|
||||
|
||||
// LogEvent('DESKTOP_TEST8');
|
||||
|
||||
export function LogEvent(args){
|
||||
|
||||
if ( arguments.length == 1) {
|
||||
logEvent(analytics, arguments[0]);
|
||||
} else {
|
||||
logEvent(analytics, arguments[0], arguments[1]);
|
||||
}
|
||||
|
||||
}
|
||||
1
backup/firebase-jssdk/fb-ga.min.js
vendored
1
backup/firebase-jssdk/fb-ga.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,6 @@
|
||||
{
|
||||
"maingate_mongodb_url": "mongodb://...",
|
||||
"session_storage": "",
|
||||
"session_ttl" : 3600,
|
||||
|
||||
"autologin_ttl": 604800,
|
||||
"maximum_num_link_account": 10,
|
||||
"redirect_base_url": "",
|
||||
"google_client_id" : "",
|
||||
"google_client_secret" : "",
|
||||
@ -28,15 +24,6 @@
|
||||
|
||||
"firebase_admin_sdk_credentialfile": "",
|
||||
|
||||
"firebase_google_analytics_jssdk_apikey": "",
|
||||
"firebase_google_analytics_jssdk_authdomain": "",
|
||||
"firebase_google_analytics_jssdk_databaseurl": "",
|
||||
"firebase_google_analytics_jssdk_projectid": "",
|
||||
"firebase_google_analytics_jssdk_storagebucket": "",
|
||||
"firebase_google_analytics_jssdk_messagingsenderid": "",
|
||||
"firebase_google_analytics_jssdk_apiid": "",
|
||||
"firebase_google_analytics_jssdk_measurementid": "",
|
||||
|
||||
"maingate_global_admins" : [
|
||||
"mountain@action2quare.com"
|
||||
]
|
||||
|
||||
311
core/api.go
311
core/api.go
@ -2,7 +2,9 @@ package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -16,7 +18,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"repositories.action2quare.com/ayo/gocommon"
|
||||
common "repositories.action2quare.com/ayo/gocommon"
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
@ -24,7 +26,8 @@ import (
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type FileDocumentDesc struct {
|
||||
type fileDocumentDesc struct {
|
||||
Service string `bson:"service" json:"service"`
|
||||
Key string `bson:"key" json:"key"`
|
||||
Src string `bson:"src" json:"src"`
|
||||
Link string `bson:"link" json:"link"`
|
||||
@ -34,7 +37,7 @@ type FileDocumentDesc struct {
|
||||
Contents []byte `bson:"contents,omitempty" json:"contents,omitempty"`
|
||||
}
|
||||
|
||||
func (fd *FileDocumentDesc) Save() error {
|
||||
func (fd *fileDocumentDesc) save() error {
|
||||
// 새 파일 올라옴
|
||||
if len(fd.Contents) == 0 {
|
||||
return nil
|
||||
@ -63,16 +66,48 @@ func (fd *FileDocumentDesc) Save() error {
|
||||
if fd.Extract {
|
||||
switch path.Ext(destFile) {
|
||||
case ".zip":
|
||||
err = gocommon.Unzip(destFile)
|
||||
err = common.Unzip(destFile)
|
||||
case ".tar":
|
||||
err = gocommon.Untar(destFile)
|
||||
err = common.Untar(destFile)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (caller apiCaller) isAdmin() bool {
|
||||
if *noauth {
|
||||
return true
|
||||
}
|
||||
|
||||
v, ok := caller.userinfo["email"]
|
||||
if !ok {
|
||||
logger.Println("isVaidUser failed. email is missing :", caller.userinfo)
|
||||
return false
|
||||
}
|
||||
|
||||
email := v.(string)
|
||||
if _, ok := caller.globalAdmins[email]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return caller.mg.service().isAdmin(email)
|
||||
}
|
||||
|
||||
func (caller apiCaller) isAdminOrValidToken() bool {
|
||||
if caller.isAdmin() {
|
||||
return true
|
||||
}
|
||||
|
||||
return caller.mg.service().isValidToken(caller.apiToken)
|
||||
}
|
||||
|
||||
func (caller apiCaller) filesAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
if r.Method == "GET" {
|
||||
// if !caller.isAdminOrValidToken() {
|
||||
// w.WriteHeader(http.StatusUnauthorized)
|
||||
// return nil
|
||||
// }
|
||||
|
||||
allfiles, err := caller.mg.mongoClient.All(CollectionFile, options.Find().SetProjection(bson.M{
|
||||
"contents": 0,
|
||||
}).SetReturnKey(false))
|
||||
@ -91,6 +126,11 @@ func (caller apiCaller) filesAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if !caller.isAdminOrValidToken() {
|
||||
// w.WriteHeader(http.StatusUnauthorized)
|
||||
// return nil
|
||||
// }
|
||||
|
||||
_, err := caller.mg.mongoClient.Delete(CollectionFile, bson.M{
|
||||
"key": key,
|
||||
})
|
||||
@ -107,6 +147,11 @@ var seq = uint32(0)
|
||||
|
||||
func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
if r.Method == "PUT" {
|
||||
servicename := r.FormValue("service")
|
||||
hasher := md5.New()
|
||||
hasher.Write([]byte(servicename))
|
||||
subfolder := hex.EncodeToString(hasher.Sum(nil))[:8]
|
||||
|
||||
infile, header, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
@ -122,19 +167,20 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
|
||||
var b [5]byte
|
||||
binary.BigEndian.PutUint32(b[0:4], uint32(time.Now().Unix()))
|
||||
b[4] = byte(atomic.AddUint32(&seq, 1) % 255)
|
||||
|
||||
rf := hex.EncodeToString(b[1:])
|
||||
newidstr := subfolder + rf
|
||||
newidbt, _ := hex.DecodeString(newidstr)
|
||||
newidobj := primitive.NewObjectID()
|
||||
copy(newidobj[:], b[1:])
|
||||
copy(newidobj[:], newidbt[:8])
|
||||
|
||||
rf := newidobj.Hex()
|
||||
var link string
|
||||
if extract {
|
||||
link = path.Join("static", rf)
|
||||
link = path.Join("static", subfolder, rf)
|
||||
} else {
|
||||
link = path.Join("static", rf, header.Filename)
|
||||
link = path.Join("static", subfolder, rf, header.Filename)
|
||||
}
|
||||
|
||||
newdoc := FileDocumentDesc{
|
||||
newdoc := fileDocumentDesc{
|
||||
Contents: contents,
|
||||
Src: header.Filename,
|
||||
Timestamp: time.Now().UTC().Unix(),
|
||||
@ -142,9 +188,11 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
|
||||
Link: link,
|
||||
Desc: desc,
|
||||
Key: rf,
|
||||
Service: servicename,
|
||||
}
|
||||
_, _, err = caller.mg.mongoClient.UpsertOne(CollectionFile, bson.M{
|
||||
"_id": newidobj,
|
||||
"service": servicename,
|
||||
"key": rf,
|
||||
}, newdoc)
|
||||
|
||||
@ -158,83 +206,48 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
mg := caller.mg
|
||||
logger.Println("blockAPI :", r.Method)
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
target, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
|
||||
if !ok {
|
||||
// 페이지네이션 해야할 듯
|
||||
//json.NewEncoder(w).Encode(mg.bl.all())
|
||||
} else if !target.IsZero() {
|
||||
var blocked []blockinfo
|
||||
if err := caller.mg.mongoClient.FindAllAs(CollectionBlock, bson.M{
|
||||
"accid": target,
|
||||
}, &blocked); err == nil {
|
||||
json.NewEncoder(w).Encode(blocked)
|
||||
}
|
||||
}
|
||||
case "PUT":
|
||||
var targets struct {
|
||||
Start primitive.DateTime
|
||||
End primitive.DateTime
|
||||
Accounts map[primitive.ObjectID]primitive.M // accid->meta
|
||||
}
|
||||
if err := gocommon.MakeDecoder(r).Decode(&targets); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for accid, meta := range targets.Accounts {
|
||||
bi := blockinfo{
|
||||
Start: targets.Start,
|
||||
End: targets.End,
|
||||
Meta: meta,
|
||||
}
|
||||
|
||||
_, 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)
|
||||
mg.sessionProvider.RevokeAll(accid)
|
||||
}
|
||||
}
|
||||
case "DELETE":
|
||||
id := r.URL.Query().Get("id")
|
||||
|
||||
if len(id) == 0 {
|
||||
return errors.New("id param is missing")
|
||||
}
|
||||
idobj, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mg.mongoClient.Delete(CollectionBlock, bson.M{"_id": idobj})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
mg := caller.mg
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
var all []whitelistmember
|
||||
if err := mg.mongoClient.AllAs(CollectionWhitelist, &all); err == nil {
|
||||
enc := json.NewEncoder(w)
|
||||
enc.Encode(all)
|
||||
queryvals := r.URL.Query()
|
||||
if r.Method == "GET" {
|
||||
// if !caller.isAdminOrValidToken() {
|
||||
// logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
|
||||
// w.WriteHeader(http.StatusUnauthorized)
|
||||
// return nil
|
||||
// }
|
||||
|
||||
all, err := mg.mongoClient.All(CollectionWhitelist)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "PUT":
|
||||
|
||||
if len(all) > 0 {
|
||||
var notexp []primitive.M
|
||||
for _, v := range all {
|
||||
if _, exp := v["_ts"]; !exp {
|
||||
notexp = append(notexp, v)
|
||||
}
|
||||
}
|
||||
allraw, _ := json.Marshal(notexp)
|
||||
w.Write(allraw)
|
||||
}
|
||||
} else if r.Method == "PUT" {
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
var member whitelistmember
|
||||
if err := json.Unmarshal(body, &member); err != nil {
|
||||
return err
|
||||
}
|
||||
member.ExpiredAt = 0
|
||||
member.Id = primitive.NewObjectID()
|
||||
|
||||
// if !caller.isAdminOrValidToken() {
|
||||
// logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
|
||||
// w.WriteHeader(http.StatusUnauthorized)
|
||||
// return nil
|
||||
// }
|
||||
|
||||
member.Expired = 0
|
||||
|
||||
_, _, err := mg.mongoClient.Update(CollectionWhitelist, bson.M{
|
||||
"_id": member.Id,
|
||||
"_id": primitive.NewObjectID(),
|
||||
}, bson.M{
|
||||
"$set": &member,
|
||||
}, options.Update().SetUpsert(true))
|
||||
@ -242,9 +255,8 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "DELETE":
|
||||
id := r.URL.Query().Get("id")
|
||||
|
||||
} else if r.Method == "DELETE" {
|
||||
id := queryvals.Get("id")
|
||||
if len(id) == 0 {
|
||||
return errors.New("id param is missing")
|
||||
}
|
||||
@ -270,20 +282,20 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
|
||||
func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
mg := caller.mg
|
||||
if r.Method == "GET" {
|
||||
logger.Println("serviceAPI :", r.URL.Path)
|
||||
if mg.service().Id.IsZero() {
|
||||
logger.Println(" id is zero")
|
||||
newService := serviceDescription{
|
||||
ServiceDescriptionSummary: ServiceDescriptionSummary{
|
||||
Id: primitive.NewObjectID(),
|
||||
},
|
||||
}
|
||||
if err := newService.prepare(caller.mg); err != nil {
|
||||
logger.Println(" prepare failed :", err)
|
||||
return err
|
||||
}
|
||||
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&newService))
|
||||
}
|
||||
|
||||
w.Write(mg.service().serviceSerialized)
|
||||
serptr := atomic.LoadPointer(&mg.service().serviceSerialized)
|
||||
w.Write(*(*[]byte)(serptr))
|
||||
} else if r.Method == "POST" {
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
var service serviceDescription
|
||||
@ -318,7 +330,8 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
|
||||
func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
mg := caller.mg
|
||||
if r.Method == "GET" {
|
||||
w.Write(mg.service().divisionsSerialized)
|
||||
serptr := atomic.LoadPointer(&mg.service().divisionsSerialized)
|
||||
w.Write(*(*[]byte)(serptr))
|
||||
} else if r.Method == "POST" {
|
||||
var divs map[string]*Division
|
||||
dec := json.NewDecoder(r.Body)
|
||||
@ -342,115 +355,10 @@ func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (caller apiCaller) couponAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
switch r.Method {
|
||||
case "PUT":
|
||||
// 쿠폰 생성
|
||||
logger.Println("begin generateCoupons")
|
||||
generateCoupons(caller.mg.mongoClient, w, r)
|
||||
|
||||
case "POST":
|
||||
// TODO : 쿠폰 사용
|
||||
// 쿠폰 사용 표시 해주고 내용을 응답
|
||||
logger.Println("begin useCoupon")
|
||||
useCoupon(caller.mg.mongoClient, w, r)
|
||||
|
||||
case "GET":
|
||||
// 쿠폰 조회
|
||||
if r.Form.Has("code") {
|
||||
// 쿠폰 코드 조회
|
||||
logger.Println("begin queryCoupon")
|
||||
queryCoupon(caller.mg.mongoClient, w, r)
|
||||
} else if r.Form.Has("name") {
|
||||
// 쿠폰 코드 다운
|
||||
logger.Println("begin downloadCoupons")
|
||||
downloadCoupons(caller.mg.mongoClient, w, r)
|
||||
} else {
|
||||
// 쿠폰 이름 목록
|
||||
logger.Println("begin listAllCouponNames")
|
||||
listAllCouponNames(caller.mg.mongoClient, w, r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type accountlinkinfo struct {
|
||||
Uid string `json:"uid"`
|
||||
Platform string `json:"platform"`
|
||||
}
|
||||
|
||||
func (caller apiCaller) userinfoAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
mg := caller.mg
|
||||
if r.Method == "GET" {
|
||||
// 계정 조회
|
||||
accid, _ := gocommon.ReadObjectIDFormValue(r.Form, "accid")
|
||||
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 {
|
||||
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 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
var errApiTokenMissing = errors.New("mg-x-api-token is missing")
|
||||
|
||||
func (caller apiCaller) configAPI(w http.ResponseWriter, r *http.Request) error {
|
||||
mg := caller.mg
|
||||
|
||||
if !*devflag {
|
||||
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
||||
if len(apitoken) == 0 {
|
||||
return errApiTokenMissing
|
||||
@ -460,7 +368,6 @@ func (caller apiCaller) configAPI(w http.ResponseWriter, r *http.Request) error
|
||||
if !mg.service().isValidToken(apitokenObj) {
|
||||
return fmt.Errorf("mg-x-api-token is not valid : %s", apitoken)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -485,11 +392,9 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body.Close()
|
||||
}()
|
||||
|
||||
r.ParseMultipartForm(32 << 20)
|
||||
|
||||
var userinfo map[string]any
|
||||
|
||||
if !*devflag {
|
||||
if !*noauth {
|
||||
authheader := r.Header.Get("Authorization")
|
||||
if len(authheader) == 0 {
|
||||
logger.Println("Authorization header is not valid :", authheader)
|
||||
@ -523,18 +428,17 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
||||
ptr := atomic.LoadPointer(&mg.admins)
|
||||
adminsptr := (*globalAdmins)(ptr)
|
||||
|
||||
if adminsptr.modtime != gocommon.ConfigModTime() {
|
||||
if adminsptr.modtime != common.ConfigModTime() {
|
||||
var config globalAdmins
|
||||
if err := gocommon.LoadConfig(&config); err == nil {
|
||||
if err := common.LoadConfig(&config); err == nil {
|
||||
config.parse()
|
||||
adminsptr = &config
|
||||
atomic.StorePointer(&mg.admins, unsafe.Pointer(adminsptr))
|
||||
}
|
||||
}
|
||||
|
||||
var apiTokenObj primitive.ObjectID
|
||||
if !*devflag {
|
||||
apiToken := r.Header.Get("MG-X-API-TOKEN")
|
||||
var apiTokenObj primitive.ObjectID
|
||||
if len(apiToken) > 0 {
|
||||
obj, err := primitive.ObjectIDFromHex(apiToken)
|
||||
if err != nil {
|
||||
@ -544,7 +448,6 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
apiTokenObj = obj
|
||||
}
|
||||
}
|
||||
|
||||
logger.Println("api call :", r.URL.Path, r.Method, r.URL.Query(), userinfo)
|
||||
caller := apiCaller{
|
||||
@ -567,12 +470,6 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
||||
err = caller.maintenanceAPI(w, r)
|
||||
} else if strings.HasSuffix(r.URL.Path, "/files") {
|
||||
err = caller.filesAPI(w, r)
|
||||
} else if strings.HasSuffix(r.URL.Path, "/block") {
|
||||
err = caller.blockAPI(w, r)
|
||||
} else if strings.HasSuffix(r.URL.Path, "/coupon") {
|
||||
err = caller.couponAPI(w, r)
|
||||
} else if strings.HasSuffix(r.URL.Path, "/userinfo") {
|
||||
err = caller.userinfoAPI(w, r)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
@ -1,377 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"repositories.action2quare.com/ayo/gocommon"
|
||||
coupon "repositories.action2quare.com/ayo/gocommon/coupon"
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
CollectionCoupon = gocommon.CollectionName("coupon")
|
||||
CollectionCouponUse = gocommon.CollectionName("coupon_use")
|
||||
)
|
||||
|
||||
type couponDoc struct {
|
||||
Name string `json:"name" bson:"name"`
|
||||
Effect string `json:"effect" bson:"effect"`
|
||||
Desc string `json:"desc" bson:"desc"`
|
||||
Total int64 `json:"total" bson:"total"`
|
||||
Remains []string `json:"remains,omitempty" bson:"remains,omitempty"`
|
||||
Used []string `json:"used,omitempty" bson:"used,omitempty"`
|
||||
}
|
||||
|
||||
func makeCouponKey(roundnum uint32, uid []byte) string {
|
||||
left := binary.BigEndian.Uint16(uid[0:2])
|
||||
right := binary.BigEndian.Uint16(uid[2:4])
|
||||
multi := uint32(left) * uint32(right)
|
||||
xor := roundnum ^ multi
|
||||
|
||||
final := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint32(final, xor)
|
||||
copy(final[4:], uid)
|
||||
return fmt.Sprintf("%s-%s-%s-%s", hex.EncodeToString(final[0:2]), hex.EncodeToString(final[2:4]), hex.EncodeToString(final[4:6]), hex.EncodeToString(final[6:8]))
|
||||
}
|
||||
|
||||
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
func makeCouponCodes(name string, count int) (string, map[string]string) {
|
||||
checkunique := make(map[string]bool)
|
||||
keys := make(map[string]string)
|
||||
uid := make([]byte, 4)
|
||||
|
||||
roundHash, roundnum := coupon.MakeCouponRoundHash(name)
|
||||
|
||||
for len(keys) < count {
|
||||
r.Read(uid)
|
||||
|
||||
code := makeCouponKey(roundnum, uid)
|
||||
|
||||
if _, ok := checkunique[code]; !ok {
|
||||
checkunique[code] = true
|
||||
keys[hex.EncodeToString(uid)] = code
|
||||
}
|
||||
}
|
||||
return roundHash, keys
|
||||
}
|
||||
|
||||
func generateCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||
name, _ := gocommon.ReadStringFormValue(r.Form, "name")
|
||||
effect, _ := gocommon.ReadStringFormValue(r.Form, "effect")
|
||||
count, _ := gocommon.ReadIntegerFormValue(r.Form, "count")
|
||||
desc, _ := gocommon.ReadStringFormValue(r.Form, "desc")
|
||||
|
||||
if count == 0 {
|
||||
logger.Println("[generateCoupons] count == 0")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
roundHash, _ := coupon.MakeCouponRoundHash(name)
|
||||
roundObj, _ := primitive.ObjectIDFromHex(roundHash + roundHash + roundHash)
|
||||
|
||||
if count < 0 {
|
||||
// 무한 쿠폰이므로 그냥 문서 생성해 주고 끝
|
||||
if _, _, err := mongoClient.Update(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
}, bson.M{
|
||||
"$set": &couponDoc{
|
||||
Name: name,
|
||||
Effect: effect,
|
||||
Desc: desc,
|
||||
Total: -1,
|
||||
},
|
||||
}, options.Update().SetUpsert(true)); err != nil {
|
||||
logger.Println("[generateCoupons] Update failed :", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// effect가 비어있으면 기존의 roundName에 갯수를 추가해 준다
|
||||
// effect가 비어있지 않으면 roundName이 겹쳐서는 안된다.
|
||||
coupondoc, err := mongoClient.FindOne(CollectionCoupon, bson.M{"_id": roundObj})
|
||||
if err != nil {
|
||||
logger.Println("[generateCoupons] FindOne failed :", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
lastKeys := make(map[string]bool)
|
||||
if coupondoc != nil {
|
||||
if r, ok := coupondoc["remains"]; ok {
|
||||
remains := r.(primitive.A)
|
||||
for _, uid := range remains {
|
||||
lastKeys[uid.(string)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issuedKeys := make(map[string]string)
|
||||
for len(issuedKeys) < int(count) {
|
||||
_, vs := makeCouponCodes(name, int(count)-len(issuedKeys))
|
||||
for k, v := range vs {
|
||||
if _, ok := lastKeys[k]; !ok {
|
||||
// 기존 키와 중복되지 않는 것만
|
||||
issuedKeys[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var coupons []string
|
||||
var uids []string
|
||||
for uid, code := range issuedKeys {
|
||||
uids = append(uids, uid)
|
||||
coupons = append(coupons, code)
|
||||
}
|
||||
|
||||
if coupondoc != nil {
|
||||
_, _, err = mongoClient.Update(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
}, bson.M{
|
||||
"$push": bson.M{"remains": bson.M{"$each": uids}},
|
||||
"$inc": bson.M{"total": count},
|
||||
}, options.Update().SetUpsert(true))
|
||||
} else {
|
||||
_, _, err = mongoClient.Update(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
}, bson.M{
|
||||
"$push": bson.M{"remains": bson.M{"$each": uids}},
|
||||
"$set": couponDoc{
|
||||
Name: name,
|
||||
Effect: effect,
|
||||
Desc: desc,
|
||||
Total: count,
|
||||
},
|
||||
}, options.Update().SetUpsert(true))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Println("[generateCoupons] Update failed :", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
enc.Encode(coupons)
|
||||
}
|
||||
|
||||
func downloadCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||
name, _ := gocommon.ReadStringFormValue(r.Form, "name")
|
||||
if len(name) == 0 {
|
||||
logger.Println("[downloadCoupons] name is empty")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
round, _ := coupon.MakeCouponRoundHash(name)
|
||||
|
||||
roundObj, err := primitive.ObjectIDFromHex(round + round + round)
|
||||
if err != nil {
|
||||
// 유효하지 않은 형식의 code
|
||||
logger.Println("[downloadCoupons] ObjectIDFromHex failed :", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var coupon couponDoc
|
||||
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
}, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "remains": 1})); err != nil {
|
||||
logger.Println("[downloadCoupons] FindOne failed :", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
roundnum := binary.BigEndian.Uint32(roundObj[:])
|
||||
var coupons []string
|
||||
for _, uid := range coupon.Remains {
|
||||
decUid, err := hex.DecodeString(uid)
|
||||
if err != nil {
|
||||
logger.Println("downloadCoupons Fail", err)
|
||||
continue
|
||||
}
|
||||
coupons = append(coupons, makeCouponKey(roundnum, decUid))
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
enc.Encode(coupons)
|
||||
}
|
||||
|
||||
func queryCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||
code, _ := gocommon.ReadStringFormValue(r.Form, "code")
|
||||
if len(code) == 0 {
|
||||
logger.Println("[queryCoupon] code is empty")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
round, _ := coupon.DisolveCouponCode(code)
|
||||
if len(round) == 0 {
|
||||
// 유효하지 않은 형식의 code
|
||||
// 쿠폰 이름일 수 있으므로 round hash를 계산한다.
|
||||
round, _ = coupon.MakeCouponRoundHash(code)
|
||||
}
|
||||
|
||||
roundObj, err := primitive.ObjectIDFromHex(round + round + round)
|
||||
if err != nil {
|
||||
// 유효하지 않은 형식의 code
|
||||
logger.Println("[queryCoupon] ObjectIDFromHex failed :", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var coupon couponDoc
|
||||
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
}, &coupon, options.FindOne().SetProjection(bson.M{"effect": 1, "name": 1, "reason": 1, "total": 1, "desc": 1}).SetReturnKey(false)); err != nil {
|
||||
logger.Println("[queryCoupon] FindOneAs failed :", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
enc.Encode(coupon)
|
||||
}
|
||||
|
||||
func listAllCouponNames(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||
all, err := mongoClient.FindAll(CollectionCoupon, bson.M{}, options.Find().SetProjection(bson.M{"name": 1}))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var names []string
|
||||
for _, doc := range all {
|
||||
names = append(names, doc["name"].(string))
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
enc.Encode(names)
|
||||
}
|
||||
|
||||
func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||
acc, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
|
||||
if !ok || acc.IsZero() {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
code, _ := gocommon.ReadStringFormValue(r.Form, "code")
|
||||
code = strings.TrimSpace(code)
|
||||
if len(code) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
round, key := coupon.DisolveCouponCode(code)
|
||||
if len(round) == 0 {
|
||||
// couponId가 쿠폰 이름일 수도 있다. 무한 쿠폰
|
||||
round, _ = coupon.MakeCouponRoundHash(code)
|
||||
}
|
||||
|
||||
// 쿠폰 사용 유무 검사
|
||||
alreadyused, err := mongoClient.Exists(CollectionCouponUse, bson.M{
|
||||
"_id": acc,
|
||||
"rounds": round,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if alreadyused {
|
||||
// 이미 이 라운드의 쿠폰을 사용한 적이 있다.
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
return
|
||||
}
|
||||
|
||||
var coupon couponDoc
|
||||
roundObj, _ := primitive.ObjectIDFromHex(round + round + round)
|
||||
if len(key) == 0 {
|
||||
// 무한 쿠폰일 수 있으므로 존재하는지 확인
|
||||
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
}, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "effect": 1, "name": 1, "reason": 1, "total": 1})); err != nil {
|
||||
logger.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if coupon.Total > 0 {
|
||||
// 무한 쿠폰 아니네?
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// 2. 쿠폰을 하나 꺼냄
|
||||
matched, _, err := mongoClient.Update(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
"remains": key,
|
||||
}, bson.M{
|
||||
"$pull": bson.M{"remains": key},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if !matched {
|
||||
// 쿠폰이 없다.
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 3. round의 효과 읽기
|
||||
if err := mongoClient.FindOneAndUpdateAs(CollectionCoupon, bson.M{
|
||||
"_id": roundObj,
|
||||
}, bson.M{
|
||||
"$push": bson.M{"used": key},
|
||||
}, &coupon, options.FindOneAndUpdate().SetProjection(bson.M{"effect": 1})); err != nil {
|
||||
logger.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(coupon.Effect) == 0 {
|
||||
// 쿠폰이 없네?
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 4. 쿠폰은 사용한 것으로 표시
|
||||
// 이제 이 아래에서 실패하면 이 쿠폰은 못쓴다.
|
||||
updated, _, err := mongoClient.Update(CollectionCouponUse, bson.M{
|
||||
"_id": acc,
|
||||
}, bson.M{
|
||||
"$push": bson.M{"rounds": round},
|
||||
"$set": bson.M{round + ".id": code},
|
||||
"$currentDate": bson.M{round + ".ts": true},
|
||||
}, options.Update().SetUpsert(true))
|
||||
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if !updated {
|
||||
logger.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(coupon.Effect))
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMakeLocalUniqueId(t *testing.T) {
|
||||
|
||||
}
|
||||
512
core/maingate.go
512
core/maingate.go
@ -9,19 +9,17 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"text/template"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"repositories.action2quare.com/ayo/gocommon"
|
||||
common "repositories.action2quare.com/ayo/gocommon"
|
||||
"repositories.action2quare.com/ayo/gocommon/flagx"
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
"repositories.action2quare.com/ayo/gocommon/session"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
@ -36,29 +34,27 @@ import (
|
||||
|
||||
var devflag = flagx.Bool("dev", false, "")
|
||||
var noauth = flagx.Bool("noauth", false, "")
|
||||
var authtype = flagx.String("auth", "on", "on|off|both")
|
||||
|
||||
var (
|
||||
CollectionLink = gocommon.CollectionName("link")
|
||||
CollectionWhitelist = gocommon.CollectionName("whitelist")
|
||||
CollectionService = gocommon.CollectionName("service")
|
||||
CollectionAccount = gocommon.CollectionName("account")
|
||||
CollectionFile = gocommon.CollectionName("file")
|
||||
CollectionBlock = gocommon.CollectionName("block")
|
||||
CollectionPlatformLoginToken = gocommon.CollectionName("platform_login_token") //-- 각 플랫폼에 로그인 및 권한 받아오는 과정에 사용하는 Key
|
||||
CollectionUserToken = gocommon.CollectionName("usertoken")
|
||||
CollectionGamepotUserInfo = gocommon.CollectionName("gamepot_userinfo") //-- 클라로부터 수집된 gamepot 정보 - server to server로 유효성이 검증되진 않았지만 수집은 한다.
|
||||
CollectionFirebaseUserInfo = gocommon.CollectionName("firebase_userinfo") //-- Firebase UserInfo
|
||||
CollectionLink = common.CollectionName("link")
|
||||
CollectionAuth = common.CollectionName("auth")
|
||||
CollectionWhitelist = common.CollectionName("whitelist")
|
||||
CollectionService = common.CollectionName("service")
|
||||
CollectionAccount = common.CollectionName("account")
|
||||
CollectionFile = common.CollectionName("file")
|
||||
CollectionBlock = common.CollectionName("block")
|
||||
CollectionPlatformLoginToken = common.CollectionName("platform_login_token") //-- 각 플랫폼에 로그인 및 권한 받아오는 과정에 사용하는 Key
|
||||
CollectionUserToken = common.CollectionName("usertoken")
|
||||
CollectionGamepotUserInfo = common.CollectionName("gamepot_userinfo") //-- 클라로부터 수집된 gamepot 정보 - server to server로 유효성이 검증되진 않았지만 수집은 한다.
|
||||
CollectionFirebaseUserInfo = common.CollectionName("firebase_userinfo") //-- Firebase UserInfo
|
||||
)
|
||||
|
||||
const (
|
||||
AuthPlatformSteamSDK = "steam"
|
||||
AuthPlatformFirebaseAuth = "firebase"
|
||||
AuthPlatformGoogle = "google"
|
||||
AuthPlatformMicrosoft = "microsoft"
|
||||
AuthPlatformApple = "apple"
|
||||
AuthPlatformTwitter = "twitter"
|
||||
AuthPlatformHybeim = "hybeim"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -74,13 +70,56 @@ func SessionTTL() time.Duration {
|
||||
return sessionTTL
|
||||
}
|
||||
|
||||
type mongoAuthCell struct {
|
||||
src *common.Authinfo
|
||||
}
|
||||
|
||||
func (ac *mongoAuthCell) ToAuthinfo() *common.Authinfo {
|
||||
if ac.src == nil {
|
||||
logger.Error("mongoAuthCell ToAuthinfo failed. ac.src is nil")
|
||||
}
|
||||
return ac.src
|
||||
}
|
||||
|
||||
func (ac *mongoAuthCell) ToBytes() []byte {
|
||||
bt, _ := json.Marshal(ac.src)
|
||||
return bt
|
||||
}
|
||||
|
||||
func makeAuthCollection(mongoClient common.MongoClient, sessionTTL time.Duration) *common.AuthCollection {
|
||||
authcoll := common.MakeAuthCollection(sessionTTL)
|
||||
authcoll.SessionRemoved = func(sk string) {
|
||||
skid, _ := primitive.ObjectIDFromHex(sk)
|
||||
mongoClient.Delete(CollectionAuth, bson.M{
|
||||
"sk": skid,
|
||||
})
|
||||
}
|
||||
authcoll.QuerySession = func(sk string, token string) common.AuthinfoCell {
|
||||
skid, _ := primitive.ObjectIDFromHex(sk)
|
||||
var outcell mongoAuthCell
|
||||
err := mongoClient.FindOneAs(CollectionAuth, bson.M{
|
||||
"sk": skid,
|
||||
}, &outcell.src, options.FindOne().SetHint("skonly"))
|
||||
|
||||
if err != nil {
|
||||
logger.Error("QuerySession failed :", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if outcell.src == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &outcell
|
||||
}
|
||||
|
||||
return authcoll
|
||||
}
|
||||
|
||||
type maingateConfig struct {
|
||||
session.SessionConfig `json:",inline"`
|
||||
MustUseChecksum bool `json:"maingate_must_checksum"`
|
||||
Mongo string `json:"maingate_mongodb_url"`
|
||||
SessionTTL int64 `json:"maingate_session_ttl"`
|
||||
Autologin_ttl int64 `json:"autologin_ttl"`
|
||||
AccDelTTL int64 `json:"acc_del_ttl"`
|
||||
MaximumNumLinkAccount int64 `json:"maximum_num_link_account"`
|
||||
RedirectBaseUrl string `json:"redirect_base_url"`
|
||||
GoogleClientId string `json:"google_client_id"`
|
||||
GoogleClientSecret string `json:"google_client_secret"`
|
||||
@ -98,26 +137,6 @@ type maingateConfig struct {
|
||||
GamepotProjectId string `json:"gamepot_project_id"`
|
||||
GamepotLoginCheckAPIURL string `json:"gamepot_logincheckapi_url"`
|
||||
FirebaseAdminSDKCredentialFile string `json:"firebase_admin_sdk_credentialfile"`
|
||||
SteamAppId string `json:"steam_app_id"`
|
||||
SteamPublisherAuthKey string `json:"steam_publisher_authkey"`
|
||||
GlobalMaingateToken string `json:"maingate_api_token"`
|
||||
HybeImProjectIdstring string `json:"hybeim_projectid"`
|
||||
HybeImServiceIdstring string `json:"hybeim_serviceid"`
|
||||
HybeImAccessKey string `json:"hybeim_acesskey"`
|
||||
HybeImEndPoint string `json:"hybeim_Endpoint"`
|
||||
|
||||
Firebase_Google_Analytics_JS_SDK_Config
|
||||
}
|
||||
|
||||
type Firebase_Google_Analytics_JS_SDK_Config struct {
|
||||
FGA_apiKey string `json:"firebase_google_analytics_jssdk_apikey"`
|
||||
FGA_authDomain string `json:"firebase_google_analytics_jssdk_authdomain"`
|
||||
FGA_databaseURL string `json:"firebase_google_analytics_jssdk_databaseurl"`
|
||||
FGA_projectId string `json:"firebase_google_analytics_jssdk_projectid"`
|
||||
FGA_storageBucket string `json:"firebase_google_analytics_jssdk_storagebucket"`
|
||||
FGA_messagingSenderId string `json:"firebase_google_analytics_jssdk_messagingsenderid"`
|
||||
FGA_appId string `json:"firebase_google_analytics_jssdk_apiid"`
|
||||
FGA_measurementId string `json:"ffirebase_google_analytics_jssdk_measurementid"`
|
||||
}
|
||||
|
||||
type globalAdmins struct {
|
||||
@ -132,53 +151,63 @@ func (ga *globalAdmins) parse() {
|
||||
parsed[admin] = true
|
||||
}
|
||||
ga.emails = parsed
|
||||
ga.modtime = gocommon.ConfigModTime()
|
||||
}
|
||||
|
||||
type firebaseClient struct {
|
||||
firebaseAppClient *auth.Client
|
||||
firebaseAppContext context.Context
|
||||
ga.modtime = common.ConfigModTime()
|
||||
}
|
||||
|
||||
// Maingate :
|
||||
type Maingate struct {
|
||||
mongoClient gocommon.MongoClient
|
||||
maingateConfig
|
||||
|
||||
sessionProvider session.Provider
|
||||
mongoClient common.MongoClient
|
||||
|
||||
auths *common.AuthCollection
|
||||
//services servicelist
|
||||
serviceptr unsafe.Pointer
|
||||
admins unsafe.Pointer
|
||||
wl whitelist
|
||||
|
||||
tokenEndpoints map[string]string
|
||||
authorizationEndpoints map[string]string
|
||||
userinfoEndpoint map[string]string
|
||||
jwksUri map[string]string
|
||||
|
||||
firebase *firebaseClient
|
||||
firebaseAppClient *auth.Client
|
||||
firebaseAppContext context.Context
|
||||
}
|
||||
|
||||
var config maingateConfig
|
||||
var collectionNameMod = int32(0)
|
||||
|
||||
// New :
|
||||
func New(ctx context.Context) (*Maingate, error) {
|
||||
if err := gocommon.LoadConfig(&config); err != nil {
|
||||
if *devflag && atomic.AddInt32(&collectionNameMod, 1) == 1 {
|
||||
hostname, _ := os.Hostname()
|
||||
CollectionLink = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionLink)))
|
||||
CollectionAuth = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionAuth)))
|
||||
CollectionWhitelist = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionWhitelist)))
|
||||
CollectionService = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionService)))
|
||||
CollectionAccount = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionAccount)))
|
||||
CollectionBlock = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionBlock)))
|
||||
CollectionPlatformLoginToken = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionPlatformLoginToken)))
|
||||
CollectionUserToken = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionUserToken)))
|
||||
CollectionGamepotUserInfo = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionGamepotUserInfo)))
|
||||
CollectionFirebaseUserInfo = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionFirebaseUserInfo)))
|
||||
}
|
||||
|
||||
var config maingateConfig
|
||||
if err := common.LoadConfig(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var admins globalAdmins
|
||||
if err := gocommon.LoadConfig(&admins); err == nil {
|
||||
if err := common.LoadConfig(&admins); err == nil {
|
||||
admins.parse()
|
||||
}
|
||||
|
||||
if len(config.SessionStorage) == 0 {
|
||||
return nil, errors.New("maingate_session_storage is missing")
|
||||
}
|
||||
|
||||
if config.SessionTTL == 0 {
|
||||
config.SessionTTL = 3600
|
||||
}
|
||||
|
||||
mg := Maingate{
|
||||
maingateConfig: config,
|
||||
admins: unsafe.Pointer(&admins),
|
||||
tokenEndpoints: make(map[string]string),
|
||||
authorizationEndpoints: make(map[string]string),
|
||||
@ -188,32 +217,22 @@ func New(ctx context.Context) (*Maingate, error) {
|
||||
|
||||
err := mg.prepare(ctx)
|
||||
if err != nil {
|
||||
logger.Error("mg.prepare() failed :", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(*authtype) == 0 {
|
||||
*authtype = "on"
|
||||
}
|
||||
|
||||
if !*noauth && (*authtype == "on" || *authtype == "both") {
|
||||
if len(config.FirebaseAdminSDKCredentialFile) > 0 {
|
||||
opt := option.WithCredentialsFile(config.FirebaseAdminSDKCredentialFile)
|
||||
if !*noauth {
|
||||
opt := option.WithCredentialsFile(mg.FirebaseAdminSDKCredentialFile)
|
||||
firebaseApp, err := firebase.NewApp(context.Background(), nil, opt)
|
||||
if err != nil {
|
||||
logger.Error("firebase admin error initializing app failed :", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
firebaseAppClient, err := firebaseApp.Auth(ctx)
|
||||
mg.firebaseAppContext = ctx
|
||||
mg.firebaseAppClient, err = firebaseApp.Auth(mg.firebaseAppContext)
|
||||
if err != nil {
|
||||
logger.Println("FirebaseAppClient error getting Auth client:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mg.firebase = &firebaseClient{
|
||||
firebaseAppContext: ctx,
|
||||
firebaseAppClient: firebaseAppClient,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,113 +299,101 @@ func (mg *Maingate) discoverOpenIdConfiguration(name string, url string) error {
|
||||
|
||||
func (mg *Maingate) prepare(context context.Context) (err error) {
|
||||
if err := mg.discoverOpenIdConfiguration(AuthPlatformMicrosoft, "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
if err := mg.discoverOpenIdConfiguration("google", "https://accounts.google.com/.well-known/openid-configuration"); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// redis에서 env를 가져온 후에
|
||||
mg.mongoClient, err = gocommon.NewMongoClient(context, config.Mongo)
|
||||
mg.mongoClient, err = common.NewMongoClient(context, mg.Mongo, "maingate")
|
||||
if err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionCouponUse, map[string]bson.D{
|
||||
"idrounds": {{Key: "_id", Value: 1}, {Key: "rounds", Value: 1}},
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionAuth, map[string]bson.D{
|
||||
"skonly": {{Key: "sk", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
|
||||
"platformuid": {{Key: "platform", Value: 1}, {Key: "uid", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeIndices(CollectionAccount, map[string]bson.D{
|
||||
"accid": {{Key: "accid", Value: 1}},
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeIndices(CollectionWhitelist, map[string]bson.D{
|
||||
"service": {{Key: "service", Value: 1}},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeIndices(CollectionFile, map[string]bson.D{
|
||||
"service": {{Key: "service", Value: 1}},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionFile, map[string]bson.D{
|
||||
"keyonly": {{Key: "key", Value: 1}},
|
||||
"sk": {{Key: "service", Value: 1}, {Key: "key", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeExpireIndex(CollectionAccount, int32(config.AccDelTTL)); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeExpireIndex(CollectionLink, int32(config.AccDelTTL)); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
}
|
||||
|
||||
// Delete대신 _ts로 expire시킴. pipeline에 삭제 알려주기 위함
|
||||
if err = mg.mongoClient.MakeExpireIndex(CollectionWhitelist, 10); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if *devflag {
|
||||
// 에러 체크하지 말것
|
||||
mg.mongoClient.DropIndex(CollectionBlock, "codeaccid")
|
||||
}
|
||||
|
||||
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.MakeExpireIndex(CollectionAuth, int32(mg.SessionTTL+300)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionBlock, map[string]bson.D{
|
||||
"accidend": {{Key: "accid", Value: 1}, {Key: "end", Value: 1}},
|
||||
"codeaccid": {{Key: "code", Value: 1}, {Key: "accid", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeExpireIndex(CollectionBlock, int32(3)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionPlatformLoginToken, map[string]bson.D{
|
||||
"platformauthtoken": {{Key: "platform", Value: 1}, {Key: "key", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(config.SessionTTL+300)); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(mg.SessionTTL+300)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionUserToken, map[string]bson.D{
|
||||
"platformusertoken": {{Key: "platform", Value: 1}, {Key: "userid", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionGamepotUserInfo, map[string]bson.D{
|
||||
"gamepotuserid": {{Key: "gamepotuserid", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionFirebaseUserInfo, map[string]bson.D{
|
||||
"firebaseuserid": {{Key: "firebaseuserid", Value: 1}},
|
||||
}); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
mg.sessionProvider, err = session.NewProviderWithConfig(context, config.SessionConfig)
|
||||
if err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
}
|
||||
mg.auths = makeAuthCollection(mg.mongoClient, time.Duration(mg.SessionTTL*int64(time.Second)))
|
||||
|
||||
var preall []struct {
|
||||
Link string `bson:"link"`
|
||||
@ -395,7 +402,7 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
|
||||
if err = mg.mongoClient.FindAllAs(CollectionFile, nil, &preall, options.Find().SetProjection(bson.M{
|
||||
"link": 1,
|
||||
})); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pre := range preall {
|
||||
@ -405,104 +412,92 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
|
||||
}
|
||||
logger.Println("saving files :", pre.Link)
|
||||
|
||||
var fulldoc FileDocumentDesc
|
||||
var fulldoc fileDocumentDesc
|
||||
err = mg.mongoClient.FindOneAs(CollectionFile, bson.M{
|
||||
"_id": pre.Id,
|
||||
}, &fulldoc)
|
||||
if err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
err = fulldoc.Save()
|
||||
err = fulldoc.save()
|
||||
if err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var whites []whitelistmember
|
||||
if err := mg.mongoClient.AllAs(CollectionWhitelist, &whites, options.Find().SetReturnKey(false)); err != nil {
|
||||
return err
|
||||
}
|
||||
mg.wl.init(whites)
|
||||
|
||||
go watchAuthCollection(context, mg.auths, mg.mongoClient)
|
||||
go mg.watchWhitelistCollection(context)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var portptr = flagx.Int("port", 80, "")
|
||||
func whitelistKey(email string) string {
|
||||
if strings.HasPrefix(email, "*@") {
|
||||
// 도메인 전체 허용
|
||||
return email[2:]
|
||||
}
|
||||
|
||||
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) error {
|
||||
return email
|
||||
}
|
||||
|
||||
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error {
|
||||
var allServices []*serviceDescription
|
||||
if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
|
||||
if *noauth {
|
||||
host, _ := os.Hostname()
|
||||
empty := serviceDescription{
|
||||
ServiceDescriptionSummary: ServiceDescriptionSummary{
|
||||
ServiceCode: "000000000000",
|
||||
},
|
||||
Divisions: map[string]*Division{
|
||||
host: {
|
||||
DivisionForUser: DivisionForUser{
|
||||
Priority: 0,
|
||||
State: DivisionState_FullOpen,
|
||||
},
|
||||
Url: fmt.Sprintf("http://%s/warehouse", host),
|
||||
},
|
||||
},
|
||||
}
|
||||
empty.prepare(mg)
|
||||
allServices = append(allServices, &empty)
|
||||
} else if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(allServices) > 0 {
|
||||
only := allServices[0]
|
||||
only.prepare(mg)
|
||||
only.mustUseChecksum = config.MustUseChecksum
|
||||
|
||||
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(only))
|
||||
} else {
|
||||
empty := serviceDescription{
|
||||
ServiceDescriptionSummary: ServiceDescriptionSummary{
|
||||
Id: primitive.NewObjectID(),
|
||||
}
|
||||
|
||||
if *devflag {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
}
|
||||
ipaddr := "127.0.0.1"
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil && ipnet.IP.IsPrivate() {
|
||||
ipaddr = ipnet.IP.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
empty.Divisions = map[string]*Division{
|
||||
"default": {
|
||||
DivisionForUser: DivisionForUser{
|
||||
Priority: 0,
|
||||
State: DivisionState_FullOpen,
|
||||
},
|
||||
|
||||
Urls: bson.M{
|
||||
"warehouse": fmt.Sprintf("http://%s:%d/warehouse", ipaddr, *portptr),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
empty.prepare(mg)
|
||||
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&empty))
|
||||
|
||||
filter := bson.M{"_id": empty.Id}
|
||||
_, _, err := mg.mongoClient.Update(CollectionService, filter, bson.M{
|
||||
"$set": &empty,
|
||||
}, options.Update().SetUpsert(true))
|
||||
|
||||
if err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
if *devflag {
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "/"), func(w http.ResponseWriter, r *http.Request) {
|
||||
// mg.service()를 요청마다 불러야 함
|
||||
mg.service().serveHTTP_dev(w, r)
|
||||
})
|
||||
} else {
|
||||
pattern := gocommon.MakeHttpHandlerPattern(prefix, "/")
|
||||
logger.Println("pattern registered :", pattern)
|
||||
serveMux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||
// mg.service()를 요청마다 불러야 함
|
||||
mg.service().serveHTTP(w, r)
|
||||
})
|
||||
}
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "api/"), mg.api)
|
||||
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)
|
||||
|
||||
configraw, _ := json.Marshal(config)
|
||||
configraw, _ := json.Marshal(mg.maingateConfig)
|
||||
var convertedConfig map[string]any
|
||||
if err := json.Unmarshal(configraw, &convertedConfig); err != nil {
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "config"), func(w http.ResponseWriter, r *http.Request) {
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "config"), func(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
s := recover()
|
||||
if s != nil {
|
||||
@ -510,7 +505,7 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
|
||||
}
|
||||
}()
|
||||
|
||||
if !*devflag {
|
||||
if !*noauth {
|
||||
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
||||
if len(apitoken) == 0 {
|
||||
logger.Println("MG-X-API-TOKEN is missing")
|
||||
@ -522,8 +517,6 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
|
||||
if mg.service().isValidToken(apitokenObj) {
|
||||
convertedConfig["divisions"] = mg.service().Divisions
|
||||
}
|
||||
} else {
|
||||
convertedConfig["divisions"] = mg.service().Divisions
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
@ -532,49 +525,33 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
|
||||
|
||||
if err := os.MkdirAll("static", os.ModePerm); err != nil {
|
||||
// 일반 엔드유저한테 오픈할 static 페이지
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
cfsx := http.FileServer(http.Dir("console"))
|
||||
pattern := gocommon.MakeHttpHandlerPattern(prefix, "console", "/")
|
||||
serveMux.Handle(pattern, http.StripPrefix(pattern, cfsx))
|
||||
logger.Println("maingate console registered :", pattern)
|
||||
fsx := http.FileServer(http.Dir("./console"))
|
||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, "console/"), http.StripPrefix("/console/", fsx))
|
||||
|
||||
staticfs := http.FileServer(http.Dir("static"))
|
||||
pattern = gocommon.MakeHttpHandlerPattern(prefix, "static", "/")
|
||||
serveMux.Handle(pattern, http.StripPrefix(pattern, staticfs))
|
||||
logger.Println("maingate static registered :", pattern)
|
||||
ssx := http.FileServer(http.Dir("./static"))
|
||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, "static/"), http.StripPrefix("/static/", ssx))
|
||||
|
||||
fbafs := http.FileServer(http.Dir("fba"))
|
||||
pattern = gocommon.MakeHttpHandlerPattern(prefix, "fba", "/")
|
||||
serveMux.Handle(pattern, http.StripPrefix(pattern, fbafs))
|
||||
logger.Println("google_analytics static registered :", pattern)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformGoogle), mg.platform_google_get_login_url)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformGoogle), mg.platform_google_authorize)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformGoogle), mg.platform_google_authorize_result)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "fba", "fb-ga.min.js"), mg.google_analytics_js)
|
||||
logger.Println("google_analytics.js static registered :", pattern)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformMicrosoft), mg.platform_microsoft_get_login_url)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformMicrosoft), mg.platform_microsoft_authorize)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformMicrosoft), mg.platform_microsoft_authorize_result)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformGoogle), mg.platform_google_get_login_url)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformGoogle), mg.platform_google_authorize)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformGoogle), mg.platform_google_authorize_result)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformTwitter), mg.platform_twitter_get_login_url)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformTwitter), mg.platform_twitter_authorize)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformTwitter), mg.platform_twitter_authorize_result)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformMicrosoft), mg.platform_microsoft_get_login_url)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformMicrosoft), mg.platform_microsoft_authorize)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformMicrosoft), mg.platform_microsoft_authorize_result)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformApple), mg.platform_apple_get_login_url)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformApple), mg.platform_apple_authorize)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformApple), mg.platform_apple_authorize_result)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformTwitter), mg.platform_twitter_get_login_url)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformTwitter), mg.platform_twitter_authorize)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformTwitter), mg.platform_twitter_authorize_result)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformApple), mg.platform_apple_get_login_url)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformApple), mg.platform_apple_authorize)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformApple), mg.platform_apple_authorize_result)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_get_login_url)
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_authorize_sdk)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformSteamSDK), mg.platform_steamsdk_authorize)
|
||||
|
||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformHybeim), mg.platform_hybeim_authorize)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_get_login_url)
|
||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_authorize_sdk)
|
||||
|
||||
go mg.watchServiceCollection(ctx, serveMux, prefix)
|
||||
go mg.watchFileCollection(ctx, serveMux, prefix)
|
||||
@ -585,11 +562,59 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mg *Maingate) query(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
s := recover()
|
||||
if s != nil {
|
||||
logger.Error(s)
|
||||
}
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
io.Copy(io.Discard, r.Body)
|
||||
r.Body.Close()
|
||||
}()
|
||||
|
||||
queryvals := r.URL.Query()
|
||||
sk := queryvals.Get("sk")
|
||||
|
||||
if len(sk) == 0 {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
info := mg.auths.Find(sk)
|
||||
if info == nil {
|
||||
logger.Println("session key is not valid :", sk)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if !*noauth {
|
||||
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
||||
if len(apitoken) == 0 {
|
||||
logger.Println("MG-X-API-TOKEN is missing")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
apitokenObj, _ := primitive.ObjectIDFromHex(apitoken)
|
||||
if !mg.service().isValidToken(apitokenObj) {
|
||||
logger.Println("MG-X-API-TOKEN is invalid :", apitoken)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
bt, _ := json.Marshal(info)
|
||||
w.Write(bt)
|
||||
}
|
||||
|
||||
func (mg *Maingate) GeneratePlatformLoginNonceKey() string {
|
||||
const allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, 52)
|
||||
for i := range b {
|
||||
b[i] = allowed[r.Intn(len(allowed))]
|
||||
b[i] = allowed[rand.Intn(len(allowed))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
@ -603,7 +628,7 @@ func (mg *Maingate) GetUserBrowserInfo(r *http.Request) (string, error) {
|
||||
|
||||
cookie, err := r.Cookie("ActionSquareSessionExtraInfo")
|
||||
if err != nil {
|
||||
return "", logger.ErrorWithCallStack(err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
//requestinfo := fmt.Sprintf("%s_%s", cookie.Value, host) //-- RemoteAddr체크는 로드밸런서 IP 찍히는 문제 때문에 제외한다.
|
||||
@ -625,7 +650,7 @@ func (mg *Maingate) setUserToken(info usertokeninfo) error {
|
||||
"accesstoken_expire_time": info.accesstoken_expire_time,
|
||||
},
|
||||
}, options.Update().SetUpsert(true))
|
||||
return logger.ErrorWithCallStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo string) (usertokeninfo, error) {
|
||||
@ -650,7 +675,7 @@ func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo
|
||||
|
||||
updatetime, ok := found["lastupdate"].(int64)
|
||||
|
||||
if !ok || time.Now().Unix()-updatetime < config.Autologin_ttl {
|
||||
if !ok || time.Now().Unix()-updatetime < mg.maingateConfig.Autologin_ttl {
|
||||
info.platform = platform
|
||||
info.userid = userid
|
||||
info.brinfo = brinfo
|
||||
@ -697,10 +722,6 @@ func (mg *Maingate) updateUserinfo(info usertokeninfo) (bool, string, string) {
|
||||
success, userid, email = mg.platform_microsoft_getuserinfo(info)
|
||||
case AuthPlatformGoogle:
|
||||
success, userid, email = mg.platform_google_getuserinfo(info)
|
||||
case AuthPlatformSteamSDK:
|
||||
success, userid, email = mg.platform_steamsdk_getuserinfo(info)
|
||||
case AuthPlatformHybeim:
|
||||
success, userid, email = mg.platform_hybeim_getuserinfo(info)
|
||||
case AuthPlatformFirebaseAuth:
|
||||
success, userid, email = mg.platform_firebase_getuserinfo(info)
|
||||
}
|
||||
@ -910,22 +931,3 @@ func JWTparseCode(keyurl string, code string) (string, string, string) {
|
||||
//--- nonce 체크 필요하다.
|
||||
return claims["sub"].(string), email, nonce
|
||||
}
|
||||
|
||||
func (mg *Maingate) google_analytics_js(w http.ResponseWriter, r *http.Request) {
|
||||
fgaconfig := Firebase_Google_Analytics_JS_SDK_Config{
|
||||
FGA_apiKey: config.FGA_apiKey,
|
||||
FGA_authDomain: config.FGA_authDomain,
|
||||
FGA_databaseURL: config.FGA_databaseURL,
|
||||
FGA_projectId: config.FGA_projectId,
|
||||
FGA_storageBucket: config.FGA_storageBucket,
|
||||
FGA_messagingSenderId: config.FGA_messagingSenderId,
|
||||
FGA_appId: config.FGA_appId,
|
||||
FGA_measurementId: config.FGA_measurementId,
|
||||
}
|
||||
parsedTemplate, _ := template.ParseFiles("template/fb-ga.min.js")
|
||||
err := parsedTemplate.Execute(w, fgaconfig)
|
||||
if err != nil {
|
||||
logger.Error("Error executing template :", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,8 +95,8 @@ func (mg *Maingate) platform_apple_get_login_url(w http.ResponseWriter, r *http.
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("client_id", config.AppleCientId)
|
||||
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformApple)
|
||||
params.Add("client_id", mg.AppleCientId)
|
||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformApple)
|
||||
|
||||
params.Add("response_type", "code id_token")
|
||||
params.Add("scope", "name email")
|
||||
@ -146,7 +146,7 @@ func (mg *Maingate) platform_apple_authorize(w http.ResponseWriter, r *http.Requ
|
||||
}
|
||||
http.SetCookie(w, &cookie)
|
||||
|
||||
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformApple, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformApple, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||
@ -208,17 +208,17 @@ func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *ht
|
||||
}
|
||||
|
||||
// Generate the client secret used to authenticate with Apple's validation servers
|
||||
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId)
|
||||
secret, err := generateClientSecret(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
|
||||
if err != nil {
|
||||
logger.Error("error generating secret: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
vReq := Apple_WebValidationTokenRequest{
|
||||
ClientID: config.AppleServiceId,
|
||||
ClientID: mg.AppleServiceId,
|
||||
ClientSecret: secret,
|
||||
Code: code,
|
||||
RedirectURI: config.RedirectBaseUrl + "/authorize/" + AuthPlatformApple, // This URL must be validated with apple in your service
|
||||
RedirectURI: mg.RedirectBaseUrl + "/authorize/" + AuthPlatformApple, // This URL must be validated with apple in your service
|
||||
}
|
||||
|
||||
var resp Apple_ValidationResponse
|
||||
@ -268,14 +268,14 @@ func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *ht
|
||||
|
||||
func (mg *Maingate) platform_apple_getuserinfo(refreshToken string) (bool, string, string) {
|
||||
//=================================RefreshToken을 사용해서 정보 가져 온다. 이미 인증된 사용자의 업데이트 목적
|
||||
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId)
|
||||
secret, err := generateClientSecret(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
|
||||
if err != nil {
|
||||
logger.Error("error generating secret: ", err)
|
||||
return false, "", ""
|
||||
}
|
||||
|
||||
vReqRefreshToken := Apple_WebRefreshTokenRequest{
|
||||
ClientID: config.AppleServiceId,
|
||||
ClientID: mg.AppleServiceId,
|
||||
ClientSecret: secret,
|
||||
RefreshToken: refreshToken,
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package core
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -147,11 +146,6 @@ func (mg *Maingate) platform_firebaseauth_authorize_sdk(w http.ResponseWriter, r
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, memberId, nickname, provider, providerId, email, photourl, phonenumber string) (bool, string) {
|
||||
if mg.firebase == nil {
|
||||
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return false, ""
|
||||
}
|
||||
|
||||
found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{
|
||||
"platform": AuthPlatformFirebaseAuth,
|
||||
@ -194,7 +188,7 @@ func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, b
|
||||
return false, ""
|
||||
}
|
||||
|
||||
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, code)
|
||||
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, code)
|
||||
if err != nil {
|
||||
log.Println("error verifying ID token:", err)
|
||||
return false, ""
|
||||
@ -248,10 +242,6 @@ func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, b
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, string, string) {
|
||||
if mg.firebase == nil {
|
||||
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
|
||||
return false, "", ""
|
||||
}
|
||||
|
||||
found, err := mg.mongoClient.FindOne(CollectionFirebaseUserInfo, bson.M{
|
||||
"firebaseuserid": info.userid,
|
||||
@ -266,16 +256,13 @@ func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, str
|
||||
return false, "", ""
|
||||
}
|
||||
|
||||
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, info.token)
|
||||
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, info.token)
|
||||
if err != nil {
|
||||
log.Println("error verifying ID token:", err)
|
||||
return false, "", ""
|
||||
}
|
||||
|
||||
tempEmail := found["firebaseemail"].(string)
|
||||
if found["firebaseprovider"].(string) == "guest" {
|
||||
tempEmail = fmt.Sprintf("%s@guest.flag", info.userid)
|
||||
}
|
||||
|
||||
return true, info.userid, tempEmail
|
||||
|
||||
|
||||
@ -84,9 +84,9 @@ func (mg *Maingate) platform_google_get_login_url(w http.ResponseWriter, r *http
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("client_id", config.GoogleClientId)
|
||||
params.Add("client_id", mg.GoogleClientId)
|
||||
params.Add("response_type", "code")
|
||||
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
|
||||
params.Add("access_type", "offline")
|
||||
params.Add("prompt", "consent")
|
||||
@ -140,7 +140,7 @@ func (mg *Maingate) platform_google_authorize(w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
http.SetCookie(w, &cookie2)
|
||||
|
||||
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformGoogle, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformGoogle, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||
@ -211,9 +211,9 @@ func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *h
|
||||
|
||||
//=================
|
||||
params := url.Values{}
|
||||
params.Add("client_id", config.GoogleClientId)
|
||||
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||
params.Add("client_secret", config.GoogleClientSecret)
|
||||
params.Add("client_id", mg.GoogleClientId)
|
||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||
params.Add("client_secret", mg.GoogleClientSecret)
|
||||
params.Add("code", code)
|
||||
params.Add("grant_type", "authorization_code")
|
||||
|
||||
@ -285,9 +285,9 @@ func (mg *Maingate) platform_google_getuserinfo(info usertokeninfo) (bool, strin
|
||||
if time.Now().Unix() > info.accesstoken_expire_time {
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("client_id", config.GoogleClientId)
|
||||
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||
params.Add("client_secret", config.GoogleClientSecret)
|
||||
params.Add("client_id", mg.GoogleClientId)
|
||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||
params.Add("client_secret", mg.GoogleClientSecret)
|
||||
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
|
||||
params.Add("refresh_token", info.token)
|
||||
params.Add("grant_type", "refresh_token")
|
||||
|
||||
@ -1,198 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
)
|
||||
|
||||
type HybeImSDKAuthInfo struct {
|
||||
UserHybeimid string `json:"imid"`
|
||||
UserLoginVerifyToken string `json:"loginVerifyToken"`
|
||||
}
|
||||
|
||||
type HybeImSDKLoginAuthInfo struct {
|
||||
ServiceId string `json:"serviceId"`
|
||||
UserLoginVerifyToken string `json:"loginVerifyToken"`
|
||||
}
|
||||
|
||||
type Hiveim_LoginVerifyResult struct {
|
||||
State string `json:"state"`
|
||||
ImId string `json:"imId"`
|
||||
Provider string `json:"provider"`
|
||||
Os string `json:"os"`
|
||||
AppStore string `json:"appStore"`
|
||||
UserBlockInfo []Hiveim_UserBlockInfo `json:"blocks"`
|
||||
}
|
||||
|
||||
type Hiveim_UserBlockInfo struct {
|
||||
BlockId int `json:"blockId"`
|
||||
ReasonId int `json:"reasonId"`
|
||||
BlockedAt int64 `json:"blockedAt"`
|
||||
ExpireAt int64 `json:"expireAt"`
|
||||
Permanent bool `json:"permanent"`
|
||||
}
|
||||
|
||||
type Hiveim_LoginValidationResponse struct {
|
||||
ResultCode string `json:"resultCode"`
|
||||
ResultMessage string `json:"resultMessage"`
|
||||
ResultData Hiveim_LoginVerifyResult `json:"resultData"`
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_hybeim_authorize(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
brinfo, err := mg.GetUserBrowserInfo(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
logger.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
var authinfo HybeImSDKAuthInfo
|
||||
err = json.NewDecoder(r.Body).Decode(&authinfo)
|
||||
if err != nil {
|
||||
logger.Println("authinfo decoding fail:", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var resultcode string
|
||||
var blockinfo Hiveim_UserBlockInfo
|
||||
if !*noauth {
|
||||
err, resultcode, blockinfo = authenticateHybeImUser(config.HybeImProjectIdstring, config.HybeImServiceIdstring, config.HybeImAccessKey, config.HybeImEndPoint, authinfo.UserHybeimid, authinfo.UserLoginVerifyToken)
|
||||
}
|
||||
|
||||
// https://hybeim.gitbook.io/im-assemble/api/im-assemble-s2s-api#login-verify
|
||||
// SUCCESS : 성공
|
||||
// INVALID_LOGIN_VERIFY_TOKEN : login 인증 토큰 오류
|
||||
// LOGIN_VERIFY_EXPIRED : login 인증 토큰 만료
|
||||
// INVALID_SERVICE_ID : 유효 하지 않은 서비스 id
|
||||
// WITHDRAWAL_ACCOUNT : 탈퇴 대기 상태 유저
|
||||
// RELOGIN_REQUIRED : 로그인 데이터에 문제가 있어 다시 로그인 해야 되는 경우
|
||||
// INTERNAL_SERVER_ERROR : 서버 오류
|
||||
|
||||
if err == nil && resultcode == "SUCCESS" {
|
||||
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
|
||||
|
||||
var info usertokeninfo
|
||||
info.platform = AuthPlatformHybeim
|
||||
info.userid = authinfo.UserHybeimid
|
||||
info.token = authinfo.UserLoginVerifyToken
|
||||
info.brinfo = brinfo
|
||||
//info.accesstoken = respReferesh.AccessToken
|
||||
info.accesstoken_expire_time = acceestoken_expire_time
|
||||
mg.setUserToken(info)
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("id", authinfo.UserHybeimid)
|
||||
params.Add("authtype", AuthPlatformHybeim)
|
||||
w.Write([]byte("?" + params.Encode()))
|
||||
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
||||
return
|
||||
} else {
|
||||
params := url.Values{}
|
||||
params.Add("resultcode", resultcode)
|
||||
if resultcode == "BLOCKED" {
|
||||
blockinfoBytes, _ := json.Marshal(blockinfo)
|
||||
blockinfostr := string(blockinfoBytes)
|
||||
params.Add("blockinfo", blockinfostr)
|
||||
}
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("?" + params.Encode()))
|
||||
}
|
||||
|
||||
// logger.Println(err)
|
||||
// http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
||||
|
||||
}
|
||||
|
||||
func authenticateHybeImUser(projectid, serviceid, accesskey, endpoint, imid, UserLoginVerifyToken string) (error, string, Hiveim_UserBlockInfo) {
|
||||
|
||||
// endpoint
|
||||
// qa = https://api-qa.pub-dev.hybegames.io
|
||||
// prod = https://api.hybegames.com
|
||||
|
||||
verifyurl := endpoint + "/member/api-game/v1/auth/login/verify"
|
||||
|
||||
var param HybeImSDKLoginAuthInfo
|
||||
param.UserLoginVerifyToken = UserLoginVerifyToken
|
||||
param.ServiceId = serviceid
|
||||
|
||||
dat, err := json.Marshal(param)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var respReferesh Hiveim_LoginValidationResponse
|
||||
req, err := http.NewRequest("POST", verifyurl, bytes.NewBuffer(dat))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req.Header.Add("X-Auth-Access-Key", accesskey)
|
||||
req.Header.Add("X-Req-Pjid", projectid)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
var blockinfo Hiveim_UserBlockInfo
|
||||
body, e := ioutil.ReadAll(resp.Body)
|
||||
if e != nil {
|
||||
return e, "", blockinfo
|
||||
}
|
||||
|
||||
json.Unmarshal(body, &respReferesh)
|
||||
|
||||
//fmt.Println(string(body))
|
||||
|
||||
var doc map[string]interface{}
|
||||
if err := json.Unmarshal(body, &doc); err != nil {
|
||||
return err, respReferesh.ResultCode, blockinfo
|
||||
}
|
||||
|
||||
// if respReferesh.ResultData.State != "NORMAL" {
|
||||
// return errors.New("higveimSDK: State is not NORMAL"), respReferesh.ResultCode, blockinfo
|
||||
// }
|
||||
|
||||
if respReferesh.ResultData.Provider != "STEAM" {
|
||||
return errors.New("higveimSDK: Provider is not STEAM"), respReferesh.ResultCode, blockinfo
|
||||
}
|
||||
|
||||
if respReferesh.ResultData.ImId != imid {
|
||||
return errors.New("higveimSDK: ImId is not match"), respReferesh.ResultCode, blockinfo
|
||||
}
|
||||
|
||||
if respReferesh.ResultCode == "SUCCESS" {
|
||||
if respReferesh.ResultData.State == "BLOCKED" && len(respReferesh.ResultData.UserBlockInfo) > 0 {
|
||||
blockinfo = respReferesh.ResultData.UserBlockInfo[0]
|
||||
return nil, "BLOCKED", blockinfo
|
||||
}
|
||||
}
|
||||
|
||||
return nil, respReferesh.ResultCode, blockinfo
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_hybeim_getuserinfo(info usertokeninfo) (bool, string, string) {
|
||||
// Hybeim ( Steam )도 이메일 정보를 받을수 없기 때문에 userid로 리턴한다.
|
||||
dummyEmail := fmt.Sprintf("%s@hibeim.id", info.userid)
|
||||
return true, info.userid, dummyEmail
|
||||
|
||||
}
|
||||
@ -83,9 +83,9 @@ func (mg *Maingate) platform_microsoft_get_login_url(w http.ResponseWriter, r *h
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("client_id", config.MicrosoftClientId)
|
||||
params.Add("client_id", mg.MicrosoftClientId)
|
||||
params.Add("response_type", "code")
|
||||
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||
params.Add("response_mode", "query")
|
||||
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
||||
|
||||
@ -127,7 +127,7 @@ func (mg *Maingate) platform_microsoft_authorize(w http.ResponseWriter, r *http.
|
||||
}
|
||||
http.SetCookie(w, &cookie)
|
||||
|
||||
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformMicrosoft, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformMicrosoft, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||
@ -191,13 +191,13 @@ func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r
|
||||
//=================
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("client_id", config.MicrosoftClientId)
|
||||
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||
params.Add("client_id", mg.MicrosoftClientId)
|
||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||
params.Add("code", code)
|
||||
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
||||
params.Add("grant_type", "authorization_code")
|
||||
|
||||
params.Add("client_secret", config.MicrosoftClientSecret)
|
||||
params.Add("client_secret", mg.MicrosoftClientSecret)
|
||||
|
||||
var respReferesh Microsoft_ValidationResponse
|
||||
acceestoken_expire_time := time.Now().Unix()
|
||||
@ -263,13 +263,13 @@ func (mg *Maingate) platform_microsoft_getuserinfo(info usertokeninfo) (bool, st
|
||||
if time.Now().Unix() > info.accesstoken_expire_time {
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("client_id", config.MicrosoftClientId)
|
||||
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||
params.Add("client_id", mg.MicrosoftClientId)
|
||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||
params.Add("refresh_token", info.token)
|
||||
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
||||
params.Add("grant_type", "refresh_token")
|
||||
|
||||
params.Add("client_secret", config.MicrosoftClientSecret)
|
||||
params.Add("client_secret", mg.MicrosoftClientSecret)
|
||||
|
||||
var respReferesh Microsoft_ValidationResponse
|
||||
acceestoken_expire_time := time.Now().Unix()
|
||||
|
||||
@ -1,121 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
)
|
||||
|
||||
type SteamSDKAuthInfo struct {
|
||||
UserSteamId string `json:"steamid"`
|
||||
UserAuthToken string `json:"authtoken"`
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_steamsdk_authorize(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
defer r.Body.Close()
|
||||
|
||||
brinfo, err := mg.GetUserBrowserInfo(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
logger.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
var authinfo SteamSDKAuthInfo
|
||||
|
||||
err = json.NewDecoder(r.Body).Decode(&authinfo)
|
||||
if err != nil {
|
||||
logger.Println("authinfo decoding fail:", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := authenticateSteamUser(config.SteamPublisherAuthKey, config.SteamAppId, authinfo.UserSteamId, authinfo.UserAuthToken); err == nil {
|
||||
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
|
||||
|
||||
var info usertokeninfo
|
||||
info.platform = AuthPlatformSteamSDK
|
||||
info.userid = authinfo.UserSteamId
|
||||
info.token = authinfo.UserAuthToken
|
||||
info.brinfo = brinfo
|
||||
//info.accesstoken = respReferesh.AccessToken
|
||||
info.accesstoken_expire_time = acceestoken_expire_time
|
||||
mg.setUserToken(info)
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("id", authinfo.UserSteamId)
|
||||
params.Add("authtype", AuthPlatformSteamSDK)
|
||||
w.Write([]byte("?" + params.Encode()))
|
||||
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
||||
} else {
|
||||
logger.Println(err)
|
||||
http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func authenticateSteamUser(pubkey, appid, playerid, ticket string) error {
|
||||
// Returns: The user's 64-bit SteamID if the user's ticket is valid
|
||||
url := fmt.Sprintf("https://partner.steam-api.com/ISteamUserAuth/AuthenticateUserTicket/v1/?key=%s&appid=%s&ticket=%s", pubkey, appid, ticket)
|
||||
resp, e := http.Get(url)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
body, e := ioutil.ReadAll(resp.Body)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
// fmt.Println(url)
|
||||
// fmt.Println(string(body))
|
||||
|
||||
var doc map[string]interface{}
|
||||
if err := json.Unmarshal(body, &doc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v, ok := doc["response"]; ok {
|
||||
response := v.(map[string]interface{})
|
||||
if v, ok = response["params"]; ok {
|
||||
paramsnode := v.(map[string]interface{})
|
||||
if v, ok = paramsnode["result"]; ok {
|
||||
if v.(string) == "OK" {
|
||||
if v, ok = paramsnode["steamid"]; ok {
|
||||
// playerid에는 빌드 구성 suffix가 붙어있는 상태이므로 == 비교가 아니라 HasPrefix로 비교
|
||||
if strings.HasPrefix(playerid, v.(string)) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else if v.(string) == "Invalid ticket" {
|
||||
return errors.New("steam: invalid ticket")
|
||||
}
|
||||
}
|
||||
} else if errdocraw, ok := response["error"]; ok {
|
||||
errdoc := errdocraw.(map[string]interface{})
|
||||
desc := errdoc["errordesc"].(string)
|
||||
return errors.New(desc)
|
||||
}
|
||||
}
|
||||
return errors.New("steam: response is not expected")
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_steamsdk_getuserinfo(info usertokeninfo) (bool, string, string) {
|
||||
// Steam은 이메일 정보를 받을수 없기 때문에 userid로 리턴한다.
|
||||
dummyEmail := fmt.Sprintf("%s@steam.id", info.userid)
|
||||
return true, info.userid, dummyEmail
|
||||
|
||||
}
|
||||
@ -123,7 +123,7 @@ func (mg *Maingate) platform_twitter_authorize(w http.ResponseWriter, r *http.Re
|
||||
}
|
||||
http.SetCookie(w, &cookie)
|
||||
|
||||
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformTwitter, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformTwitter, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||
}
|
||||
|
||||
func (mg *Maingate) platform_twitter_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||
@ -249,7 +249,7 @@ func (mg *Maingate) platform_twitter_getuserinfo(token, secret string) (bool, st
|
||||
}
|
||||
|
||||
func (mg *Maingate) CallTwitterAPI_WithAPPKey(requesturl, method, nonce string) string {
|
||||
return mg.CallTwitterAPI(requesturl, method, config.TwitterOAuthKey, config.TwitterOAuthSecret, nonce)
|
||||
return mg.CallTwitterAPI(requesturl, method, mg.TwitterOAuthKey, mg.TwitterOAuthSecret, nonce)
|
||||
}
|
||||
|
||||
func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret, nonce string) string {
|
||||
@ -272,8 +272,8 @@ func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret
|
||||
//vals.Add("oauth_callback", "actionclient://callback")
|
||||
//vals.Add("oauth_callback", "http://127.0.0.1:7770/auth")
|
||||
|
||||
vals.Add("oauth_callback", config.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter)
|
||||
vals.Add("oauth_consumer_key", config.TwitterCustomerKey)
|
||||
vals.Add("oauth_callback", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter)
|
||||
vals.Add("oauth_consumer_key", mg.TwitterCustomerKey)
|
||||
vals.Add("oauth_token", oauth_token)
|
||||
vals.Add("oauth_signature_method", "HMAC-SHA1")
|
||||
vals.Add("oauth_timestamp", strconv.Itoa(int(time.Now().Unix())))
|
||||
@ -282,7 +282,7 @@ func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret
|
||||
|
||||
parameterString := strings.Replace(vals.Encode(), "+", "%20", -1)
|
||||
signatureBase := strings.ToUpper(method) + "&" + url.QueryEscape(strings.Split(requesturl, "?")[0]) + "&" + url.QueryEscape(parameterString)
|
||||
signingKey := url.QueryEscape(config.TwitterCustomerSecret) + "&" + url.QueryEscape(oauth_secret)
|
||||
signingKey := url.QueryEscape(mg.TwitterCustomerSecret) + "&" + url.QueryEscape(oauth_secret)
|
||||
signature := calculateTwitterSignature(signatureBase, signingKey)
|
||||
|
||||
headerString := "OAuth oauth_callback=\"" + url.QueryEscape(vals.Get("oauth_callback")) + "\", oauth_consumer_key=\"" + url.QueryEscape(vals.Get("oauth_consumer_key")) + "\", oauth_nonce=\"" + url.QueryEscape(vals.Get("oauth_nonce")) +
|
||||
|
||||
930
core/service.go
930
core/service.go
File diff suppressed because it is too large
Load Diff
233
core/watch.go
233
core/watch.go
@ -1,15 +1,18 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"repositories.action2quare.com/ayo/gocommon"
|
||||
common "repositories.action2quare.com/ayo/gocommon"
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
@ -18,6 +21,14 @@ import (
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type authPipelineDocument struct {
|
||||
OperationType string `bson:"operationType"`
|
||||
DocumentKey struct {
|
||||
Id primitive.ObjectID `bson:"_id"`
|
||||
} `bson:"documentKey"`
|
||||
Authinfo *common.Authinfo `bson:"fullDocument"`
|
||||
}
|
||||
|
||||
type servicePipelineDocument struct {
|
||||
OperationType string `bson:"operationType"`
|
||||
DocumentKey struct {
|
||||
@ -31,10 +42,106 @@ type filePipelineDocument struct {
|
||||
DocumentKey struct {
|
||||
Id primitive.ObjectID `bson:"_id"`
|
||||
} `bson:"documentKey"`
|
||||
File *FileDocumentDesc `bson:"fullDocument"`
|
||||
File *fileDocumentDesc `bson:"fullDocument"`
|
||||
}
|
||||
|
||||
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
|
||||
type whilelistPipelineDocument struct {
|
||||
OperationType string `bson:"operationType"`
|
||||
DocumentKey struct {
|
||||
Id primitive.ObjectID `bson:"_id"`
|
||||
} `bson:"documentKey"`
|
||||
Member *whitelistmember `bson:"fullDocument"`
|
||||
}
|
||||
|
||||
func (mg *Maingate) watchWhitelistCollection(parentctx context.Context) {
|
||||
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: "operationType", Value: 1},
|
||||
{Key: "fullDocument", Value: 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var stream *mongo.ChangeStream
|
||||
var err error
|
||||
var ctx context.Context
|
||||
|
||||
for {
|
||||
if stream == nil {
|
||||
stream, err = mg.mongoClient.Watch(CollectionWhitelist, mongo.Pipeline{matchStage, projectStage})
|
||||
if err != nil {
|
||||
logger.Error("watchWhitelistCollection watch failed :", err)
|
||||
time.Sleep(time.Minute)
|
||||
continue
|
||||
}
|
||||
ctx = context.TODO()
|
||||
}
|
||||
|
||||
changed := stream.TryNext(ctx)
|
||||
if ctx.Err() != nil {
|
||||
logger.Error("watchWhitelistCollection stream.TryNext failed. process should be restarted! :", ctx.Err().Error())
|
||||
break
|
||||
}
|
||||
|
||||
if changed {
|
||||
var data whilelistPipelineDocument
|
||||
if err := stream.Decode(&data); err == nil {
|
||||
ot := data.OperationType
|
||||
switch ot {
|
||||
case "insert":
|
||||
// 새 화이트리스트 멤버
|
||||
mg.service().wl.add(data.Member)
|
||||
case "update":
|
||||
if data.Member.Expired != 0 {
|
||||
logger.Println("whitelist member is removed :", *data.Member)
|
||||
mg.service().wl.remove(data.Member.Email)
|
||||
} else {
|
||||
logger.Println("whitelist member is updated :", *data.Member)
|
||||
mg.service().wl.add(data.Member)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.Error("watchWhitelistCollection stream.Decode failed :", err)
|
||||
}
|
||||
} else if stream.Err() != nil || stream.ID() == 0 {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
logger.Println("watchWhitelistCollection is done")
|
||||
stream.Close(ctx)
|
||||
return
|
||||
|
||||
case <-time.After(time.Second):
|
||||
logger.Error("watchWhitelistCollection stream error :", stream.Err())
|
||||
stream.Close(ctx)
|
||||
stream = nil
|
||||
}
|
||||
} else {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
|
||||
defer func() {
|
||||
s := recover()
|
||||
if s != nil {
|
||||
@ -106,7 +213,7 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux goco
|
||||
if err := stream.Decode(&data); err == nil {
|
||||
switch data.OperationType {
|
||||
case "insert":
|
||||
data.File.Save()
|
||||
data.File.save()
|
||||
|
||||
case "delete":
|
||||
subfolder := hex.EncodeToString(data.DocumentKey.Id[:4])
|
||||
@ -119,7 +226,7 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux goco
|
||||
}
|
||||
}
|
||||
|
||||
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
|
||||
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
|
||||
defer func() {
|
||||
s := recover()
|
||||
if s != nil {
|
||||
@ -180,9 +287,11 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux g
|
||||
logger.Error("service cannot be prepared :", data.Service, err)
|
||||
} else {
|
||||
// 내가 임시로 가지고 있던 서비스일 수 있다.
|
||||
if mg.service().Id == data.Service.Id {
|
||||
already := mg.service().Id == data.Service.Id
|
||||
logger.Println("service is on the board! :", data.Service)
|
||||
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(data.Service))
|
||||
if !already {
|
||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, data.Service.ServiceCode, "/"), mg.service())
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +300,33 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux g
|
||||
|
||||
case "update":
|
||||
data.Service.prepare(mg)
|
||||
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(data.Service))
|
||||
old := mg.service()
|
||||
|
||||
atomic.SwapPointer(&old.divisionsForUsersSerialized, data.Service.divisionsForUsersSerialized)
|
||||
atomic.SwapPointer(&old.divisionsSerialized, data.Service.divisionsSerialized)
|
||||
atomic.SwapPointer(&old.admins, data.Service.admins)
|
||||
atomic.SwapPointer(&old.serviceSerialized, data.Service.serviceSerialized)
|
||||
atomic.SwapPointer(&old.serviceSummarySerialized, data.Service.serviceSummarySerialized)
|
||||
atomic.SwapPointer(&old.wl.emailptr, data.Service.wl.emailptr)
|
||||
|
||||
old.Divisions = data.Service.Divisions
|
||||
for _, div := range old.Divisions {
|
||||
var req *http.Request
|
||||
if div.State == DivisionState_FullOpen {
|
||||
req, _ = http.NewRequest("POST", div.Url+"/maingate", nil)
|
||||
} else if div.Maintenance != nil {
|
||||
bt, _ := json.Marshal(div.Maintenance)
|
||||
req, _ = http.NewRequest("POST", div.Url+"/maingate", bytes.NewBuffer(bt))
|
||||
}
|
||||
|
||||
if req != nil {
|
||||
// MG-X-API-TOKEN
|
||||
req.Header.Add("MG-X-API-TOKEN", old.ServerApiTokens[0].Hex())
|
||||
if resp, err := http.DefaultClient.Do(req); err == nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.Error("watchServiceCollection stream.Decode failed :", err)
|
||||
@ -213,3 +348,87 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux g
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func watchAuthCollection(parentctx context.Context, ac *common.AuthCollection, mongoClient common.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{
|
||||
"delete",
|
||||
"insert",
|
||||
"update",
|
||||
}},
|
||||
}},
|
||||
},
|
||||
}}
|
||||
projectStage := bson.D{
|
||||
{
|
||||
Key: "$project", Value: bson.D{
|
||||
{Key: "documentKey", Value: 1},
|
||||
{Key: "operationType", Value: 1},
|
||||
{Key: "fullDocument", Value: 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var stream *mongo.ChangeStream
|
||||
var err error
|
||||
var ctx context.Context
|
||||
|
||||
for {
|
||||
if stream == nil {
|
||||
stream, err = mongoClient.Watch(CollectionAuth, mongo.Pipeline{matchStage, projectStage})
|
||||
if err != nil {
|
||||
logger.Error("watchAuthCollection watch failed :", err)
|
||||
time.Sleep(time.Minute)
|
||||
continue
|
||||
}
|
||||
ctx = context.TODO()
|
||||
}
|
||||
|
||||
changed := stream.TryNext(ctx)
|
||||
if ctx.Err() != nil {
|
||||
logger.Error("watchAuthCollection stream.TryNext failed. process should be restarted! :", ctx.Err().Error())
|
||||
break
|
||||
}
|
||||
|
||||
if changed {
|
||||
var data authPipelineDocument
|
||||
if err := stream.Decode(&data); err == nil {
|
||||
ot := data.OperationType
|
||||
switch ot {
|
||||
case "insert":
|
||||
ac.AddRaw(&mongoAuthCell{src: data.Authinfo})
|
||||
case "update":
|
||||
ac.AddRaw(&mongoAuthCell{src: data.Authinfo})
|
||||
case "delete":
|
||||
ac.RemoveByAccId(data.DocumentKey.Id)
|
||||
}
|
||||
} else {
|
||||
logger.Error("watchAuthCollection stream.Decode failed :", err)
|
||||
}
|
||||
} else if stream.Err() != nil || stream.ID() == 0 {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
logger.Println("watchAuthCollection is done")
|
||||
stream.Close(ctx)
|
||||
return
|
||||
|
||||
case <-time.After(time.Second):
|
||||
logger.Error("watchAuthCollection stream error :", stream.Err())
|
||||
stream.Close(ctx)
|
||||
stream = nil
|
||||
}
|
||||
} else {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script type="text/javascript" src="./fb-ga.min.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- <body> -->
|
||||
<!-- <body onload="window.FBA.TrackLogEvent('DESKTOP-TEST');"> -->
|
||||
<!-- <script type="cjs" src="./fb-ga.rollup.js"> -->
|
||||
64
go.mod
64
go.mod
@ -1,38 +1,34 @@
|
||||
module repositories.action2quare.com/ayo/maingate
|
||||
|
||||
go 1.22.1
|
||||
|
||||
|
||||
go 1.18
|
||||
|
||||
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.157.0
|
||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86
|
||||
google.golang.org/api v0.128.0
|
||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621052811-06ef97f11d22
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.111.0 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go v0.110.2 // indirect
|
||||
cloud.google.com/go/compute v1.20.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // 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/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/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/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/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/klauspost/compress v1.16.6 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/pires/go-proxyproto v0.7.0 // indirect
|
||||
@ -42,22 +38,20 @@ 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
|
||||
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
|
||||
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.9.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.30.0 // indirect
|
||||
)
|
||||
|
||||
replace repositories.action2quare.com/ayo/maingate => ./
|
||||
|
||||
156
go.sum
156
go.sum
@ -1,27 +1,34 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
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 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/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.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/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/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/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
|
||||
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/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=
|
||||
@ -30,16 +37,11 @@ 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/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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
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=
|
||||
@ -50,13 +52,16 @@ 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=
|
||||
@ -73,17 +78,19 @@ 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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
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/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
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/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/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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/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/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=
|
||||
@ -105,14 +112,17 @@ 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=
|
||||
@ -131,24 +141,15 @@ 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/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=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
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.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
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/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=
|
||||
@ -156,48 +157,55 @@ 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.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
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/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
||||
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
||||
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/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.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
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/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.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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.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/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/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=
|
||||
@ -207,29 +215,35 @@ 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=
|
||||
google.golang.org/api v0.157.0 h1:ORAeqmbrrozeyw5NjnMxh7peHO0UzV4wWYSwZeCUb20=
|
||||
google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g=
|
||||
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/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.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
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/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-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/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/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.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
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/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=
|
||||
@ -241,16 +255,18 @@ 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.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
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-20240806115838-ca5632031c86 h1:vP0mVST68cw14fI/af3Xp1ZQoYjkNGK4S0zji1BVfSI=
|
||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86/go.mod h1:XA8+hQtUNh956T+kAbJKkUtMl5HUWj83knvdBvvPS5s=
|
||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621052811-06ef97f11d22 h1:DImSGNxZrc+Q4WlS1OKMsLAScEfDYLX4XMJdjAaVnXc=
|
||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621052811-06ef97f11d22/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
|
||||
|
||||
19
main.go
19
main.go
@ -2,9 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"repositories.action2quare.com/ayo/gocommon"
|
||||
common "repositories.action2quare.com/ayo/gocommon"
|
||||
"repositories.action2quare.com/ayo/gocommon/flagx"
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
"repositories.action2quare.com/ayo/maingate/core"
|
||||
@ -19,29 +21,26 @@ func main() {
|
||||
flagx.Parse()
|
||||
|
||||
logger.Println("build revision =", revision)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
mg, err := core.New(ctx)
|
||||
if err != nil {
|
||||
logger.Error("core.New failed :", err)
|
||||
return
|
||||
panic(err)
|
||||
}
|
||||
defer mg.Destructor()
|
||||
|
||||
serveMux := http.NewServeMux()
|
||||
if err := mg.RegisterHandlers(ctx, serveMux, *prefix); err != nil {
|
||||
logger.Error("RegisterHandlers failed :", err)
|
||||
return
|
||||
panic(err)
|
||||
}
|
||||
|
||||
server := gocommon.NewHTTPServer(serveMux)
|
||||
server := common.NewHTTPServer(serveMux)
|
||||
logger.Println("maingate is started")
|
||||
|
||||
if err := server.Start(); err != nil {
|
||||
logger.Error("maingate is stopped with error :", err)
|
||||
}
|
||||
|
||||
logger.Println("maingate is terminated")
|
||||
cancel()
|
||||
mg.Destructor()
|
||||
}
|
||||
|
||||
30
make_maingate_package.ps1
Normal file
30
make_maingate_package.ps1
Normal file
@ -0,0 +1,30 @@
|
||||
# $ErrorActionPreference = 'SilentlyContinue'
|
||||
|
||||
$CurBranch = git branch --show-current
|
||||
|
||||
Remove-Item maingate.zip -Force -Recurse -ErrorAction SilentlyContinue
|
||||
|
||||
cd ..
|
||||
cd maingate-console
|
||||
|
||||
|
||||
git switch $CurBranch
|
||||
git pull
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
Remove-Item console -Force -Recurse -ErrorAction SilentlyContinue
|
||||
Copy-Item build console -Recurse
|
||||
|
||||
Compress-Archive -Path console -DestinationPath ..\maingate\maingate.zip -Force
|
||||
Remove-Item console -Force -Recurse
|
||||
|
||||
cd ..
|
||||
cd maingate
|
||||
|
||||
$Env:GOOS="linux"
|
||||
$Env:GOARCH="amd64"
|
||||
go build -ldflags="-s -w" .
|
||||
|
||||
Compress-Archive -Path maingate -Update -DestinationPath maingate.zip
|
||||
Compress-Archive -Path *-firebase-*.json -Update -DestinationPath maingate.zip
|
||||
1
template/fb-ga.min.js
vendored
1
template/fb-ga.min.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user