Compare commits

...

25 Commits

Author SHA1 Message Date
2d060fe117 [이민권] 쿠폰
- 유효번호 쿠폰 사용 안 되는 이슈 수정
- 유효번호 쿠폰이 사용 불가여도 사용 처리 되는 이슈 수정
2024-02-26 15:51:49 +09:00
231b1a35d5 Revert "[이민우] 운영툴 개선"
This reverts commit 424c8be420.
2024-02-22 17:07:16 +09:00
845784d204 api token 체크 누락 수정 2024-02-21 11:12:25 +09:00
424c8be420 [이민우] 운영툴 개선
- 쿠폰 사용 시 accid 변수타입 잘못 받는 이슈 수정
2024-02-20 11:23:27 +09:00
ce39e8d878 [이민권] go-common 최신화 2024-02-05 18:07:32 +09:00
54c727117b Revert "[이민권] go common 업데이트"
This reverts commit 7816fd56c0.
2024-01-25 17:12:41 +09:00
7816fd56c0 [이민권] go common 업데이트 2024-01-25 17:12:03 +09:00
564a2ee14a [이민권] 계정 삭제
- 버그 수정
2024-01-25 17:08:51 +09:00
cbcae00c77 [이민권] 계정 삭제
- 버그 수정
2024-01-25 16:18:38 +09:00
28dc84769d [이민우] 운영툴 개선
- 쿠폰 만료시간 못가져오는 이슈 수정
2024-01-22 17:43:53 +09:00
0c678947cd [이민우] 운영툴 개선
- 쿠폰 만료시간 안되는 이슈 수정
- 전체 유저 제재 목록을 볼 수 있도록 수정
2024-01-22 11:37:07 +09:00
dbd0a7bf5f [이민우] 운영툴 개선
- 쿠폰 삭제 기능 추가
- 쿠폰 만료 날짜 추가
- 무한인지 일회용인지 판별하여 쿠폰 사용 유무 검사
2024-01-19 14:24:52 +09:00
86247e053d 계정 이메일 조회 기능 추가
-> kd브렌치에 맞춰서 오류난 부분 수정
2024-01-16 12:13:20 +09:00
757c6d312c 계정 이메일 조회 기능 추가
Cherrypick - e7b3f59dd0
2024-01-16 11:47:26 +09:00
e37a974d9c [이민권] 계정 삭제
- 계정 삭제 시, Firebase 정보 삭제
2024-01-12 12:31:21 +09:00
470591cb44 [이민권] 계정 삭제
- 계정 삭제 취소 기능 추가
2024-01-11 19:11:43 +09:00
38114769b3 [이민권] 계정 삭제
- 계정 삭제 취소 기능 추가
2024-01-11 12:54:48 +09:00
b05473a1c6 [이민권] 계정 삭제
- 계정 삭제 취소 기능 추가
2024-01-10 18:40:38 +09:00
0fff694e8a [이민권] 계정 삭제
- 계정 삭제 취소 기능 추가
2024-01-10 18:10:18 +09:00
d8713298c4 [이민권] 계정 삭제
- 계정 삭제 취소 기능 추가
2024-01-10 17:35:00 +09:00
763b0fc4bd [이민권] 계정 삭제
- 계정 삭제 취소 기능 추가
2024-01-10 17:28:24 +09:00
d8e18d7ffc [이민권] 서비스 준비
- 계정 삭제 시, TTL 적용
2024-01-09 19:56:57 +09:00
381f1edb80 [이민우] 정보가 아니라 주소갑이 나와서 수정 (대리 커밋) 2023-12-08 17:08:14 +09:00
a8e448b8ca 로그 정리 2023-10-30 17:25:39 +09:00
9b0e3a5d5b 모듈 정리 2023-10-30 17:25:31 +09:00
8 changed files with 264 additions and 97 deletions

View File

@ -1,6 +1,7 @@
{ {
"maingate_mongodb_url": "mongodb://...", "maingate_mongodb_url": "mongodb://...",
"autologin_ttl": 604800, "autologin_ttl": 604800,
"acc_del_ttl": 7776000,
"maximum_num_link_account": 10, "maximum_num_link_account": 10,
"redirect_base_url": "", "redirect_base_url": "",
"google_client_id" : "", "google_client_id" : "",

View File

@ -161,14 +161,7 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error { func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
mg := caller.mg mg := caller.mg
if r.Method == "GET" { if r.Method == "GET" {
target, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
if ok {
json.NewEncoder(w).Encode(mg.bl.all()) json.NewEncoder(w).Encode(mg.bl.all())
} else if !target.IsZero() {
if blocked, ok := mg.bl.get(target); ok && blocked != nil {
json.NewEncoder(w).Encode(blocked)
}
}
} else if r.Method == "PUT" { } else if r.Method == "PUT" {
body, _ := io.ReadAll(r.Body) body, _ := io.ReadAll(r.Body)
@ -379,6 +372,11 @@ func (caller apiCaller) couponAPI(w http.ResponseWriter, r *http.Request) error
logger.Println("begin listAllCouponNames") logger.Println("begin listAllCouponNames")
listAllCouponNames(caller.mg.mongoClient, w, r) listAllCouponNames(caller.mg.mongoClient, w, r)
} }
case "DELETE":
// 쿠폰 삭제
logger.Println("begin deleteCoupon")
deleteCoupon(caller.mg.mongoClient, w, r)
} }
return nil return nil
} }
@ -461,11 +459,28 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
var userinfo map[string]any var userinfo map[string]any
var apiTokenObj primitive.ObjectID
if !*devflag { if !*devflag {
apiToken := r.Header.Get("MG-X-API-TOKEN")
if len(apiToken) > 0 {
if apiToken != mg.maingateConfig.ApiToken {
w.WriteHeader(http.StatusUnauthorized)
return
}
obj, err := primitive.ObjectIDFromHex(apiToken)
if err != nil {
logger.Error(err)
w.WriteHeader(http.StatusBadRequest)
return
}
apiTokenObj = obj
} else {
authheader := r.Header.Get("Authorization") authheader := r.Header.Get("Authorization")
if len(authheader) == 0 { if len(authheader) == 0 {
logger.Println("Authorization header is not valid :", authheader) logger.Println("Authorization header is not valid :", authheader)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusUnauthorized)
return return
} }
@ -491,6 +506,7 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
return return
} }
} }
}
ptr := atomic.LoadPointer(&mg.admins) ptr := atomic.LoadPointer(&mg.admins)
adminsptr := (*globalAdmins)(ptr) adminsptr := (*globalAdmins)(ptr)
@ -504,20 +520,6 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
} }
} }
var apiTokenObj primitive.ObjectID
if !*devflag {
apiToken := r.Header.Get("MG-X-API-TOKEN")
if len(apiToken) > 0 {
obj, err := primitive.ObjectIDFromHex(apiToken)
if err != nil {
logger.Error(err)
w.WriteHeader(http.StatusBadRequest)
return
}
apiTokenObj = obj
}
}
logger.Println("api call :", r.URL.Path, r.Method, r.URL.Query(), userinfo) logger.Println("api call :", r.URL.Path, r.Method, r.URL.Query(), userinfo)
caller := apiCaller{ caller := apiCaller{
userinfo: userinfo, userinfo: userinfo,

View File

@ -30,6 +30,7 @@ type couponDoc struct {
Total int64 `json:"total" bson:"total"` Total int64 `json:"total" bson:"total"`
Remains []string `json:"remains,omitempty" bson:"remains,omitempty"` Remains []string `json:"remains,omitempty" bson:"remains,omitempty"`
Used []string `json:"used,omitempty" bson:"used,omitempty"` Used []string `json:"used,omitempty" bson:"used,omitempty"`
Expire int64 `json:"expire" bson:"expire"`
} }
func makeCouponKey(roundnum uint32, uid []byte) string { func makeCouponKey(roundnum uint32, uid []byte) string {
@ -72,6 +73,7 @@ func generateCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r
effect, _ := gocommon.ReadStringFormValue(r.Form, "effect") effect, _ := gocommon.ReadStringFormValue(r.Form, "effect")
count, _ := gocommon.ReadIntegerFormValue(r.Form, "count") count, _ := gocommon.ReadIntegerFormValue(r.Form, "count")
desc, _ := gocommon.ReadStringFormValue(r.Form, "desc") desc, _ := gocommon.ReadStringFormValue(r.Form, "desc")
expire, _ := gocommon.ReadIntegerFormValue(r.Form, "expire")
if count == 0 { if count == 0 {
logger.Println("[generateCoupons] count == 0") logger.Println("[generateCoupons] count == 0")
@ -92,6 +94,7 @@ func generateCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r
Effect: effect, Effect: effect,
Desc: desc, Desc: desc,
Total: -1, Total: -1,
Expire: expire,
}, },
}, options.Update().SetUpsert(true)); err != nil { }, options.Update().SetUpsert(true)); err != nil {
logger.Println("[generateCoupons] Update failed :", err) logger.Println("[generateCoupons] Update failed :", err)
@ -154,6 +157,7 @@ func generateCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r
Effect: effect, Effect: effect,
Desc: desc, Desc: desc,
Total: count, Total: count,
Expire: expire,
}, },
}, options.Update().SetUpsert(true)) }, options.Update().SetUpsert(true))
} }
@ -198,7 +202,12 @@ func downloadCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r
roundnum := binary.BigEndian.Uint32(roundObj[:]) roundnum := binary.BigEndian.Uint32(roundObj[:])
var coupons []string var coupons []string
for _, uid := range coupon.Remains { for _, uid := range coupon.Remains {
coupons = append(coupons, makeCouponKey(roundnum, []byte(uid))) 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 := json.NewEncoder(w)
@ -231,7 +240,7 @@ func queryCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *htt
var coupon couponDoc var coupon couponDoc
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{ if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
"_id": roundObj, "_id": roundObj,
}, &coupon, options.FindOne().SetProjection(bson.M{"effect": 1, "name": 1, "reason": 1, "total": 1, "desc": 1}).SetReturnKey(false)); err != nil { }, &coupon, options.FindOne().SetProjection(bson.M{"effect": 1, "name": 1, "reason": 1, "total": 1, "desc": 1, "expire": 1}).SetReturnKey(false)); err != nil {
logger.Println("[queryCoupon] FindOneAs failed :", err) logger.Println("[queryCoupon] FindOneAs failed :", err)
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
@ -275,8 +284,8 @@ func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.
round, _ = coupon.MakeCouponRoundHash(code) round, _ = coupon.MakeCouponRoundHash(code)
} }
// 1. 내가 이 라운드의 쿠폰을 쓴 적이 있나 // 쿠폰 사용 유무 검사
already, err := mongoClient.Exists(CollectionCouponUse, bson.M{ alreadyused, err := mongoClient.Exists(CollectionCouponUse, bson.M{
"_id": acc, "_id": acc,
"rounds": round, "rounds": round,
}) })
@ -286,7 +295,7 @@ func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.
return return
} }
if already { if alreadyused {
// 이미 이 라운드의 쿠폰을 사용한 적이 있다. // 이미 이 라운드의 쿠폰을 사용한 적이 있다.
w.WriteHeader(http.StatusConflict) w.WriteHeader(http.StatusConflict)
return return
@ -298,7 +307,7 @@ func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.
// 무한 쿠폰일 수 있으므로 존재하는지 확인 // 무한 쿠폰일 수 있으므로 존재하는지 확인
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{ if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
"_id": roundObj, "_id": roundObj,
}, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "effect": 1, "name": 1, "reason": 1, "total": 1})); err != nil { }, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "effect": 1, "name": 1, "total": 1, "expire": 1})); err != nil {
logger.Println(err) logger.Println(err)
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
@ -310,9 +319,10 @@ func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.
return return
} }
} else { } else {
// 2. 쿠폰을 하나 꺼냄 // 쿠폰을 하나 꺼냄
matched, _, err := mongoClient.Update(CollectionCoupon, bson.M{ matched, _, err := mongoClient.Update(CollectionCoupon, bson.M{
"_id": roundObj, "_id": roundObj,
"remains": key,
}, bson.M{ }, bson.M{
"$pull": bson.M{"remains": key}, "$pull": bson.M{"remains": key},
}) })
@ -328,18 +338,24 @@ func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.
return return
} }
// 3. round의 효과 읽기 // round의 효과 읽기
if err := mongoClient.FindOneAndUpdateAs(CollectionCoupon, bson.M{ if err := mongoClient.FindOneAndUpdateAs(CollectionCoupon, bson.M{
"_id": roundObj, "_id": roundObj,
}, bson.M{ }, bson.M{
"$push": bson.M{"used": key}, "$push": bson.M{"used": key},
}, &coupon, options.FindOneAndUpdate().SetProjection(bson.M{"effect": 1})); err != nil { }, &coupon, options.FindOneAndUpdate().SetProjection(bson.M{"effect": 1, "expire": 1})); err != nil {
logger.Println(err) logger.Println(err)
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
} }
if coupon.Expire < time.Now().Unix() {
// 쿠폰 만료시간 경과
w.WriteHeader(http.StatusInternalServerError)
return
}
if len(coupon.Effect) == 0 { if len(coupon.Effect) == 0 {
// 쿠폰이 없네? // 쿠폰이 없네?
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
@ -370,3 +386,22 @@ func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.
w.Write([]byte(coupon.Effect)) w.Write([]byte(coupon.Effect))
} }
func deleteCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
code, _ := gocommon.ReadStringFormValue(r.Form, "name")
if len(code) == 0 {
logger.Println("coupon delete code error")
w.WriteHeader(http.StatusBadRequest)
return
}
_, err := mongoClient.Delete(CollectionCoupon, bson.M{
"name": code,
})
if err != nil {
logger.Println("coupon delete error")
w.WriteHeader(http.StatusBadRequest)
return
}
}

View File

@ -123,7 +123,9 @@ func makeAuthCollection(mongoClient gocommon.MongoClient, sessionTTL time.Durati
type maingateConfig struct { type maingateConfig struct {
Mongo string `json:"maingate_mongodb_url"` Mongo string `json:"maingate_mongodb_url"`
SessionTTL int64 `json:"maingate_session_ttl"` SessionTTL int64 `json:"maingate_session_ttl"`
ApiToken string `json:"maingate_api_token"`
Autologin_ttl int64 `json:"autologin_ttl"` Autologin_ttl int64 `json:"autologin_ttl"`
AccDelTTL int64 `json:"acc_del_ttl"`
MaximumNumLinkAccount int64 `json:"maximum_num_link_account"` MaximumNumLinkAccount int64 `json:"maximum_num_link_account"`
RedirectBaseUrl string `json:"redirect_base_url"` RedirectBaseUrl string `json:"redirect_base_url"`
GoogleClientId string `json:"google_client_id"` GoogleClientId string `json:"google_client_id"`
@ -354,6 +356,14 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
return makeErrorWithStack(err) return makeErrorWithStack(err)
} }
if err = mg.mongoClient.MakeExpireIndex(CollectionAccount, int32(mg.AccDelTTL)); err != nil {
return makeErrorWithStack(err)
}
if err = mg.mongoClient.MakeExpireIndex(CollectionLink, int32(mg.AccDelTTL)); err != nil {
return makeErrorWithStack(err)
}
// Delete대신 _ts로 expire시킴. pipeline에 삭제 알려주기 위함 // Delete대신 _ts로 expire시킴. pipeline에 삭제 알려주기 위함
if err = mg.mongoClient.MakeExpireIndex(CollectionWhitelist, 10); err != nil { if err = mg.mongoClient.MakeExpireIndex(CollectionWhitelist, 10); err != nil {
return makeErrorWithStack(err) return makeErrorWithStack(err)

View File

@ -95,7 +95,7 @@ func (p *memberContainerPtr[K, T]) contains(key K, out *T) bool {
return false return false
} }
if out != nil { if out != nil {
out = &found *out = found
} }
return true return true
} }

View File

@ -322,7 +322,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
if !guestlink { if !guestlink {
_, err = sh.readProfile(oldType, oldId, bfinfo) _, err = sh.readProfile(oldType, oldId, bfinfo)
if err != nil { if err != nil {
logger.Error("readProfile(old) failed :", err) logger.Println("readProfile(old) failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -332,7 +332,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
oldType, oldId, err = sh.getProviderInfo(oldType, oldId) oldType, oldId, err = sh.getProviderInfo(oldType, oldId)
if err != nil { if err != nil {
logger.Error("getProviderInfo failed :", err) logger.Println("getProviderInfo failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -346,7 +346,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
email, err := sh.readProfile(newType, newId, bfinfo) email, err := sh.readProfile(newType, newId, bfinfo)
if err != nil { if err != nil {
logger.Error("readProfile(new) failed :", err) logger.Println("readProfile(new) failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -359,7 +359,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
newType, newId, err = sh.getProviderInfo(newType, newId) newType, newId, err = sh.getProviderInfo(newType, newId)
if err != nil { if err != nil {
logger.Error("getProviderInfo failed :", err) logger.Println("getProviderInfo failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -390,7 +390,7 @@ func (sh *serviceDescription) link(w http.ResponseWriter, r *http.Request) {
}, options.Update().SetUpsert(true)) }, options.Update().SetUpsert(true))
if err != nil { if err != nil {
logger.Error("link failed. Update ServiceName err :", err) logger.Error("link failed. Update ServiceName err :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusInternalServerError)
return return
} }
@ -457,7 +457,7 @@ func (sh *serviceDescription) unlink(w http.ResponseWriter, r *http.Request) {
sType, sId, err := sh.getProviderInfo(sType, sId) sType, sId, err := sh.getProviderInfo(sType, sId)
if err != nil { if err != nil {
logger.Error("getProviderInfo failed :", err) logger.Println("getProviderInfo failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -476,7 +476,7 @@ func (sh *serviceDescription) unlink(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
logger.Error("unlink failed, fail to count accounts :", err) logger.Error("unlink failed, fail to count accounts :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusInternalServerError)
} }
if len(accDocs) <= 1 { if len(accDocs) <= 1 {
@ -505,7 +505,7 @@ func (sh *serviceDescription) unlink(w http.ResponseWriter, r *http.Request) {
}, options.FindOneAndDelete().SetProjection(bson.M{"_id": 1})) }, options.FindOneAndDelete().SetProjection(bson.M{"_id": 1}))
if err != nil { if err != nil {
logger.Error("unlink failed. Delete ServiceName err :", err) logger.Error("unlink failed. Delete ServiceName err :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusInternalServerError)
return return
} }
if preid == nil { if preid == nil {
@ -554,7 +554,7 @@ func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
sType, sId, err := sh.getProviderInfo(sType, sId) sType, sId, err := sh.getProviderInfo(sType, sId)
if err != nil { if err != nil {
logger.Error("getProviderInfo failed :", err) logger.Println("getProviderInfo failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -574,7 +574,7 @@ func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
})) }))
if err != nil { if err != nil {
logger.Error("linkinfo failed. CountDocuments err :", err) logger.Error("linkinfo failed. CountDocuments err :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusInternalServerError)
return return
} }
@ -588,6 +588,11 @@ func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
}, options.Find().SetLimit(sh.MaximumNumLinkAccount).SetProjection(bson.M{ }, options.Find().SetLimit(sh.MaximumNumLinkAccount).SetProjection(bson.M{
platformName: 1, platformName: 1,
})) }))
if err != nil {
logger.Error("linkinfo failed. FindAll returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
var linkstrs []string var linkstrs []string
for _, link := range links { for _, link := range links {
@ -597,7 +602,7 @@ func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
linkbytes, err := json.Marshal(linkstrs) linkbytes, err := json.Marshal(linkstrs)
if err != nil { if err != nil {
logger.Error("linkinfo failed. json marshal fail :", err) logger.Error("linkinfo failed. json marshal fail :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusInternalServerError)
return return
} }
@ -605,6 +610,49 @@ func (sh *serviceDescription) linkinfo(w http.ResponseWriter, r *http.Request) {
w.Write(linkbytes) w.Write(linkbytes)
} }
// == 계정 이메일 조회
func (sh *serviceDescription) emailinfo(w http.ResponseWriter, r *http.Request) {
defer func() {
s := recover()
if s != nil {
logger.Error(s)
}
}()
if r.Method != "GET" {
w.WriteHeader(http.StatusBadRequest)
return
}
queryvals := r.URL.Query()
sk := queryvals.Get("sk")
authInfo := sh.auths.Find(sk)
if authInfo == nil {
logger.Println(" session key is not valid :", sk)
w.WriteHeader(http.StatusInternalServerError)
return
}
email := authInfo.Email
if strings.HasPrefix(email, "__dummy_") && strings.HasSuffix(email, "temp__") {
email = ""
}
if strings.HasSuffix(email, "@noauth.flag") || strings.HasSuffix(email, "@guest.flag") {
email = ""
}
// fmt.Println("=================")
// fmt.Println(email)
// fmt.Println("=================")
//logger.Println("Email :", email)
w.Write([]byte(fmt.Sprintf(`{"email":"%s"}`, email)))
}
func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request) { func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request) {
defer func() { defer func() {
s := recover() s := recover()
@ -630,29 +678,29 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
//email, err := sh.readProfile(authtype, uid, accesstoken) //email, err := sh.readProfile(authtype, uid, accesstoken)
bfinfo, err := sh.getUserBrowserInfo(r) bfinfo, err := sh.getUserBrowserInfo(r)
if err != nil { if err != nil {
logger.Error("getUserBrowserInfo failed :", err) logger.Println("getUserBrowserInfo failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
email, err = sh.readProfile(authtype, uid, bfinfo) email, err = sh.readProfile(authtype, uid, bfinfo)
if err != nil { if err != nil {
logger.Error("readProfile failed :", err) logger.Println("readProfile failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
newType, newId, err := sh.getProviderInfo(authtype, uid) newType, newId, err := sh.getProviderInfo(authtype, uid)
if err != nil { if err != nil {
logger.Error("getProviderInfo failed :", err) logger.Println("getProviderInfo failed :", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
if authtype != newType || uid != newId { if authtype != newType || uid != newId {
logger.Printf("auth success ( redirect ) : %s->%s, %s->%s, %s, %s", authtype, newType, uid, newId, email, session)
authtype = newType authtype = newType
uid = newId uid = newId
logger.Println("auth success ( redirect ) :", authtype, uid, email, session)
} }
} else { } else {
email = fmt.Sprintf("%s@guest.flag", uid) email = fmt.Sprintf("%s@guest.flag", uid)
@ -673,13 +721,15 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
"create": createtime, "create": createtime,
"email": email, "email": email,
}, },
}, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(true).SetProjection(bson.M{"_id": 1})) }, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(true).SetProjection(bson.M{
"_id": 1,
"_ts": 1,
}))
if err != nil { if err != nil {
logger.Error("authorize failed :", err) logger.Error("authorize failed :", err)
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
linkid := link["_id"].(primitive.ObjectID) linkid := link["_id"].(primitive.ObjectID)
newaccid := primitive.NewObjectID() newaccid := primitive.NewObjectID()
for i := 0; i < len(sh.serviceCodeBytes); i++ { for i := 0; i < len(sh.serviceCodeBytes); i++ {
@ -733,6 +783,8 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
return return
} }
logger.Println("session created :", accid, authtype, uid, email, newsession)
output := map[string]any{ output := map[string]any{
"sk": newsession.Hex(), "sk": newsession.Hex(),
"expirein": sh.sessionTTL.Seconds(), "expirein": sh.sessionTTL.Seconds(),
@ -742,6 +794,14 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
if *noauth { if *noauth {
output["noauth"] = true output["noauth"] = true
} }
if link["_ts"] != nil {
delts := link["_ts"].(primitive.DateTime)
if !delts.Time().IsZero() {
// 삭제된 계정. 삭제 되었다고 알려주자
w.Header().Add("MG-ACCOUNT-DELETED", "TRUE")
}
}
bt, _ := json.Marshal(output) bt, _ := json.Marshal(output)
w.Write(bt) w.Write(bt)
} else if len(session) > 0 { } else if len(session) > 0 {
@ -757,8 +817,7 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
}, },
}, options.Update().SetUpsert(false)) }, options.Update().SetUpsert(false))
if err != nil { if err != nil {
logger.Error("update auth collection failed") logger.Error("update auth collection failed :", err)
logger.Error(err)
return return
} }
@ -773,6 +832,31 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
"sk": session, "sk": session,
"expirein": sh.sessionTTL.Seconds(), "expirein": sh.sessionTTL.Seconds(),
} }
logger.Println("session updated :", authtype, uid, session)
authInfo := sh.auths.Find(session)
if authInfo == nil {
// 잘못된 세션
logger.Println("authorize failed. fail to find authInfo :", session)
w.WriteHeader(http.StatusBadRequest)
return
}
//혹시 삭제 된 계정 아닌지 확인해본다.
link, err := sh.mongoClient.FindOne(CollectionLink, bson.M{
"platform": authtype,
"uid": uid,
}, options.FindOne().SetProjection(bson.M{
"_ts": 1,
}))
if link["_ts"] != nil {
delts := link["_ts"].(primitive.DateTime)
if !delts.Time().IsZero() {
// 삭제된 계정. 삭제 되었다고 알려주자
w.Header().Add("MG-ACCOUNT-DELETED", "TRUE")
}
}
bt, _ := json.Marshal(output) bt, _ := json.Marshal(output)
w.Write(bt) w.Write(bt)
} else { } else {
@ -815,6 +899,7 @@ func (sh *serviceDescription) delacc(w http.ResponseWriter, r *http.Request) {
sType := queryvals.Get("stype") sType := queryvals.Get("stype")
sId := queryvals.Get("sid") sId := queryvals.Get("sid")
sk := queryvals.Get("sk") sk := queryvals.Get("sk")
cancel := queryvals.Has("cancel")
authInfo := sh.auths.Find(sk) authInfo := sh.auths.Find(sk)
if authInfo == nil { if authInfo == nil {
@ -824,13 +909,21 @@ func (sh *serviceDescription) delacc(w http.ResponseWriter, r *http.Request) {
return return
} }
originAuthType := sType
sType, sId, err := sh.getProviderInfo(sType, sId)
if err != nil {
logger.Error("delacc failed. getProviderInfo err :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
if authInfo.Uid != sId || authInfo.Platform != sType { if authInfo.Uid != sId || authInfo.Platform != sType {
logger.Println("delacc failed. session key is not correct :", *authInfo, queryvals) logger.Println("delacc failed. session key is not correct :", *authInfo, queryvals)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
accids, err := sh.mongoClient.FindAll(CollectionAccount, bson.M{ linkidMap, err := sh.mongoClient.FindAll(CollectionAccount, bson.M{
"accid": authInfo.Accid, "accid": authInfo.Accid,
}, options.Find().SetProjection(bson.M{ }, options.Find().SetProjection(bson.M{
"_id": 1, "_id": 1,
@ -841,27 +934,55 @@ func (sh *serviceDescription) delacc(w http.ResponseWriter, r *http.Request) {
return return
} }
var addIdFilter bson.A var linkidAry primitive.A
for _, accid := range accids { for _, linkid := range linkidMap {
addIdFilter = append(addIdFilter, accid["_id"].(primitive.ObjectID)) linkidAry = append(linkidAry, linkid["_id"].(primitive.ObjectID))
} }
delfilter := bson.D{{Key: "_id", Value: bson.D{{Key: "$in", Value: addIdFilter}}}} delfilter := primitive.M{"_id": bson.M{"$in": linkidAry}}
delaccnum, err := sh.mongoClient.DeleteMany(CollectionAccount, delfilter) var delop primitive.M
if err != nil { if !cancel {
logger.Error("delacc failed. Delete many CollectionAccount err :", err) curtime := primitive.NewDateTimeFromTime(time.Now().UTC())
w.WriteHeader(http.StatusBadRequest) delop = primitive.M{
"$set": primitive.M{"_ts": curtime},
}
if originAuthType == AuthPlatformFirebaseAuth {
sh.mongoClient.Delete(CollectionFirebaseUserInfo, bson.M{
"firebaseuserid": sId,
})
}
} else {
delfilter["platform"] = sType
targetLinkId, err := sh.mongoClient.FindAll(CollectionLink, delfilter, options.Find().SetProjection(bson.M{
"_id": 1,
}))
if len(targetLinkId) != 1 {
logger.Error("delacc failed. FindAll link err :", err)
w.WriteHeader(http.StatusInternalServerError)
return return
} }
_, err = sh.mongoClient.DeleteMany(CollectionLink, delfilter) delfilter = primitive.M{"_id": targetLinkId[0]["_id"].(primitive.ObjectID)}
if err != nil { delop = primitive.M{
logger.Error("delacc failed. Delete many CollectionLink err :", err) "$unset": primitive.M{"_ts": true},
w.WriteHeader(http.StatusBadRequest) }
}
updated, _, err := sh.mongoClient.Update(CollectionAccount, delfilter, delop, options.Update().SetUpsert(false))
if !updated || err != nil {
logger.Error("delacc failed. Update CollectionAccount timestamp err :", err)
w.WriteHeader(http.StatusInternalServerError)
return return
} }
logger.Println("delacc success :", delaccnum) updated, _, err = sh.mongoClient.Update(CollectionLink, delfilter, delop, options.Update().SetUpsert(false))
if !updated || err != nil {
logger.Error("delacc failed. Update CollectionLink timestamp err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
logger.Println("delacc success :", linkidMap)
} }
func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request) { func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request) {
@ -885,6 +1006,8 @@ func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request)
sh.unlink(w, r) sh.unlink(w, r)
} else if strings.HasSuffix(r.URL.Path, "/linkinfo") { } else if strings.HasSuffix(r.URL.Path, "/linkinfo") {
sh.linkinfo(w, r) sh.linkinfo(w, r)
} else if strings.HasSuffix(r.URL.Path, "/emailinfo") {
sh.emailinfo(w, r)
} else if strings.HasSuffix(r.URL.Path, "/delacc") { } else if strings.HasSuffix(r.URL.Path, "/delacc") {
sh.delacc(w, r) sh.delacc(w, r)
} else if strings.HasSuffix(r.URL.Path, "/divs") { } else if strings.HasSuffix(r.URL.Path, "/divs") {
@ -964,7 +1087,7 @@ func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request)
} }
} }
} else { } else {
logger.Println("div is not found :", divname) logger.Println("div is not found :", divname, sh.Divisions)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
} }
} else { } else {

2
go.mod
View File

@ -7,7 +7,7 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
go.mongodb.org/mongo-driver v1.11.7 go.mongodb.org/mongo-driver v1.11.7
google.golang.org/api v0.128.0 google.golang.org/api v0.128.0
repositories.action2quare.com/ayo/gocommon v0.0.0-20230912075917-f9a146321cdb repositories.action2quare.com/ayo/gocommon v0.0.0-20240205060841-c31f838ba8a9
) )
require ( require (

8
go.sum
View File

@ -268,11 +268,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/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-20230710085810-8173216e9574 h1:Ha0d/sv/MzC3ASCTXfe2tAFJieLNJmTCBL8aETEOY14=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710085810-8173216e9574/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230911034515-1af5d7281946 h1:YSvgTNuHeKis37+FfOvzVLYCaXQ0oF+CWBTy4bRqq3g=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230911034515-1af5d7281946/go.mod h1:XvklTTSvQX5uviivGBcZo8eIL+mV94W2e4uBBXcT5JY=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230912074842-ea8ae4d02c7d h1:W6Ir1+kA6wMDya7bYz2S2X96qhb25FKpa/+wnHnSNVo=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230912074842-ea8ae4d02c7d/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230912075917-f9a146321cdb h1:Rdf6uhBIWunRLZ2LIT1hSovYXxZoOzx9mdSK5bjWpos= repositories.action2quare.com/ayo/gocommon v0.0.0-20230912075917-f9a146321cdb h1:Rdf6uhBIWunRLZ2LIT1hSovYXxZoOzx9mdSK5bjWpos=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230912075917-f9a146321cdb/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0= repositories.action2quare.com/ayo/gocommon v0.0.0-20230912075917-f9a146321cdb/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240205060841-c31f838ba8a9 h1:5cQ60XjlI7k0qld0rIpd6gy7+a9csv3ijz1EVKTzsy8=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240205060841-c31f838ba8a9/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=