Merge branch 'master' into kd-live
This commit is contained in:
132
core/service.go
132
core/service.go
@ -7,10 +7,9 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"repositories.action2quare.com/ayo/gocommon"
|
||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||
@ -22,19 +21,45 @@ import (
|
||||
|
||||
type blockinfo struct {
|
||||
Start primitive.DateTime `bson:"start" json:"start"`
|
||||
End primitive.DateTime `bson:"_ts"`
|
||||
End primitive.DateTime `bson:"_ts" json:"_ts"`
|
||||
Reason string `bson:"reason" json:"reason"`
|
||||
Accid primitive.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
|
||||
}
|
||||
|
||||
type blockinfoWithStringId struct {
|
||||
Reason string `bson:"reason" json:"reason"`
|
||||
StrId string `bson:"id" json:"id"`
|
||||
StartUnix int64 `bson:"start_unix" json:"start_unix"`
|
||||
EndUnix int64 `bson:"end_unix" json:"end_unix"`
|
||||
}
|
||||
|
||||
type whitelistmember struct {
|
||||
Email string `bson:"email" json:"email"`
|
||||
Platform string `bson:"platform" json:"platform"`
|
||||
Desc string `bson:"desc" json:"desc"`
|
||||
Expired primitive.DateTime `bson:"_ts,omitempty" json:"_ts,omitempty"`
|
||||
Id primitive.ObjectID `bson:"_id" json:"_id"`
|
||||
Email string `bson:"email" json:"email"`
|
||||
Platform string `bson:"platform" json:"platform"`
|
||||
Desc string `bson:"desc" json:"desc"`
|
||||
ExpiredAt primitive.DateTime `bson:"_ts,omitempty" json:"_ts,omitempty"`
|
||||
}
|
||||
|
||||
type whitelist struct {
|
||||
emailptr unsafe.Pointer
|
||||
func (wh *whitelistmember) Key() string {
|
||||
if strings.HasPrefix(wh.Email, "*@") {
|
||||
// 도메인 전체 허용
|
||||
return wh.Email[2:]
|
||||
}
|
||||
return wh.Email
|
||||
}
|
||||
|
||||
func (wh *whitelistmember) Expired() bool {
|
||||
// 얘는 Expired가 있기만 하면 제거된 상태
|
||||
return wh.ExpiredAt != 0
|
||||
}
|
||||
|
||||
func (bi *blockinfo) Key() primitive.ObjectID {
|
||||
return bi.Accid
|
||||
}
|
||||
|
||||
func (bi *blockinfo) Expired() bool {
|
||||
return bi.End.Time().Unix() < time.Now().UTC().Unix()
|
||||
}
|
||||
|
||||
type usertokeninfo struct {
|
||||
@ -47,54 +72,6 @@ type usertokeninfo struct {
|
||||
accesstoken_expire_time int64 // microsoft only
|
||||
}
|
||||
|
||||
func (wl *whitelist) init(total []whitelistmember) {
|
||||
all := make(map[string]*whitelistmember)
|
||||
for _, member := range total {
|
||||
all[whitelistKey(member.Email, member.Platform)] = &member
|
||||
}
|
||||
atomic.StorePointer(&wl.emailptr, unsafe.Pointer(&all))
|
||||
}
|
||||
|
||||
func addToUnsafePointer(to *unsafe.Pointer, m *whitelistmember) {
|
||||
ptr := atomic.LoadPointer(to)
|
||||
src := (*map[string]*whitelistmember)(ptr)
|
||||
|
||||
next := map[string]*whitelistmember{}
|
||||
for k, v := range *src {
|
||||
next[k] = v
|
||||
}
|
||||
next[whitelistKey(m.Email, m.Platform)] = m
|
||||
atomic.StorePointer(to, unsafe.Pointer(&next))
|
||||
}
|
||||
|
||||
func removeFromUnsafePointer(from *unsafe.Pointer, email string, platform string) {
|
||||
ptr := atomic.LoadPointer(from)
|
||||
src := (*map[string]*whitelistmember)(ptr)
|
||||
|
||||
next := make(map[string]*whitelistmember)
|
||||
for k, v := range *src {
|
||||
next[k] = v
|
||||
}
|
||||
delete(next, whitelistKey(email, platform))
|
||||
atomic.StorePointer(from, unsafe.Pointer(&next))
|
||||
}
|
||||
|
||||
func (wl *whitelist) add(m *whitelistmember) {
|
||||
addToUnsafePointer(&wl.emailptr, m)
|
||||
}
|
||||
|
||||
func (wl *whitelist) remove(email string, platform string) {
|
||||
removeFromUnsafePointer(&wl.emailptr, email, platform)
|
||||
}
|
||||
|
||||
func (wl *whitelist) isMember(email string, platform string) bool {
|
||||
ptr := atomic.LoadPointer(&wl.emailptr)
|
||||
src := *(*map[string]*whitelistmember)(ptr)
|
||||
|
||||
_, exists := src[whitelistKey(email, platform)]
|
||||
return exists
|
||||
}
|
||||
|
||||
type DivisionStateName string
|
||||
|
||||
const (
|
||||
@ -134,7 +111,8 @@ type serviceDescription struct {
|
||||
VersionSplits map[string]string `bson:"version_splits" json:"version_splits"`
|
||||
|
||||
auths *gocommon.AuthCollection
|
||||
wl *whitelist
|
||||
wl memberContainerPtr[string, *whitelistmember]
|
||||
bl memberContainerPtr[primitive.ObjectID, *blockinfo]
|
||||
mongoClient gocommon.MongoClient
|
||||
sessionTTL time.Duration
|
||||
|
||||
@ -280,10 +258,12 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
|
||||
sh.updateUserinfo = mg.updateUserinfo
|
||||
sh.getProviderInfo = mg.getProviderInfo
|
||||
|
||||
sh.wl = &mg.wl
|
||||
sh.wl = mg.wl
|
||||
sh.bl = mg.bl
|
||||
sh.serviceSummarySerialized, _ = json.Marshal(sh.ServiceDescriptionSummary)
|
||||
sh.serviceSerialized, _ = json.Marshal(sh)
|
||||
|
||||
logger.Println("service is ready :", sh.ServiceCode, string(sh.divisionsSerialized))
|
||||
logger.Println("service is ready :", sh.ServiceCode, string(sh.serviceSerialized))
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -721,28 +701,16 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
|
||||
oldcreate := account["create"].(primitive.DateTime)
|
||||
newaccount := oldcreate == createtime
|
||||
|
||||
var bi blockinfo
|
||||
if err := sh.mongoClient.FindOneAs(CollectionBlock, bson.M{
|
||||
"code": sh.ServiceCode,
|
||||
"accid": accid,
|
||||
}, &bi); err != nil {
|
||||
logger.Error("authorize failed. find blockinfo in CollectionBlock err:", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
var bi *blockinfo
|
||||
if sh.bl.contains(accid, &bi) {
|
||||
// 블럭된 계정. 블락 정보를 알려준다.
|
||||
w.Header().Add("MG-ACCOUNTBLOCK-START", strconv.FormatInt(bi.Start.Time().Unix(), 10))
|
||||
w.Header().Add("MG-ACCOUNTBLOCK-END", strconv.FormatInt(bi.End.Time().Unix(), 10))
|
||||
w.Header().Add("MG-ACCOUNTBLOCK-REASON", bi.Reason)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if !bi.Start.Time().IsZero() {
|
||||
now := time.Now().UTC()
|
||||
if bi.Start.Time().Before(now) && bi.End.Time().After(now) {
|
||||
// block됐네?
|
||||
// status는 정상이고 reason을 넘겨주자
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"blocked": bi,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
newsession := primitive.NewObjectID()
|
||||
expired := primitive.NewDateTimeFromTime(time.Now().UTC().Add(sh.sessionTTL))
|
||||
newauth := gocommon.Authinfo{
|
||||
@ -769,6 +737,9 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
|
||||
"newAccount": newaccount,
|
||||
"accid": newauth.Accid.Hex(),
|
||||
}
|
||||
if *noauth {
|
||||
output["noauth"] = true
|
||||
}
|
||||
bt, _ := json.Marshal(output)
|
||||
w.Write(bt)
|
||||
} else if len(session) > 0 {
|
||||
@ -971,7 +942,8 @@ func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if sh.wl.isMember(cell.ToAuthinfo().Email, cell.ToAuthinfo().Platform) {
|
||||
wm := &whitelistmember{Email: cell.ToAuthinfo().Email, Platform: cell.ToAuthinfo().Platform}
|
||||
if sh.wl.contains(wm.Key(), nil) {
|
||||
// qa 권한이면 입장 가능
|
||||
w.Write([]byte(fmt.Sprintf(`{"service":"%s"}`, div.Url)))
|
||||
} else if div.Maintenance != nil {
|
||||
|
||||
Reference in New Issue
Block a user