From 8f9b9cf402ec5115d93c21ab9ee08b59aaa8ed8e Mon Sep 17 00:00:00 2001 From: l2vator Date: Mon, 15 Jul 2024 12:37:52 +0900 Subject: [PATCH] =?UTF-8?q?[=EC=98=A4=EC=8A=B9=EC=84=9D]=20=EA=B3=84?= =?UTF-8?q?=EC=A0=95=20=EC=82=AD=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/maingate.go | 9 ++++ core/service.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/core/maingate.go b/core/maingate.go index 90bcfc9..055763b 100644 --- a/core/maingate.go +++ b/core/maingate.go @@ -79,6 +79,7 @@ type maingateConfig struct { MustUseChecksum bool `json:"maingate_must_checksum"` Mongo string `json:"maingate_mongodb_url"` 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"` @@ -323,6 +324,14 @@ func (mg *Maingate) prepare(context context.Context) (err error) { 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 logger.ErrorWithCallStack(err) diff --git a/core/service.go b/core/service.go index 6ec9943..d427300 100644 --- a/core/service.go +++ b/core/service.go @@ -743,7 +743,7 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request) "create": createtime, "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 { logger.Error("authorize failed :", err) w.WriteHeader(http.StatusInternalServerError) @@ -800,6 +800,14 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request) output["noauth"] = true } + if link["_ts"] != nil { + delts := link["_ts"].(primitive.DateTime) + if !delts.Time().IsZero() { + // 삭제된 계정. 삭제 되었다고 알려주자 + w.Header().Add("MG-ACCOUNT-DELETED", "TRUE") + } + } + json.NewEncoder(w).Encode(output) } @@ -816,6 +824,98 @@ func (sh *serviceDescription) findVersionSplit(version string) []byte { return sh.divisionsSplits["default"] } +func (sh *serviceDescription) delacc(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() + sType := queryvals.Get("stype") + sId := queryvals.Get("sid") + sk := queryvals.Get("sk") + cancel := queryvals.Has("cancel") + + authInfo, err := sh.sessionProvider.Query(sk) + if err != nil { + logger.Println("sessionProvider.Query return err :", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + originAuthType := sType + if !*noauth && !*devflag { + 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 { + logger.Println("delacc failed. session key is not correct :", authInfo, queryvals) + w.WriteHeader(http.StatusBadRequest) + return + } + + linkidMap, err := sh.mongoClient.FindAll(CollectionAccount, bson.M{"accid": authInfo.Account}, options.Find().SetProjection(bson.M{"_id": 1})) + if err != nil { + logger.Error("delacc failed. FindAll account err :", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + var linkidAry primitive.A + for _, linkid := range linkidMap { + linkidAry = append(linkidAry, linkid["_id"].(primitive.ObjectID)) + } + + delfilter := primitive.M{"_id": bson.M{"$in": linkidAry}} + var delop primitive.M + if !cancel { + curtime := time.Now().UTC() + delop = primitive.M{"$set": primitive.M{"_ts": primitive.NewDateTimeFromTime(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 + } + + delfilter = primitive.M{"_id": targetLinkId[0]["_id"].(primitive.ObjectID)} + delop = primitive.M{"$unset": primitive.M{"_ts": true}} + } + updated, _, err := sh.mongoClient.Update(CollectionAccount, delfilter, delop, options.Update().SetUpsert(false)) + if !updated || err != nil { + logger.Error("delacc failed. Update CollectionAccount timestamp err :", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + updated, _, err = sh.mongoClient.Update(CollectionLink, delfilter, delop, options.Update().SetUpsert(false)) + if !updated || err != nil { + logger.Error("delacc failed. Update CollectionLink timestamp err :", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + logger.Println("delacc success :", linkidMap) +} + func (sh *serviceDescription) serveHTTP_dev(w http.ResponseWriter, r *http.Request) { if strings.HasSuffix(r.URL.Path, "/auth") { sh.authorize_dev(w, r) @@ -847,6 +947,8 @@ func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request) sh.linkinfo(w, r) } else if strings.HasSuffix(r.URL.Path, "/emailinfo") { sh.emailinfo(w, r) + } else if strings.HasSuffix(r.URL.Path, "/delacc") { + sh.delacc(w, r) } else if strings.HasSuffix(r.URL.Path, "/divs") { // TODO : 세션키와 authtoken을 헤더로 받아서 accid 조회 queryvals := r.URL.Query()