Compare commits

...

117 Commits

Author SHA1 Message Date
c63c3ddd92 block collection 에 account를 복수로 저장 2025-08-01 19:44:58 +09:00
3c57cb833e Merge branch 'master' of https://repositories.action2quare.com/ayo/maingate 2024-08-22 11:26:15 +09:00
c82b52fae6 세션 되돌림 2024-08-22 11:26:13 +09:00
6660e465f2 에러 로그 강화 2024-08-21 18:07:55 +09:00
7c41346f51 세션 최적화 2024-08-20 22:53:58 +09:00
cc6115f30c [오승석] GetyDivisionAddress 할 때 div.State가 restricted 인 경우 공지 빠진부분 추가 2024-08-14 14:36:13 +09:00
86c892f154 Merge branch 'master' of https://repositories.action2quare.com/ayo/maingate 2024-08-06 21:07:05 +09:00
37f37899df [오승석] email 저장 제거
- CollectionLink에 email 저장 안함
- whitelist key 변경: Email -> Alias
2024-08-06 21:04:48 +09:00
c9cd3720e9 Merge branch 'master' of https://repositories.action2quare.com/ayo/maingate 2024-08-06 12:53:43 +09:00
d1e677056d divname이 없을 때 default 2024-08-06 12:53:41 +09:00
d6daa9bdba [오승석] unlink & linkinfo 최신화
- KD쪽 코드 가져옴
2024-08-01 14:16:38 +09:00
0c5a4194f0 로그 제거 2024-08-01 12:29:36 +09:00
e25f788cbd 모듈 업데이트 2024-07-31 16:52:50 +09:00
a7a9b207e2 계정 대량 조회 추가 2024-07-31 16:49:06 +09:00
f7e3da51ae RegisterHandlers 시그니쳐 수정 (ServerMuxInterface) 2024-07-31 16:48:54 +09:00
4212d3ed59 Hybe로그인 관련 제재 로그인 금지 처리 - 로그인 authorize에서 제재 처리 하는 기능 추가 2024-07-22 16:16:11 +09:00
bdae4eeb48 url 타입 변경 2024-07-20 12:26:51 +09:00
dbd22fe285 Merge pull request 'to_upstream' (#2) from ws/maingate:to_upstream into master
Reviewed-on: #2
2024-07-18 15:09:45 +09:00
894663ed38 reqauthtype 으로 변경 하면서 빠진 부분 수정 -> platform 정보가 flag 정보로 씌워지는 문제 2024-07-18 15:08:48 +09:00
ec3edbd8d5 noauth대신 authtype 파라미터 사용 2024-07-18 15:08:35 +09:00
938f80b460 [오승석] 계정 삭제
- 에디터에서 테스트용 예외처리 추가
2024-07-16 10:54:04 +09:00
843ac3340c [오승석] 계정 삭제
- 게스트 계정은 삭제 불가
2024-07-15 19:22:53 +09:00
97e0effc61 [오승석] 계정 삭제
- 테스트로 게스트계정 예외처리 넣었던부분 제거
2024-07-15 18:05:15 +09:00
8f9b9cf402 [오승석] 계정 삭제 추가 2024-07-15 12:37:52 +09:00
53d4d4536d firebase 설정에 따라 인스턴스 생성 2024-07-10 12:14:58 +09:00
f2afeac3da [오승석] Account Link
- func link()안에서 CollectionLink에 이미 link된 계정이 있는경우, json으로 '{"alreadylink":true}' 반환하도록 추가
2024-07-03 14:44:53 +09:00
cf9c4d57c7 계정조회 api 추가 accid -> platform, uid 조회하는 api 추가 2024-07-02 10:53:41 +09:00
ddf88501a1 [오승석] Account Link
- Firebase::Anonymously(guest) 에서 Firebase 를 통한 다른 Platform 으로 Link 추가
2024-06-27 15:18:09 +09:00
681927911c * [오승석] firebase를 통한 guset로그인시 email에 @guest.flag 추가
- 위치 이동
2024-06-24 15:42:37 +09:00
e862ff3717 Maingate - Hybeim SDK를 통한 Steam 로그인 처리 2024-06-11 11:54:17 +09:00
d3e72a2e4b 로그 추가 2024-05-17 10:05:14 +09:00
8956ba03d5 모듈 업데이트 2024-05-17 10:02:01 +09:00
048ffa00b6 세션 인터페이스 변경 적용 2024-04-23 11:24:19 +09:00
ba19cc0006 중복 로그인 방지 2024-04-22 17:58:53 +09:00
f8557078cc [오승석] firebase를 통한 guset로그인시 email에 @guest.flag 추가 2024-04-01 14:38:32 +09:00
eace5933a1 ServiceCode제거 2024-03-29 09:06:38 +09:00
e38e8a91e5 쿠폰 버그 체리픽 2024-03-04 19:26:20 +09:00
2076fb1b81 [이민권] 쿠폰
- 유효번호 쿠폰 사용 안 되는 이슈 수정
- 유효번호 쿠폰이 사용 불가여도 사용 처리 되는 이슈 수정
2024-03-04 19:24:19 +09:00
f734ef099b 세션 무효화 적용 2024-02-21 12:23:51 +09:00
c0e1e229cd 화이트리스트 추가 오류 수정 2024-02-14 11:09:19 +09:00
b5114b5224 스팀도 readable한 email 주소 저장 2024-02-05 20:16:32 +09:00
a3b4ac47b8 maintenance 바로 반영 안되는 문제 수정 2024-02-04 15:23:33 +09:00
45e7169c3a commandcenter용 globalApiToken 추가 2024-02-02 12:45:42 +09:00
3444c17026 Merge branch 'master' of https://repositories.action2quare.com/ayo/maingate 2024-01-22 17:17:09 +09:00
98340db8df 모듈 업데이트 2024-01-22 17:17:07 +09:00
e7b3f59dd0 계정 이메일 조회 기능 추가 2024-01-10 07:37:06 +09:00
bc82cb123c Revert "Session에 email도 저장해둔다. 필요할때 꺼내줄 api만들 예정"
This reverts commit 2165a4400b.
2024-01-09 15:31:15 +09:00
2165a4400b Session에 email도 저장해둔다. 필요할때 꺼내줄 api만들 예정 2024-01-09 14:43:23 +09:00
6ca3905fed 차단 처리 2023-12-28 17:38:20 +09:00
d5708a964f block 테스트 함수 추가 2023-12-28 16:55:38 +09:00
bb9b3a9735 default division 생성 수정 2023-12-26 16:38:11 +09:00
da68071e97 dev용 serverHTTP 추가 2023-12-25 22:08:22 +09:00
2e60fac840 mg.config를 config로 변경 2023-12-06 16:35:55 +09:00
dab5a35870 모듈 업데이트 2023-11-30 14:49:01 +09:00
a35512e327 모듈 업데이트 2023-11-30 14:17:48 +09:00
8a8bd50e28 계정 제재 개선 2023-11-29 17:36:25 +09:00
db90ce931f 차단된 유저 못 가져오는 문제 수정 2023-11-29 09:30:22 +09:00
7639c749dc 모듈 업데이트 2023-11-28 22:35:01 +09:00
63461676f4 모듈 업데이트 2023-11-28 00:57:56 +09:00
eebd3fb746 모듈 업데이트 2023-11-25 22:22:33 +09:00
ba4b4eea94 로그 수정 2023-11-24 00:18:04 +09:00
e583904693 모듈 업데이트 2023-11-16 19:58:24 +09:00
a2def0af79 fba, template 폴더를 package 에 추가 2023-10-24 14:04:54 +09:00
6ccf76d1b2 Firebase-Google Analaytics Desktop 버전 연동을 위해서 JavaScript SDK( JS-SDk ) 관련 코드 추가 2023-10-23 14:28:29 +09:00
bc58249483 noauth가 아닐때 type 없으면 로그인 실패 2023-10-20 11:27:41 +09:00
95a7972835 로그 제거 2023-10-18 15:32:36 +09:00
e37aaff9cb 로그 변경 2023-10-18 15:28:14 +09:00
77cffbbe9a 로그 추가 2023-10-18 15:15:35 +09:00
d623196c10 모듈 업데이트 2023-10-12 12:05:20 +09:00
06e40853ad 화이트리스트 추가,삭제 반영 안되는 문제 수정 2023-10-05 11:11:20 +09:00
d873965d37 현재 block된 정보를 조회 2023-09-25 12:29:26 +09:00
275b9b12e3 모듈 업데이트 2023-09-19 18:52:33 +09:00
81689f7512 코드 정리 2023-09-19 18:50:45 +09:00
e3ad826826 모듈 업데이트 2023-09-11 12:48:39 +09:00
9e98b581e4 모듈 업데이트 2023-09-08 15:27:25 +09:00
41641b88e9 모듈 업데이트 2023-09-08 11:36:58 +09:00
a4d297a944 모듈 업데이트 2023-09-06 18:02:16 +09:00
418713b0c7 version split 수정 2023-09-05 17:15:15 +09:00
087743453c 모듈 업데이트 2023-09-04 14:37:58 +09:00
caed2b5925 세션 touch 리퀘스트 처리 2023-09-04 12:17:34 +09:00
e18dc74dc2 version split 수정 2023-09-04 11:15:05 +09:00
9afa1d87e7 모듈 업데이트 2023-09-04 10:24:35 +09:00
3cf9466cdb 모듈 업데이트 2023-09-01 10:49:07 +09:00
6c73e9990e 모듈 업데이트 2023-08-31 21:16:41 +09:00
e8aa6189be config로 provider 생성 2023-08-31 21:13:11 +09:00
47284a79c2 session provider생성 최신화 2023-08-31 20:44:21 +09:00
0121310941 deprecated 함수 제거 2023-08-31 17:24:21 +09:00
76a4818a66 session.provider로 교체 2023-08-30 17:04:00 +09:00
1ba32aa4c9 쿠폰 조회 오류 수정 2023-08-29 11:06:14 +09:00
edb3e07329 parsemuiltipartform 추가 . 에러는 무시 2023-08-28 13:53:59 +09:00
f5304fae80 쿠폰 api를 maingate 로 옮김 2023-08-25 12:31:32 +09:00
d9be04541b prepare 로그 자세히 2023-08-25 11:39:17 +09:00
a7a20aebcf 모듈 업데이트 2023-08-23 22:46:07 +09:00
184675a9b7 계정 제재 동작 오류 수정 2023-08-23 17:48:47 +09:00
197ee7127b 서버 noauth 플래그를 알림 2023-08-22 19:53:30 +09:00
e3afb58634 file 경로에서 servicecode 제거 2023-08-22 18:06:14 +09:00
bafb67dabc 스팀 로그인 noauth 추가 처리 2023-08-22 17:51:41 +09:00
08cb989975 서비스 json 수정 2023-08-22 11:10:59 +09:00
455011fd99 계정 제재 api추가 2023-08-22 10:16:09 +09:00
e8832f329a 안쓰는 인덱스 제거 2023-08-21 11:01:21 +09:00
a8df7d54bd version split 디폴트 이름 변경 2023-08-18 13:56:34 +09:00
39e1b925e5 divisionsSerialized가 잘못 덮어씌어진 문제 수정 2023-08-17 12:35:48 +09:00
42b4ade782 sh를 통으로 atomic하게 교체 2023-08-16 21:44:19 +09:00
c7f073c779 guest 계정 지원 2023-08-09 17:39:16 +09:00
8126406e5f 모듈 업데이트 2023-08-02 11:41:18 +09:00
fb5db25dce 불필요한 로그 삭제 2023-07-31 15:54:03 +09:00
f79e922fa0 SteamSDK - 스팀 인증 관련 기능 추가 2023-07-31 12:43:02 +09:00
d796958d5e 화이트리스트 삭제 문제 수정 2023-07-10 18:12:43 +09:00
22ec115b35 whitelist에서 email과 platform을 모두 비교 2023-07-07 15:32:54 +09:00
5abb3fd2b7 중복 로그 제거 2023-06-30 18:01:34 +09:00
ed85918e7f maingate console은 이제 빌드 안함 2023-06-29 21:32:05 +09:00
c5ec99d3e1 mongoClient 변경 2023-06-29 21:31:51 +09:00
4af93b3d7e maintenance 링크를 잘못 만들던 문제 수정 2023-06-29 21:21:49 +09:00
afc3a10f51 serviceptr이 변경됐을 때 처리 2023-06-29 16:09:27 +09:00
3834ca2e37 Merge branch 'master' of https://repositories.action2quare.com/ayo/maingate 2023-06-28 16:45:20 +09:00
0898213aa8 로그 추가 2023-06-28 16:45:18 +09:00
cb08ecb53a maingate - 연결된 계정 숫자 조회, 연결 끊는 API 추가 2023-06-28 16:14:38 +09:00
29 changed files with 10547 additions and 1058 deletions

View File

@ -0,0 +1,37 @@
// 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 Normal file

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

537
backup/firebase-jssdk/js.js Normal file

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

View File

@ -1,6 +1,10 @@
{
"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" : "",
@ -24,6 +28,15 @@
"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"
]

View File

@ -2,9 +2,7 @@ package core
import (
"bytes"
"crypto/md5"
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
@ -18,7 +16,7 @@ import (
"time"
"unsafe"
common "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger"
"go.mongodb.org/mongo-driver/bson"
@ -27,7 +25,6 @@ import (
)
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"`
@ -66,48 +63,16 @@ func (fd *FileDocumentDesc) Save() error {
if fd.Extract {
switch path.Ext(destFile) {
case ".zip":
err = common.Unzip(destFile)
err = gocommon.Unzip(destFile)
case ".tar":
err = common.Untar(destFile)
err = gocommon.Untar(destFile)
}
}
return err
}
func (caller apiCaller) isAdmin() bool {
if *devflag {
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))
@ -126,11 +91,6 @@ 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,
})
@ -147,11 +107,6 @@ 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)
@ -167,17 +122,16 @@ 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[:], newidbt[:8])
newidobj := primitive.NewObjectID()
copy(newidobj[:], b[1:])
rf := newidobj.Hex()
var link string
if extract {
link = path.Join("static", subfolder, rf)
link = path.Join("static", rf)
} else {
link = path.Join("static", subfolder, rf, header.Filename)
link = path.Join("static", rf, header.Filename)
}
newdoc := FileDocumentDesc{
@ -188,12 +142,10 @@ 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,
"_id": newidobj,
"key": rf,
}, newdoc)
if err == nil {
@ -206,48 +158,83 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
return nil
}
func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) error {
func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
mg := caller.mg
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
// }
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
}
all, err := mg.mongoClient.All(CollectionWhitelist)
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
}
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)
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)
}
} else if r.Method == "PUT" {
case "PUT":
body, _ := io.ReadAll(r.Body)
var member whitelistmember
if err := json.Unmarshal(body, &member); err != nil {
return err
}
// if !caller.isAdminOrValidToken() {
// logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
// w.WriteHeader(http.StatusUnauthorized)
// return nil
// }
member.Expired = 0
member.ExpiredAt = 0
member.Id = primitive.NewObjectID()
_, _, err := mg.mongoClient.Update(CollectionWhitelist, bson.M{
"_id": primitive.NewObjectID(),
"_id": member.Id,
}, bson.M{
"$set": &member,
}, options.Update().SetUpsert(true))
@ -255,8 +242,9 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
if err != nil {
return err
}
} else if r.Method == "DELETE" {
id := queryvals.Get("id")
case "DELETE":
id := r.URL.Query().Get("id")
if len(id) == 0 {
return errors.New("id param is missing")
}
@ -282,20 +270,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(),
},
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))
}
serptr := atomic.LoadPointer(&mg.service().serviceSerialized)
w.Write(*(*[]byte)(serptr))
w.Write(mg.service().serviceSerialized)
} else if r.Method == "POST" {
body, _ := io.ReadAll(r.Body)
var service serviceDescription
@ -330,8 +318,7 @@ 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" {
serptr := atomic.LoadPointer(&mg.service().divisionsSerialized)
w.Write(*(*[]byte)(serptr))
w.Write(mg.service().divisionsSerialized)
} else if r.Method == "POST" {
var divs map[string]*Division
dec := json.NewDecoder(r.Body)
@ -355,6 +342,109 @@ 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 {
@ -395,6 +485,8 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
r.Body.Close()
}()
r.ParseMultipartForm(32 << 20)
var userinfo map[string]any
if !*devflag {
@ -431,9 +523,9 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
ptr := atomic.LoadPointer(&mg.admins)
adminsptr := (*globalAdmins)(ptr)
if adminsptr.modtime != common.ConfigModTime() {
if adminsptr.modtime != gocommon.ConfigModTime() {
var config globalAdmins
if err := common.LoadConfig(&config); err == nil {
if err := gocommon.LoadConfig(&config); err == nil {
config.parse()
adminsptr = &config
atomic.StorePointer(&mg.admins, unsafe.Pointer(adminsptr))
@ -475,6 +567,12 @@ 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 {

377
core/api_coupon.go Normal file
View File

@ -0,0 +1,377 @@
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))
}

9
core/api_test.go Normal file
View File

@ -0,0 +1,9 @@
package core
import (
"testing"
)
func TestMakeLocalUniqueId(t *testing.T) {
}

View File

@ -9,18 +9,19 @@ import (
"fmt"
"io"
"math/big"
"math/rand"
"net"
"net/http"
"os"
"strings"
"sync/atomic"
"text/template"
"time"
"unsafe"
"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"
@ -35,10 +36,10 @@ 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")
CollectionAuth = gocommon.CollectionName("auth")
CollectionWhitelist = gocommon.CollectionName("whitelist")
CollectionService = gocommon.CollectionName("service")
CollectionAccount = gocommon.CollectionName("account")
@ -51,11 +52,13 @@ var (
)
const (
AuthPlatformSteamSDK = "steam"
AuthPlatformFirebaseAuth = "firebase"
AuthPlatformGoogle = "google"
AuthPlatformMicrosoft = "microsoft"
AuthPlatformApple = "apple"
AuthPlatformTwitter = "twitter"
AuthPlatformHybeim = "hybeim"
)
const (
@ -71,56 +74,13 @@ func SessionTTL() time.Duration {
return sessionTTL
}
type mongoAuthCell struct {
src *gocommon.Authinfo
}
func (ac *mongoAuthCell) ToAuthinfo() *gocommon.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 gocommon.MongoClient, sessionTTL time.Duration) *gocommon.AuthCollection {
authcoll := gocommon.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) gocommon.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"`
@ -138,6 +98,26 @@ 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 {
@ -155,29 +135,32 @@ func (ga *globalAdmins) parse() {
ga.modtime = gocommon.ConfigModTime()
}
type firebaseClient struct {
firebaseAppClient *auth.Client
firebaseAppContext context.Context
}
// Maingate :
type Maingate struct {
maingateConfig
mongoClient gocommon.MongoClient
auths *gocommon.AuthCollection
sessionProvider session.Provider
//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
firebaseAppClient *auth.Client
firebaseAppContext context.Context
firebase *firebaseClient
}
var config maingateConfig
// New :
func New(ctx context.Context) (*Maingate, error) {
var config maingateConfig
if err := gocommon.LoadConfig(&config); err != nil {
return nil, err
}
@ -187,12 +170,15 @@ func New(ctx context.Context) (*Maingate, error) {
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),
@ -202,22 +188,32 @@ func New(ctx context.Context) (*Maingate, error) {
err := mg.prepare(ctx)
if err != nil {
logger.Error("mg.prepare() failed :", err)
return nil, err
}
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
}
if len(*authtype) == 0 {
*authtype = "on"
}
mg.firebaseAppContext = ctx
mg.firebaseAppClient, err = firebaseApp.Auth(mg.firebaseAppContext)
if err != nil {
logger.Println("FirebaseAppClient error getting Auth client:", err)
if !*noauth && (*authtype == "on" || *authtype == "both") {
if len(config.FirebaseAdminSDKCredentialFile) > 0 {
opt := option.WithCredentialsFile(config.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)
if err != nil {
logger.Println("FirebaseAppClient error getting Auth client:", err)
return nil, err
}
mg.firebase = &firebaseClient{
firebaseAppContext: ctx,
firebaseAppClient: firebaseAppClient,
}
}
}
@ -284,101 +280,113 @@ 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 err
return logger.ErrorWithCallStack(err)
}
if err := mg.discoverOpenIdConfiguration("google", "https://accounts.google.com/.well-known/openid-configuration"); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
// redis에서 env를 가져온 후에
mg.mongoClient, err = gocommon.NewMongoClient(context, mg.Mongo, "maingate")
mg.mongoClient, err = gocommon.NewMongoClient(context, config.Mongo)
if err != nil {
return err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionAuth, map[string]bson.D{
"skonly": {{Key: "sk", Value: 1}},
if err = mg.mongoClient.MakeUniqueIndices(CollectionCouponUse, map[string]bson.D{
"idrounds": {{Key: "_id", Value: 1}, {Key: "rounds", Value: 1}},
}); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
"platformuid": {{Key: "platform", Value: 1}, {Key: "uid", Value: 1}},
}); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
"emailplatform": {{Key: "email", Value: 1}, {Key: "platform", Value: 1}},
}); err != nil {
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(CollectionWhitelist, map[string]bson.D{
"service": {{Key: "service", Value: 1}},
if err = mg.mongoClient.MakeIndices(CollectionAccount, map[string]bson.D{
"accid": {{Key: "accid", 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
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionFile, map[string]bson.D{
"sk": {{Key: "service", Value: 1}, {Key: "key", Value: 1}},
"keyonly": {{Key: "key", Value: 1}},
}); err != nil {
return err
return logger.ErrorWithCallStack(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 err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeExpireIndex(CollectionAuth, int32(mg.SessionTTL+300)); err != nil {
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.MakeUniqueIndices(CollectionBlock, map[string]bson.D{
"codeaccid": {{Key: "code", Value: 1}, {Key: "accid", Value: 1}},
"accidend": {{Key: "accid", Value: 1}, {Key: "end", Value: 1}},
}); err != nil {
return err
}
if err = mg.mongoClient.MakeExpireIndex(CollectionBlock, int32(3)); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionPlatformLoginToken, map[string]bson.D{
"platformauthtoken": {{Key: "platform", Value: 1}, {Key: "key", Value: 1}},
}); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(mg.SessionTTL+300)); err != nil {
return err
if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(config.SessionTTL+300)); err != nil {
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionUserToken, map[string]bson.D{
"platformusertoken": {{Key: "platform", Value: 1}, {Key: "userid", Value: 1}},
}); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionGamepotUserInfo, map[string]bson.D{
"gamepotuserid": {{Key: "gamepotuserid", Value: 1}},
}); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeUniqueIndices(CollectionFirebaseUserInfo, map[string]bson.D{
"firebaseuserid": {{Key: "firebaseuserid", Value: 1}},
}); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
mg.auths = makeAuthCollection(mg.mongoClient, time.Duration(mg.SessionTTL*int64(time.Second)))
mg.sessionProvider, err = session.NewProviderWithConfig(context, config.SessionConfig)
if err != nil {
return logger.ErrorWithCallStack(err)
}
var preall []struct {
Link string `bson:"link"`
@ -387,7 +395,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 err
return logger.ErrorWithCallStack(err)
}
for _, pre := range preall {
@ -402,58 +410,40 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
"_id": pre.Id,
}, &fulldoc)
if err != nil {
return err
return logger.ErrorWithCallStack(err)
}
err = fulldoc.Save()
if err != nil {
return err
return logger.ErrorWithCallStack(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
}
func whitelistKey(email string) string {
if strings.HasPrefix(email, "*@") {
// 도메인 전체 허용
return email[2:]
}
var portptr = flagx.Int("port", 80, "")
return email
}
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error {
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) error {
var allServices []*serviceDescription
if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil {
return err
return logger.ErrorWithCallStack(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(),
},
Id: primitive.NewObjectID(),
}
if *devflag {
host, _ := os.Hostname()
addrs, err := net.InterfaceAddrs()
if err != nil {
return err
return logger.ErrorWithCallStack(err)
}
ipaddr := "127.0.0.1"
for _, addr := range addrs {
@ -465,13 +455,15 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
}
empty.Divisions = map[string]*Division{
host: {
"default": {
DivisionForUser: DivisionForUser{
Priority: 0,
State: DivisionState_FullOpen,
},
Url: fmt.Sprintf("http://%s/warehouse", ipaddr),
Urls: bson.M{
"warehouse": fmt.Sprintf("http://%s:%d/warehouse", ipaddr, *portptr),
},
},
}
}
@ -485,19 +477,29 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
}, options.Update().SetUpsert(true))
if err != nil {
return err
return logger.ErrorWithCallStack(err)
}
}
logger.Println("Service is registered :", mg.service().ServiceCode)
serveMux.Handle(gocommon.MakeHttpHandlerPattern(prefix, mg.service().ServiceCode, "/"), mg.service())
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)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "query/"), mg.query)
configraw, _ := json.Marshal(mg.maingateConfig)
configraw, _ := json.Marshal(config)
var convertedConfig map[string]any
if err := json.Unmarshal(configraw, &convertedConfig); err != nil {
return err
return logger.ErrorWithCallStack(err)
}
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "config"), func(w http.ResponseWriter, r *http.Request) {
@ -530,14 +532,26 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
if err := os.MkdirAll("static", os.ModePerm); err != nil {
// 일반 엔드유저한테 오픈할 static 페이지
return err
return logger.ErrorWithCallStack(err)
}
cfsx := http.FileServer(http.Dir("console"))
serveMux.Handle(prefix+"/console/", http.StripPrefix(prefix+"/console/", cfsx))
pattern := gocommon.MakeHttpHandlerPattern(prefix, "console", "/")
serveMux.Handle(pattern, http.StripPrefix(pattern, cfsx))
logger.Println("maingate console registered :", pattern)
staticfs := http.FileServer(http.Dir("static"))
serveMux.Handle(prefix+"/static/", http.StripPrefix(prefix+"/static/", staticfs))
pattern = gocommon.MakeHttpHandlerPattern(prefix, "static", "/")
serveMux.Handle(pattern, http.StripPrefix(pattern, staticfs))
logger.Println("maingate static registered :", pattern)
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(gocommon.MakeHttpHandlerPattern(prefix, "fba", "fb-ga.min.js"), mg.google_analytics_js)
logger.Println("google_analytics.js static registered :", pattern)
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)
@ -558,6 +572,10 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
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)
go mg.watchServiceCollection(ctx, serveMux, prefix)
go mg.watchFileCollection(ctx, serveMux, prefix)
// fsx := http.FileServer(http.Dir("console"))
@ -567,59 +585,11 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
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 !*devflag {
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[rand.Intn(len(allowed))]
b[i] = allowed[r.Intn(len(allowed))]
}
return string(b)
}
@ -633,7 +603,7 @@ func (mg *Maingate) GetUserBrowserInfo(r *http.Request) (string, error) {
cookie, err := r.Cookie("ActionSquareSessionExtraInfo")
if err != nil {
return "", err
return "", logger.ErrorWithCallStack(err)
}
//requestinfo := fmt.Sprintf("%s_%s", cookie.Value, host) //-- RemoteAddr체크는 로드밸런서 IP 찍히는 문제 때문에 제외한다.
@ -655,7 +625,7 @@ func (mg *Maingate) setUserToken(info usertokeninfo) error {
"accesstoken_expire_time": info.accesstoken_expire_time,
},
}, options.Update().SetUpsert(true))
return err
return logger.ErrorWithCallStack(err)
}
func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo string) (usertokeninfo, error) {
@ -680,7 +650,7 @@ func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo
updatetime, ok := found["lastupdate"].(int64)
if !ok || time.Now().Unix()-updatetime < mg.maingateConfig.Autologin_ttl {
if !ok || time.Now().Unix()-updatetime < config.Autologin_ttl {
info.platform = platform
info.userid = userid
info.brinfo = brinfo
@ -727,6 +697,10 @@ 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)
}
@ -936,3 +910,22 @@ 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
}
}

View File

@ -95,8 +95,8 @@ func (mg *Maingate) platform_apple_get_login_url(w http.ResponseWriter, r *http.
}
params := url.Values{}
params.Add("client_id", mg.AppleCientId)
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformApple)
params.Add("client_id", config.AppleCientId)
params.Add("redirect_uri", config.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, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformApple, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
http.Redirect(w, r, config.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(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId)
if err != nil {
logger.Error("error generating secret: ", err)
return
}
vReq := Apple_WebValidationTokenRequest{
ClientID: mg.AppleServiceId,
ClientID: config.AppleServiceId,
ClientSecret: secret,
Code: code,
RedirectURI: mg.RedirectBaseUrl + "/authorize/" + AuthPlatformApple, // This URL must be validated with apple in your service
RedirectURI: config.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(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId)
if err != nil {
logger.Error("error generating secret: ", err)
return false, "", ""
}
vReqRefreshToken := Apple_WebRefreshTokenRequest{
ClientID: mg.AppleServiceId,
ClientID: config.AppleServiceId,
ClientSecret: secret,
RefreshToken: refreshToken,
}

View File

@ -3,6 +3,7 @@ package core
import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"net/url"
@ -146,6 +147,11 @@ 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,
@ -188,7 +194,7 @@ func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, b
return false, ""
}
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, code)
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, code)
if err != nil {
log.Println("error verifying ID token:", err)
return false, ""
@ -242,6 +248,10 @@ 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,
@ -256,13 +266,16 @@ func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, str
return false, "", ""
}
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, info.token)
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.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

View File

@ -84,9 +84,9 @@ func (mg *Maingate) platform_google_get_login_url(w http.ResponseWriter, r *http
}
params := url.Values{}
params.Add("client_id", mg.GoogleClientId)
params.Add("client_id", config.GoogleClientId)
params.Add("response_type", "code")
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("redirect_uri", config.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, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformGoogle, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
http.Redirect(w, r, config.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", mg.GoogleClientId)
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("client_secret", mg.GoogleClientSecret)
params.Add("client_id", config.GoogleClientId)
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("client_secret", config.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", mg.GoogleClientId)
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("client_secret", mg.GoogleClientSecret)
params.Add("client_id", config.GoogleClientId)
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("client_secret", config.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")

198
core/platformhybeim.go Normal file
View File

@ -0,0 +1,198 @@
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
}

View File

@ -83,9 +83,9 @@ func (mg *Maingate) platform_microsoft_get_login_url(w http.ResponseWriter, r *h
}
params := url.Values{}
params.Add("client_id", mg.MicrosoftClientId)
params.Add("client_id", config.MicrosoftClientId)
params.Add("response_type", "code")
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
params.Add("redirect_uri", config.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, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformMicrosoft, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
http.Redirect(w, r, config.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", mg.MicrosoftClientId)
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
params.Add("client_id", config.MicrosoftClientId)
params.Add("redirect_uri", config.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", mg.MicrosoftClientSecret)
params.Add("client_secret", config.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", mg.MicrosoftClientId)
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
params.Add("client_id", config.MicrosoftClientId)
params.Add("redirect_uri", config.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", mg.MicrosoftClientSecret)
params.Add("client_secret", config.MicrosoftClientSecret)
var respReferesh Microsoft_ValidationResponse
acceestoken_expire_time := time.Now().Unix()

121
core/platformsteam.go Normal file
View File

@ -0,0 +1,121 @@
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
}

View File

@ -123,7 +123,7 @@ func (mg *Maingate) platform_twitter_authorize(w http.ResponseWriter, r *http.Re
}
http.SetCookie(w, &cookie)
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformTwitter, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
http.Redirect(w, r, config.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, mg.TwitterOAuthKey, mg.TwitterOAuthSecret, nonce)
return mg.CallTwitterAPI(requesturl, method, config.TwitterOAuthKey, config.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", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter)
vals.Add("oauth_consumer_key", mg.TwitterCustomerKey)
vals.Add("oauth_callback", config.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter)
vals.Add("oauth_consumer_key", config.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(mg.TwitterCustomerSecret) + "&" + url.QueryEscape(oauth_secret)
signingKey := url.QueryEscape(config.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")) +

File diff suppressed because it is too large Load Diff

View File

@ -3,14 +3,13 @@ package core
import (
"context"
"encoding/hex"
"net/http"
"os"
"path"
"sync/atomic"
"time"
"unsafe"
common "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger"
"go.mongodb.org/mongo-driver/bson"
@ -19,14 +18,6 @@ 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 {
@ -43,103 +34,7 @@ type filePipelineDocument struct {
File *FileDocumentDesc `bson:"fullDocument"`
}
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) {
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
defer func() {
s := recover()
if s != nil {
@ -224,7 +119,7 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *htt
}
}
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
defer func() {
s := recover()
if s != nil {
@ -285,11 +180,9 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *
logger.Error("service cannot be prepared :", data.Service, err)
} else {
// 내가 임시로 가지고 있던 서비스일 수 있다.
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())
if mg.service().Id == data.Service.Id {
logger.Println("service is on the board! :", data.Service)
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(data.Service))
}
}
@ -320,87 +213,3 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *
}
}
}
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)
}
}
}

537
fba/js.js Normal file

File diff suppressed because one or more lines are too long

11
fba/track-event.html Normal file
View File

@ -0,0 +1,11 @@
<!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
View File

@ -1,34 +1,38 @@
module repositories.action2quare.com/ayo/maingate
go 1.19
go 1.22.1
require (
firebase.google.com/go v3.13.0+incompatible
github.com/golang-jwt/jwt v3.2.2+incompatible
go.mongodb.org/mongo-driver v1.11.7
google.golang.org/api v0.128.0
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621052811-06ef97f11d22
google.golang.org/api v0.157.0
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86
)
require (
cloud.google.com/go v0.110.2 // indirect
cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go v0.111.0 // indirect
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/firestore v1.10.0 // indirect
cloud.google.com/go/iam v1.1.1 // indirect
cloud.google.com/go/longrunning v0.5.1 // indirect
cloud.google.com/go/firestore v1.14.0 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/longrunning v0.5.4 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/klauspost/compress v1.16.6 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect
@ -38,20 +42,22 @@ require (
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/oauth2 v0.9.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.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
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
)
replace repositories.action2quare.com/ayo/maingate => ./

205
go.sum
View File

@ -1,42 +1,27 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ=
cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM=
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/firestore v1.10.0 h1:FG5C49ukKKqyljY+XNRZGae1HZaiVe7aoqi2BipnBuM=
cloud.google.com/go/firestore v1.10.0/go.mod h1:eAeoQCV8F35Mcy4k8ZrQbcSYZOayIwoiU7ZJ6xzH1+o=
cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
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.4.2 h1:WDKiiNXFTaQ6qz/G8FCOkuY9kJmOJGY67wPUC1M2RbE=
cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ=
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.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI=
cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw=
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg=
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -45,11 +30,16 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
@ -60,16 +50,13 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -86,24 +73,17 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
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.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc=
github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
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 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
@ -112,7 +92,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
@ -126,51 +105,50 @@ 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=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.11.6 h1:XM7G6PjiGAO5betLF13BIa5TlLUUE3uJ/2Ox3Lz1K+o=
go.mongodb.org/mongo-driver v1.11.6/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -178,65 +156,48 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs=
golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -246,41 +207,29 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.123.0 h1:yHVU//vA+qkOhm4reEC9LtzHVUCN/IqqNRl1iQ9xE20=
google.golang.org/api v0.123.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg=
google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750=
google.golang.org/api v0.157.0 h1:ORAeqmbrrozeyw5NjnMxh7peHO0UzV4wWYSwZeCUb20=
google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao=
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/grpc v1.56.0 h1:+y7Bs8rtMd07LeXmL3NxcTLn7mUkbKZqEpPhMNkwJEE=
google.golang.org/grpc v1.56.0/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -292,30 +241,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230612013915-5950ff4bb82e h1:m0jo1r+2NtBfxwj92e6EVaBZpzTDT6Hq7D93vWO4h9Y=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230612013915-5950ff4bb82e/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230614091557-9b877d9a732c h1:fhCuu0jFps8T1sN8hO0fGnatvNDW6VwM96PV26EA3T4=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230614091557-9b877d9a732c/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616031450-0b2c9351a717 h1:WrkkEWN3bh1QAulNJZjAiwXx2aPAj39OoIyJFUXmDaE=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616031450-0b2c9351a717/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616032216-378bc19f3742 h1:qEbzwVDz1w2ewNHu+vipzV+a804wmwRWe+0vnhCbJr4=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616032216-378bc19f3742/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230620005911-15ba3e93d621 h1:9Hzdn13l9U0RJn9mMXsZQr+jsmsgy3zQFsBHPSOJnxM=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230620005911-15ba3e93d621/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621051330-0d8752e66161 h1:sgixcFwdLOqcvwqTaKcsMEepXsLmNEgaybyur3QHRgk=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621051330-0d8752e66161/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
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=
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=

19
main.go
View File

@ -2,11 +2,9 @@ package main
import (
"context"
"math/rand"
"net/http"
"time"
common "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/flagx"
"repositories.action2quare.com/ayo/gocommon/logger"
"repositories.action2quare.com/ayo/maingate/core"
@ -21,26 +19,29 @@ 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)
panic(err)
return
}
defer mg.Destructor()
serveMux := http.NewServeMux()
if err := mg.RegisterHandlers(ctx, serveMux, *prefix); err != nil {
logger.Error("RegisterHandlers failed :", err)
panic(err)
return
}
server := common.NewHTTPServer(serveMux)
server := gocommon.NewHTTPServer(serveMux)
logger.Println("maingate is started")
if err := server.Start(); err != nil {
logger.Error("maingate is stopped with error :", err)
}
cancel()
mg.Destructor()
logger.Println("maingate is terminated")
}

View File

@ -1,30 +0,0 @@
# $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 Normal file

File diff suppressed because one or more lines are too long