Files
go-common/app/service/main/passport-game/service/passport_oauth.go
2019-04-22 18:49:16 +08:00

179 lines
4.1 KiB
Go

package service
import (
"context"
"time"
"go-common/app/service/main/passport-game/model"
"go-common/library/ecode"
"go-common/library/log"
)
// Oauth oauth.
func (s *Service) Oauth(c context.Context, app *model.App, accessToken, from string) (token *model.Token, err error) {
if accessToken == "" {
err = ecode.AccessKeyErr
return
}
region, ok := region(accessToken)
if !ok {
err = ecode.AccessKeyErr
return
}
if region == s.currentRegion {
return s.currentOauth(c, accessToken)
}
if region == _origin {
token, err = s.currentOauth(c, accessToken)
} else {
token, err = s.otherOauth(c, accessToken)
}
if err == nil && token != nil && token.Mid > 0 {
return
}
if from != "" {
s.dispatcherErrStats.Incr("dispatcher_error")
err = ErrDispatcherError
return
}
return s.originOauth(c, s.oauth[region], accessToken, s.currentRegion)
}
func (s *Service) originOauth(c context.Context, uri, accessKey, from string) (*model.Token, error) {
cache := true
token, err := s.d.OriginTokenCache(c, accessKey)
if token != nil {
if token.Mid > 0 {
return token, nil
}
return nil, ecode.NoLogin
}
if err != nil {
cache = false
log.Error("Faield to get origin token cache with access key: %s: %+v", accessKey, err)
}
token, err = s.d.Oauth(c, uri, accessKey, from)
if token != nil {
// s.addCache(func() { s.d.SetOriginTokenCache(context.Background(), token) })
return token, nil
}
log.Error("Failed to oauth token by origin: %s, %s, %s: %+v", uri, accessKey, from, err)
if !cache {
return nil, err
}
if ec := ecode.Cause(err); ec.Equal(ecode.AccessKeyErr) || ec.Equal(ecode.NoLogin) {
token = &model.Token{
Mid: -1,
AccessToken: accessKey,
}
s.addCache(func() { s.d.SetOriginTokenCache(context.Background(), token) })
}
return nil, err
}
func (s *Service) currentOauth(c context.Context, accessToken string) (token *model.Token, err error) {
var t *model.Perm
if t, err = s.tokenInfo(c, accessToken); err != nil {
err = nil
}
return s.parseToken(c, t)
}
func (s *Service) otherOauth(c context.Context, accessToken string) (token *model.Token, err error) {
var t *model.Perm
if t, err = s.d.TokenFromOtherRegion(c, accessToken); err != nil {
err = nil
}
return s.parseToken(c, t)
}
func (s *Service) parseToken(c context.Context, t *model.Perm) (token *model.Token, err error) {
if t == nil {
err = ecode.AccessKeyErr
return
}
duration := time.Now().Unix() - t.Expires
if duration > _gameAdditionalExpireSeconds {
err = ecode.AccessKeyErr
return
}
if duration > 0 && duration <= _gameAdditionalExpireSeconds {
err = ecode.AccessTokenExpires
return
}
accInfo := s.Info(c, t.Mid)
token = &model.Token{
Mid: t.Mid,
AppID: t.AppID,
AccessToken: t.AccessToken,
CreateAt: t.CreateAt,
UserID: accInfo.UserID,
Uname: accInfo.Uname,
Expires: t.Expires,
Permission: "ALL",
}
return
}
// thinOauth oauth and return mid.
func (s *Service) thinOauth(c context.Context, app *model.App, accessToken string) (res *model.Info, err error) {
if accessToken == "" {
err = ecode.AccessKeyErr
return
}
region, ok := region(accessToken)
if !ok {
err = ecode.AccessKeyErr
return
}
var mid int64
if region == s.currentRegion {
mid, err = s.thinCurrentOauth(c, app.AppKey, accessToken)
if err != nil {
return
}
res = &model.Info{
Mid: mid,
}
return
}
if region == _origin {
mid, err = s.thinCurrentOauth(c, app.AppKey, accessToken)
if err == nil {
res = &model.Info{
Mid: mid,
}
return
}
}
t, err := s.d.Oauth(c, s.oauth[region], accessToken, s.currentRegion)
if err != nil {
return
}
res = &model.Info{
Mid: t.Mid,
UserID: t.UserID,
Uname: t.Uname,
}
return
}
func (s *Service) thinCurrentOauth(c context.Context, appKey, accessToken string) (res int64, err error) {
var t *model.Perm
if t, err = s.tokenInfo(c, accessToken); err != nil {
err = nil
}
if t == nil {
err = ecode.AccessKeyErr
return
}
duration := time.Now().Unix() - t.Expires
if duration > 0 && duration <= _gameAdditionalExpireSeconds {
err = ecode.AccessTokenExpires
return
}
res = t.Mid
return
}