345 lines
9.7 KiB
Go
345 lines
9.7 KiB
Go
package core
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
type GamepotTemplate struct {
|
|
RedirectBaseUrl string
|
|
State string
|
|
}
|
|
|
|
type Gamepot_LoginValidationResponse struct {
|
|
Message string `json:"message"`
|
|
Status int `json:"status"`
|
|
}
|
|
|
|
func (mg *Maingate) platform_gamepot_get_login_url(w http.ResponseWriter, r *http.Request) {
|
|
|
|
browserinfo, err := mg.GetUserBrowserInfo(r)
|
|
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
logger.Error(err)
|
|
return
|
|
}
|
|
|
|
existid := r.URL.Query().Get("existid")
|
|
withSDK := r.URL.Query().Get("withSDK")
|
|
|
|
//fmt.Println("existid =>", existid)
|
|
if existid != "" {
|
|
//기존 계정이 있는 경우에는 그 계정 부터 조회한다.
|
|
info, err := mg.getUserTokenWithCheck(AuthPlatformGamepot, existid, browserinfo)
|
|
if err == nil {
|
|
if info.token != "" {
|
|
params := url.Values{}
|
|
params.Add("id", existid)
|
|
params.Add("authtype", AuthPlatformGamepot)
|
|
if withSDK == "1" {
|
|
w.Write([]byte("?" + params.Encode()))
|
|
} else {
|
|
http.Redirect(w, r, "actionsquare://login?"+params.Encode(), http.StatusSeeOther)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
sessionkey := mg.GeneratePlatformLoginNonceKey()
|
|
nonce := mg.GeneratePlatformLoginNonceKey()
|
|
|
|
mg.mongoClient.Delete(CollectionPlatformLoginToken, bson.M{
|
|
"platform": AuthPlatformGamepot,
|
|
"key": sessionkey,
|
|
})
|
|
|
|
_, _, err = mg.mongoClient.Update(CollectionPlatformLoginToken, bson.M{
|
|
"_id": primitive.NewObjectID(),
|
|
}, bson.M{
|
|
"$setOnInsert": bson.M{
|
|
"platform": AuthPlatformGamepot,
|
|
"key": sessionkey,
|
|
"nonce": nonce,
|
|
"brinfo": browserinfo,
|
|
},
|
|
}, options.Update().SetUpsert(true))
|
|
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
logger.Error(err)
|
|
return
|
|
}
|
|
|
|
// set cookie for storing token
|
|
cookie := http.Cookie{
|
|
Name: "LoginFlowContext_SessionKey",
|
|
Value: sessionkey,
|
|
Expires: time.Now().Add(1 * time.Hour),
|
|
//SameSite: http.SameSiteStrictMode,
|
|
SameSite: http.SameSiteLaxMode,
|
|
// HttpOnly: false,
|
|
Secure: true,
|
|
Path: "/",
|
|
}
|
|
http.SetCookie(w, &cookie)
|
|
|
|
if withSDK == "1" {
|
|
params := url.Values{}
|
|
params.Add("nonce", nonce)
|
|
w.Write([]byte("?" + params.Encode()))
|
|
} else {
|
|
var templateVar GamepotTemplate
|
|
templateVar.RedirectBaseUrl = mg.RedirectBaseUrl
|
|
templateVar.State = nonce
|
|
mg.webTemplate[AuthPlatformGamepot].Execute(w, templateVar)
|
|
}
|
|
|
|
}
|
|
|
|
func (mg *Maingate) platform_gamepot_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
|
|
}
|
|
|
|
cookie, err := r.Cookie("LoginFlowContext_SessionKey")
|
|
if err != nil {
|
|
logger.Println("Session not found", err)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
r.ParseForm()
|
|
|
|
code := r.Form.Get("code")
|
|
state := r.Form.Get("state")
|
|
|
|
gamepotmemberId := r.Form.Get("id")
|
|
gamepotnickname := r.Form.Get("nickname")
|
|
gamepotprovider := r.Form.Get("provider")
|
|
gamepotproviderId := r.Form.Get("providerId")
|
|
// gamepotverify := r.Form.Get("verify")
|
|
// gamepotagree := r.Form.Get("agree")
|
|
|
|
bSuccess, Result := mg.platform_gamepot_authorize_raw(w, brinfo, code, state, cookie.Value, gamepotmemberId, gamepotnickname, gamepotprovider, gamepotproviderId)
|
|
|
|
if bSuccess {
|
|
http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
|
} else {
|
|
http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
|
}
|
|
}
|
|
|
|
type GamePotSDKAuthInfo struct {
|
|
Code string `json:"code"`
|
|
State string `json:"state"`
|
|
MemberId string `json:"id"`
|
|
Nickname string `json:"nickname"`
|
|
Provider string `json:"provider"`
|
|
ProviderId string `json:"providerId"`
|
|
// Verify string `json:"verify"`
|
|
// Agree string `json:"agree"`
|
|
}
|
|
|
|
func (mg *Maingate) platform_gamepot_authorize_sdk(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
|
|
}
|
|
|
|
cookie, err := r.Cookie("LoginFlowContext_SessionKey")
|
|
if err != nil {
|
|
logger.Println("Session not found", err)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var authinfo GamePotSDKAuthInfo
|
|
|
|
err = json.NewDecoder(r.Body).Decode(&authinfo)
|
|
if err != nil {
|
|
logger.Println("authinfo decoding fail:", err)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
bSuccess, Result := mg.platform_gamepot_authorize_raw(w, brinfo, authinfo.Code, authinfo.State,
|
|
cookie.Value, authinfo.MemberId, authinfo.Nickname, authinfo.Provider, authinfo.ProviderId)
|
|
|
|
if bSuccess {
|
|
w.Write([]byte("?" + Result))
|
|
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
|
} else {
|
|
http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
|
}
|
|
}
|
|
|
|
func (mg *Maingate) platform_gamepot_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, gamepotmemberId, gamepotnickname, gamepotprovider, gamepotproviderId string) (bool, string) {
|
|
|
|
found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{
|
|
"platform": AuthPlatformGamepot,
|
|
"key": cookieSessionKey,
|
|
})
|
|
|
|
if err != nil {
|
|
logger.Println("LoginFlowContext_SessionKey find key :", err)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
if found == nil {
|
|
logger.Println("LoginFlowContext_SessionKey not found")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
if cookieSessionKey != found["key"] {
|
|
logger.Println("LoginFlowContext_SessionKey key not match")
|
|
logger.Println(cookieSessionKey)
|
|
logger.Println(found["key"])
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
if state != found["nonce"] {
|
|
logger.Println("LoginFlowContext_SessionKey nonce not match")
|
|
logger.Println(state)
|
|
logger.Println(found["nonce"])
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
if brinfo != found["brinfo"] { //-- 로그인 시작점과 인증점의 브라우저 혹은 접속지 정보가 다르다?
|
|
logger.Println("LoginFlowContext_SessionKey brinfo not match ")
|
|
logger.Println(brinfo)
|
|
logger.Println(found["brinfo"])
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
//=================
|
|
params := url.Values{}
|
|
params.Add("projectId", mg.GamepotProjectId)
|
|
params.Add("memberId", gamepotmemberId)
|
|
params.Add("token", code)
|
|
|
|
var respLoginCheck Gamepot_LoginValidationResponse
|
|
content := params.Encode()
|
|
resp, _ := http.Post(mg.GamepotLoginCheckAPIURL, "application/json", bytes.NewBuffer([]byte(content)))
|
|
if resp != nil {
|
|
body, _ := io.ReadAll(resp.Body)
|
|
json.Unmarshal(body, &respLoginCheck)
|
|
} else {
|
|
logger.Println("gamepot logincheck fail.")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
// fmt.Println("==============================")
|
|
// fmt.Println("respLoginCheck.Status:", respLoginCheck.Status)
|
|
// fmt.Println("respLoginCheck.Message:", respLoginCheck.Message)
|
|
// fmt.Println("==============================")
|
|
|
|
if respLoginCheck.Status != 0 {
|
|
logger.Errorf("gamepot login fail:", respLoginCheck.Message)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
|
|
|
|
if gamepotmemberId != "" && gamepotprovider != "" && gamepotproviderId != "" {
|
|
var info usertokeninfo
|
|
info.platform = AuthPlatformGamepot
|
|
info.userid = gamepotmemberId
|
|
//== memberid 제외하고는 모두 client로 부터 온 값이기 때문에 유효성이 확인된 값이 아니다. 하지만, 참조용으로 사용은 한다.
|
|
// 정확한 정보는 gamepotid를 gamepot dashboard에서 조회해서 확인 할 수 밖에 없다.
|
|
info.token = gamepotprovider + "-" + gamepotproviderId
|
|
info.brinfo = brinfo
|
|
info.accesstoken = ""
|
|
info.accesstoken_expire_time = acceestoken_expire_time
|
|
mg.setUserToken(info)
|
|
|
|
mg.mongoClient.Delete(CollectionGamepotUserInfo, bson.M{
|
|
"gamepotuserid": info.userid,
|
|
})
|
|
|
|
_, _, err := mg.mongoClient.Update(CollectionGamepotUserInfo, bson.M{
|
|
"_id": primitive.NewObjectID(),
|
|
}, bson.M{
|
|
"$setOnInsert": bson.M{
|
|
"gamepotuserid": gamepotmemberId,
|
|
"gamepotnickname": gamepotnickname,
|
|
"gamepotprovider": gamepotprovider,
|
|
"gamepotproviderId": gamepotproviderId,
|
|
// "gamepotverify": gamepotverify,
|
|
// "gamepotagree": gamepotagree,
|
|
"updatetime": time.Now(),
|
|
},
|
|
}, options.Update().SetUpsert(true))
|
|
|
|
if err != nil {
|
|
logger.Error(err)
|
|
}
|
|
|
|
params := url.Values{}
|
|
params.Add("id", gamepotmemberId)
|
|
params.Add("authtype", AuthPlatformGamepot)
|
|
return true, params.Encode()
|
|
}
|
|
return false, ""
|
|
}
|
|
|
|
func (mg *Maingate) platform_gamepot_getuserinfo(info usertokeninfo) (bool, string, string) {
|
|
|
|
found, err := mg.mongoClient.FindOne(CollectionGamepotUserInfo, bson.M{
|
|
"gamepotuserid": info.userid,
|
|
})
|
|
|
|
if err != nil {
|
|
logger.Error(err)
|
|
return false, "", ""
|
|
}
|
|
if found == nil {
|
|
logger.Error(errors.New("gamepot info not found: " + info.userid))
|
|
return false, "", ""
|
|
}
|
|
|
|
gamepotprovider := found["gamepotprovider"].(string)
|
|
gamepotproviderId := found["gamepotproviderId"].(string)
|
|
|
|
if gamepotprovider+"-"+gamepotproviderId != info.token {
|
|
logger.Println("gamepot info not match..") //-- token은 플랫폼종류+플랫폼ID로 구성했는데... 검증할 방법이 없어서 client로 부터 온값을 쓴다. 그래도 유저가 조작하지 않는 이상 일치해야 된다.
|
|
logger.Println(info.token)
|
|
logger.Println(gamepotprovider + "-" + gamepotproviderId)
|
|
return false, "", ""
|
|
}
|
|
|
|
tempEmail := info.userid + "@gamepot" //-- 게임팟은 email을 안줘서 일단 gamepotid기준으로 임시값을 할당한다.
|
|
|
|
return true, info.userid, tempEmail
|
|
|
|
}
|