You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
7.1 KiB
236 lines
7.1 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"encoding/hex" |
|
"encoding/json" |
|
"strings" |
|
"time" |
|
|
|
"go-common/app/job/main/passport-auth/model" |
|
"go-common/library/log" |
|
"go-common/library/queue/databus" |
|
xtime "go-common/library/time" |
|
) |
|
|
|
var ( |
|
local, _ = time.LoadLocation("Local") |
|
) |
|
|
|
type tokenBMsg struct { |
|
Action string |
|
Table string |
|
New *model.OldToken |
|
} |
|
|
|
type cookieBMsg struct { |
|
Action string |
|
Table string |
|
New *model.OldCookie |
|
} |
|
|
|
func (s *Service) consumeproc() { |
|
// fill callbacks |
|
s.g.New = func(msg *databus.Message) (res interface{}, err error) { |
|
bmsg := new(model.BMsg) |
|
if err = json.Unmarshal(msg.Value, &bmsg); err != nil { |
|
log.Error("json.Unmarshal(%s) error(%v)", msg.Value, err) |
|
return |
|
} |
|
log.Info("receive aso msg action(%s) table(%s) key(%s) partition(%d) offset(%d) timestamp(%d) New(%s) Old(%s)", |
|
bmsg.Action, bmsg.Table, msg.Key, msg.Partition, msg.Offset, msg.Timestamp, string(bmsg.New), string(bmsg.Old)) |
|
if strings.HasPrefix(bmsg.Table, "aso_app_perm") { |
|
tokenBMsg := &tokenBMsg{ |
|
Action: bmsg.Action, |
|
Table: bmsg.Table, |
|
} |
|
newToken := new(model.OldToken) |
|
if err = json.Unmarshal(bmsg.New, &newToken); err != nil { |
|
log.Error("json.Unmarshal(%s) error(%v)", bmsg.New, err) |
|
return |
|
} |
|
tokenBMsg.New = newToken |
|
return tokenBMsg, nil |
|
} else if strings.HasPrefix(bmsg.Table, "aso_cookie_token") { |
|
cookieBMsg := &cookieBMsg{ |
|
Action: bmsg.Action, |
|
Table: bmsg.Table, |
|
} |
|
newCookie := new(model.OldCookie) |
|
if err = json.Unmarshal(bmsg.New, newCookie); err != nil { |
|
log.Error("json.Unmarshal(%s) error(%v)", bmsg.New, err) |
|
return |
|
} |
|
cookieBMsg.New = newCookie |
|
return cookieBMsg, nil |
|
} |
|
return |
|
} |
|
s.g.Split = func(msg *databus.Message, data interface{}) int { |
|
if t, ok := data.(*tokenBMsg); ok { |
|
return int(t.New.Mid) |
|
} else if t, ok := data.(*cookieBMsg); ok { |
|
return int(t.New.Mid) |
|
} |
|
return 0 |
|
} |
|
s.g.Do = func(msgs []interface{}) { |
|
for _, m := range msgs { |
|
if msg, ok := m.(*tokenBMsg); ok { |
|
for { |
|
if err := s.handleToken(msg); err != nil { |
|
log.Error("do handleToken error", err) |
|
time.Sleep(100 * time.Millisecond) |
|
continue |
|
} |
|
break |
|
} |
|
} else if msg, ok := m.(*cookieBMsg); ok { |
|
for { |
|
if err := s.handleCookie(msg); err != nil { |
|
log.Error("do handleCookie error", err) |
|
time.Sleep(100 * time.Millisecond) |
|
continue |
|
} |
|
break |
|
} |
|
} |
|
} |
|
} |
|
// start the group |
|
s.g.Start() |
|
} |
|
|
|
func (s *Service) handleCookie(cookie *cookieBMsg) (err error) { |
|
newCookie := &model.Cookie{ |
|
Mid: cookie.New.Mid, |
|
Session: cookie.New.Session, |
|
CSRF: cookie.New.CSRFToken, |
|
Expires: cookie.New.Expires, |
|
} |
|
csrfByte, _ := hex.DecodeString(cookie.New.CSRFToken) |
|
if strings.ToLower(cookie.Action) == "insert" { |
|
if _, err = s.dao.AddCookie(context.Background(), newCookie, []byte(newCookie.Session), csrfByte, time.Now()); err != nil { |
|
return |
|
} |
|
return |
|
} else if strings.ToLower(cookie.Action) == "delete" { |
|
now := time.Now() |
|
if _, err = s.dao.DelCookie(context.Background(), []byte(cookie.New.Session), now); err != nil { |
|
log.Error("del db cookie(%s) error(%+v)", cookie.New.Session, err) |
|
return |
|
} |
|
if _, err = s.dao.DelCookie(context.Background(), []byte(cookie.New.Session), previousMonth(now, -1)); err != nil { |
|
log.Error("del db cookie(%s) error(%+v)", cookie.New.Session, err) |
|
return |
|
} |
|
if newCookie.Expires > now.Unix() { |
|
var t time.Time |
|
if cookie.New.ModifyTime == "0000-00-00 00:00:00" { |
|
t = time.Now() |
|
} else { |
|
t, err = time.ParseInLocation("2006-01-02 15:04:05", cookie.New.ModifyTime, local) |
|
if err != nil { |
|
log.Error("handleCookie error: ctime parse error(%+v) cookie(%+v)", err, cookie.New) |
|
return |
|
} |
|
} |
|
timestamp := xtime.Time(t.Unix()) |
|
newCookie.Ctime = timestamp |
|
if _, err = s.dao.AddCookieDeleted(context.Background(), newCookie, []byte(newCookie.Session), csrfByte, t); err != nil { |
|
return |
|
} |
|
} |
|
if err = s.authRPC.DelCookieCookie(context.Background(), cookie.New.Session); err != nil { |
|
log.Error("del cache cookie(%s) error(%+v)", cookie.New.Session, err) |
|
} |
|
if err = s.dao.AsoCleanCache(context.Background(), "", cookie.New.Session, cookie.New.Mid); err != nil { |
|
return |
|
} |
|
} |
|
return |
|
} |
|
|
|
func (s *Service) handleToken(token *tokenBMsg) (err error) { |
|
var t time.Time |
|
t, err = time.ParseInLocation("2006-01-02 15:04:05", token.New.CTime, local) |
|
if err != nil { |
|
log.Error("handleToken error: ctime parse err. (%+v)", token.New) |
|
return |
|
} |
|
timestamp := xtime.Time(t.Unix()) |
|
newToken := &model.Token{ |
|
Mid: token.New.Mid, |
|
Token: token.New.AccessToken, |
|
AppID: token.New.AppID, |
|
Expires: token.New.Expires, |
|
Type: token.New.Type, |
|
Ctime: timestamp, |
|
} |
|
tokenByte, _ := hex.DecodeString(newToken.Token) |
|
if strings.ToLower(token.Action) == "insert" { |
|
if _, err = s.dao.AddToken(context.Background(), newToken, tokenByte, t); err != nil { |
|
return |
|
} |
|
if token.New.RefreshToken == "" { |
|
return |
|
} |
|
newRefresh := &model.Refresh{ |
|
Mid: token.New.Mid, |
|
Refresh: token.New.RefreshToken, |
|
Token: token.New.AccessToken, |
|
AppID: token.New.AppID, |
|
Expires: token.New.Expires, // 需要考虑+30天 |
|
} |
|
tokenByteRefresh, _ := hex.DecodeString(newRefresh.Token) |
|
refreshByte, _ := hex.DecodeString(newRefresh.Refresh) |
|
if _, err = s.dao.AddRefresh(context.Background(), newRefresh, refreshByte, tokenByteRefresh, t); err != nil { |
|
return |
|
} |
|
} else if strings.ToLower(token.Action) == "delete" { |
|
now := time.Now() |
|
if _, err = s.dao.DelToken(context.Background(), tokenByte, now); err != nil { |
|
log.Error("del db token(%s) error(%+v)", token.New.AccessToken, err) |
|
return |
|
} |
|
if _, err = s.dao.DelToken(context.Background(), tokenByte, previousMonth(now, -1)); err != nil { |
|
log.Error("del db token(%s) error(%+v)", token.New.AccessToken, err) |
|
return |
|
} |
|
if _, err = s.dao.DelToken(context.Background(), tokenByte, previousMonth(now, -2)); err != nil { |
|
log.Error("del db token(%s) error(%+v)", token.New.AccessToken, err) |
|
return |
|
} |
|
if _, err = s.dao.AddTokenDeleted(context.Background(), newToken, tokenByte, t); err != nil { |
|
return |
|
} |
|
if err = s.authRPC.DelTokenCache(context.Background(), token.New.AccessToken); err != nil { |
|
log.Error("del cache token(%s) error(%+v)", token.New.AccessToken, err) |
|
} |
|
if err = s.dao.AsoCleanCache(context.Background(), token.New.AccessToken, "", token.New.Mid); err != nil { |
|
return |
|
} |
|
if token.New.RefreshToken == "" { |
|
return |
|
} |
|
refreshByte, _ := hex.DecodeString(token.New.RefreshToken) |
|
if _, err = s.dao.DelRefresh(context.Background(), refreshByte, t); err != nil { |
|
log.Error("del db refresh(%s) error(%+v)", token.New.RefreshToken, err) |
|
return |
|
} |
|
if _, err = s.dao.DelRefresh(context.Background(), refreshByte, previousMonth(t, -2)); err != nil { |
|
log.Error("del db refresh(%s) error(%+v)", token.New.RefreshToken, err) |
|
return |
|
} |
|
} |
|
return |
|
} |
|
|
|
func previousMonth(t time.Time, delta int) time.Time { |
|
if delta == 0 { |
|
return t |
|
} |
|
year, month, _ := t.Date() |
|
thisMonthFirstDay := time.Date(year, month, 1, 1, 1, 1, 1, t.Location()) |
|
return thisMonthFirstDay.AddDate(0, delta, 0) |
|
}
|
|
|