mirror of
https://gitee.com/goploy/goploy.git
synced 2024-12-01 19:57:34 +08:00
optimize cache factory
This commit is contained in:
parent
f086ba5b36
commit
7bc6a27217
@ -16,7 +16,6 @@ import (
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/middleware"
|
||||
"github.com/zhenorzz/goploy/config"
|
||||
"github.com/zhenorzz/goploy/internal/cache"
|
||||
"github.com/zhenorzz/goploy/internal/cache/factory"
|
||||
"github.com/zhenorzz/goploy/internal/media"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/server"
|
||||
@ -68,10 +67,10 @@ func (User) Login(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.IllegalParam, Message: err.Error()}
|
||||
}
|
||||
|
||||
userCache := factory.GetUserCache()
|
||||
userCache := cache.GetUserCache()
|
||||
|
||||
if config.Toml.Captcha.Enabled && userCache.IsShowCaptcha(reqData.Account) {
|
||||
captchaCache := factory.GetCaptchaCache()
|
||||
captchaCache := cache.GetCaptchaCache()
|
||||
if !captchaCache.IsChecked(reqData.CaptchaKey) {
|
||||
return response.JSON{Code: response.Error, Message: "Captcha error, please check captcha again"}
|
||||
}
|
||||
@ -131,10 +130,10 @@ func (User) Login(gp *server.Goploy) server.Response {
|
||||
}
|
||||
} else {
|
||||
if err := userData.Validate(reqData.Password); err != nil {
|
||||
errorTimes := userCache.IncErrorTimes(reqData.Account)
|
||||
errorTimes := userCache.IncErrorTimes(reqData.Account, cache.UserCacheExpireTime, cache.UserCacheShowCaptchaTime)
|
||||
// error times over 5 times, then lock the account 15 minutes
|
||||
if errorTimes >= cache.UserCacheMaxErrorTimes {
|
||||
userCache.LockAccount(reqData.Account)
|
||||
userCache.LockAccount(reqData.Account, cache.UserCacheLockTime)
|
||||
}
|
||||
return response.JSON{Code: response.Deny, Message: err.Error()}
|
||||
}
|
||||
@ -631,7 +630,7 @@ func (User) GetCaptcha(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.AccountDisabled, Message: "generate captcha fail, error msg:" + err.Error()}
|
||||
}
|
||||
|
||||
captchaCache := factory.GetCaptchaCache()
|
||||
captchaCache := cache.GetCaptchaCache()
|
||||
captchaCache.Set(key, dots, 2*time.Minute)
|
||||
|
||||
return response.JSON{
|
||||
@ -659,7 +658,7 @@ func (User) CheckCaptcha(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
captchaCache := factory.GetCaptchaCache()
|
||||
captchaCache := cache.GetCaptchaCache()
|
||||
dotsCache, ok := captchaCache.Get(reqData.Key)
|
||||
if !ok {
|
||||
return response.JSON{Code: response.Error, Message: "Illegal key, please refresh the captcha again"}
|
||||
|
@ -19,7 +19,6 @@ func Init() {
|
||||
startProjectTask()
|
||||
startServerMonitorTask()
|
||||
startDeployTask()
|
||||
startMemoryCacheTask()
|
||||
}
|
||||
|
||||
func Shutdown(ctx context.Context) error {
|
||||
|
@ -50,4 +50,7 @@ appKey = ''
|
||||
appSecret = ''
|
||||
|
||||
[captcha]
|
||||
enabled = false
|
||||
enabled = false
|
||||
|
||||
[cache]
|
||||
type = 'memory'
|
4
internal/cache/captcha.go
vendored
4
internal/cache/captcha.go
vendored
@ -8,7 +8,3 @@ type Captcha interface {
|
||||
Delete(key string)
|
||||
IsChecked(key string) bool
|
||||
}
|
||||
|
||||
type CaptchaData struct {
|
||||
Dots interface{}
|
||||
}
|
||||
|
4
internal/cache/dingtalk.go
vendored
4
internal/cache/dingtalk.go
vendored
@ -6,7 +6,3 @@ type DingtalkAccessToken interface {
|
||||
Get(key string) (string, bool)
|
||||
Set(key string, value string, ttl time.Duration)
|
||||
}
|
||||
|
||||
type AccessTokenData struct {
|
||||
AccessToken string
|
||||
}
|
||||
|
37
internal/cache/factory.go
vendored
Normal file
37
internal/cache/factory.go
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/zhenorzz/goploy/config"
|
||||
"github.com/zhenorzz/goploy/internal/cache/memory"
|
||||
)
|
||||
|
||||
const MemoryCache = "memory"
|
||||
|
||||
var cacheType = config.Toml.Cache.Type
|
||||
|
||||
func GetUserCache() User {
|
||||
switch cacheType {
|
||||
case MemoryCache:
|
||||
return memory.GetUserCache()
|
||||
default:
|
||||
return memory.GetUserCache()
|
||||
}
|
||||
}
|
||||
|
||||
func GetCaptchaCache() Captcha {
|
||||
switch cacheType {
|
||||
case MemoryCache:
|
||||
return memory.GetCaptchaCache()
|
||||
default:
|
||||
return memory.GetCaptchaCache()
|
||||
}
|
||||
}
|
||||
|
||||
func GetDingTalkAccessTokenCache() DingtalkAccessToken {
|
||||
switch cacheType {
|
||||
case MemoryCache:
|
||||
return memory.GetDingTalkAccessTokenCache()
|
||||
default:
|
||||
return memory.GetDingTalkAccessTokenCache()
|
||||
}
|
||||
}
|
34
internal/cache/factory/factory.go
vendored
34
internal/cache/factory/factory.go
vendored
@ -1,34 +0,0 @@
|
||||
package factory
|
||||
|
||||
import (
|
||||
"github.com/zhenorzz/goploy/config"
|
||||
"github.com/zhenorzz/goploy/internal/cache"
|
||||
"github.com/zhenorzz/goploy/internal/cache/memory"
|
||||
)
|
||||
|
||||
func GetUserCache() cache.User {
|
||||
cacheType := config.Toml.Cache.Type
|
||||
if cacheType == "memory" {
|
||||
return memory.GetUserCache()
|
||||
} else {
|
||||
return memory.GetUserCache()
|
||||
}
|
||||
}
|
||||
|
||||
func GetCaptchaCache() cache.Captcha {
|
||||
cacheType := config.Toml.Cache.Type
|
||||
if cacheType == "memory" {
|
||||
return memory.GetCaptchaCache()
|
||||
} else {
|
||||
return memory.GetCaptchaCache()
|
||||
}
|
||||
}
|
||||
|
||||
func GetDingTalkAccessTokenCache() cache.DingtalkAccessToken {
|
||||
cacheType := config.Toml.Cache.Type
|
||||
if cacheType == "memory" {
|
||||
return memory.GetDingTalkAccessTokenCache()
|
||||
} else {
|
||||
return memory.GetDingTalkAccessTokenCache()
|
||||
}
|
||||
}
|
9
internal/cache/memory/captcha.go
vendored
9
internal/cache/memory/captcha.go
vendored
@ -1,7 +1,6 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"github.com/zhenorzz/goploy/internal/cache"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -12,7 +11,7 @@ type CaptchaCache struct {
|
||||
}
|
||||
|
||||
type captcha struct {
|
||||
cache.CaptchaData
|
||||
dots interface{}
|
||||
expireIn time.Time
|
||||
}
|
||||
|
||||
@ -30,7 +29,7 @@ func (c *CaptchaCache) Get(key string) (interface{}, bool) {
|
||||
}
|
||||
|
||||
if !v.expireIn.IsZero() && v.expireIn.After(time.Now()) {
|
||||
return v.Dots, true
|
||||
return v.dots, true
|
||||
}
|
||||
|
||||
return nil, false
|
||||
@ -47,9 +46,7 @@ func (c *CaptchaCache) Set(key string, value interface{}, ttl time.Duration) {
|
||||
}
|
||||
|
||||
c.data[key] = captcha{
|
||||
CaptchaData: cache.CaptchaData{
|
||||
Dots: value,
|
||||
},
|
||||
dots: value,
|
||||
expireIn: expireIn,
|
||||
}
|
||||
|
||||
|
13
internal/cache/memory/dingtalk.go
vendored
13
internal/cache/memory/dingtalk.go
vendored
@ -1,7 +1,6 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"github.com/zhenorzz/goploy/internal/cache"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -12,8 +11,8 @@ type AccessTokenCache struct {
|
||||
}
|
||||
|
||||
type accessToken struct {
|
||||
cache.AccessTokenData
|
||||
expireIn time.Time
|
||||
accessToken string
|
||||
expireIn time.Time
|
||||
}
|
||||
|
||||
var accessTokenCache = &AccessTokenCache{
|
||||
@ -30,7 +29,7 @@ func (ac *AccessTokenCache) Get(key string) (string, bool) {
|
||||
}
|
||||
|
||||
if !v.expireIn.IsZero() && v.expireIn.After(time.Now()) {
|
||||
return v.AccessToken, true
|
||||
return v.accessToken, true
|
||||
}
|
||||
|
||||
return "", false
|
||||
@ -47,10 +46,8 @@ func (ac *AccessTokenCache) Set(key string, value string, ttl time.Duration) {
|
||||
}
|
||||
|
||||
ac.data[key] = accessToken{
|
||||
AccessTokenData: cache.AccessTokenData{
|
||||
AccessToken: value,
|
||||
},
|
||||
expireIn: expireIn,
|
||||
accessToken: value,
|
||||
expireIn: expireIn,
|
||||
}
|
||||
|
||||
time.AfterFunc(ttl, func() {
|
||||
|
55
internal/cache/memory/user.go
vendored
55
internal/cache/memory/user.go
vendored
@ -1,18 +1,23 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"github.com/zhenorzz/goploy/internal/cache"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
UserCacheKey = "login_error_times_"
|
||||
UserCacheLockKey = "login_lock_"
|
||||
UserCacheShowCaptchaKey = "login_show_captcha_"
|
||||
)
|
||||
|
||||
type UserCache struct {
|
||||
data map[string]user
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
type user struct {
|
||||
cache.UserData
|
||||
times int
|
||||
expireIn time.Time
|
||||
}
|
||||
|
||||
@ -20,7 +25,7 @@ var userCache = &UserCache{
|
||||
data: make(map[string]user),
|
||||
}
|
||||
|
||||
func (uc *UserCache) IncErrorTimes(account string) int {
|
||||
func (uc *UserCache) IncErrorTimes(account string, expireTime time.Duration, showCaptchaTime time.Duration) int {
|
||||
uc.Lock()
|
||||
defer uc.Unlock()
|
||||
|
||||
@ -29,52 +34,44 @@ func (uc *UserCache) IncErrorTimes(account string) int {
|
||||
times := 0
|
||||
v, ok := uc.data[cacheKey]
|
||||
if ok && !v.expireIn.IsZero() && v.expireIn.After(time.Now()) {
|
||||
times = v.Times
|
||||
times = v.times
|
||||
}
|
||||
|
||||
times += 1
|
||||
|
||||
uc.data[cacheKey] = user{
|
||||
UserData: cache.UserData{
|
||||
Times: times,
|
||||
},
|
||||
expireIn: time.Now().Add(cache.UserCacheExpireTime),
|
||||
times: times,
|
||||
expireIn: time.Now().Add(expireTime),
|
||||
}
|
||||
time.AfterFunc(expireTime, func() {
|
||||
delete(uc.data, cacheKey)
|
||||
})
|
||||
|
||||
// show captcha
|
||||
showCaptchaKey := getShowCaptchaKey(account)
|
||||
uc.data[showCaptchaKey] = user{
|
||||
UserData: cache.UserData{
|
||||
Times: 1,
|
||||
},
|
||||
expireIn: time.Now().Add(cache.UserCacheShowCaptchaTime),
|
||||
times: 1,
|
||||
expireIn: time.Now().Add(showCaptchaTime),
|
||||
}
|
||||
|
||||
time.AfterFunc(cache.UserCacheShowCaptchaTime, func() {
|
||||
time.AfterFunc(showCaptchaTime, func() {
|
||||
delete(uc.data, showCaptchaKey)
|
||||
})
|
||||
|
||||
time.AfterFunc(cache.UserCacheExpireTime, func() {
|
||||
delete(uc.data, cacheKey)
|
||||
})
|
||||
|
||||
return times
|
||||
}
|
||||
|
||||
func (uc *UserCache) LockAccount(account string) {
|
||||
func (uc *UserCache) LockAccount(account string, lockTime time.Duration) {
|
||||
uc.Lock()
|
||||
defer uc.Unlock()
|
||||
|
||||
lockKey := getLockKey(account)
|
||||
|
||||
uc.data[lockKey] = user{
|
||||
UserData: cache.UserData{
|
||||
Times: 1,
|
||||
},
|
||||
expireIn: time.Now().Add(cache.UserCacheLockTime),
|
||||
times: 1,
|
||||
expireIn: time.Now().Add(lockTime),
|
||||
}
|
||||
|
||||
time.AfterFunc(cache.UserCacheLockTime, func() {
|
||||
time.AfterFunc(lockTime, func() {
|
||||
delete(uc.data, lockKey)
|
||||
})
|
||||
|
||||
@ -93,7 +90,7 @@ func (uc *UserCache) IsLock(account string) bool {
|
||||
lockKey := getLockKey(account)
|
||||
v, ok := uc.data[lockKey]
|
||||
|
||||
return ok && !v.expireIn.IsZero() && v.expireIn.After(time.Now()) && v.Times > 0
|
||||
return ok && !v.expireIn.IsZero() && v.expireIn.After(time.Now()) && v.times > 0
|
||||
}
|
||||
|
||||
func (uc *UserCache) IsShowCaptcha(account string) bool {
|
||||
@ -103,7 +100,7 @@ func (uc *UserCache) IsShowCaptcha(account string) bool {
|
||||
showCaptchaKey := getShowCaptchaKey(account)
|
||||
v, ok := uc.data[showCaptchaKey]
|
||||
|
||||
return ok && !v.expireIn.IsZero() && v.expireIn.After(time.Now()) && v.Times > 0
|
||||
return ok && !v.expireIn.IsZero() && v.expireIn.After(time.Now()) && v.times > 0
|
||||
}
|
||||
|
||||
func (uc *UserCache) DeleteShowCaptcha(account string) {
|
||||
@ -114,15 +111,15 @@ func (uc *UserCache) DeleteShowCaptcha(account string) {
|
||||
}
|
||||
|
||||
func getCacheKey(account string) string {
|
||||
return cache.UserCacheKey + account
|
||||
return UserCacheKey + account
|
||||
}
|
||||
|
||||
func getLockKey(account string) string {
|
||||
return cache.UserCacheLockKey + account
|
||||
return UserCacheLockKey + account
|
||||
}
|
||||
|
||||
func getShowCaptchaKey(account string) string {
|
||||
return cache.UserCacheShowCaptchaKey + account
|
||||
return UserCacheShowCaptchaKey + account
|
||||
}
|
||||
|
||||
func GetUserCache() *UserCache {
|
||||
|
11
internal/cache/user.go
vendored
11
internal/cache/user.go
vendored
@ -3,23 +3,16 @@ package cache
|
||||
import "time"
|
||||
|
||||
type User interface {
|
||||
IncErrorTimes(account string) int
|
||||
LockAccount(account string)
|
||||
IncErrorTimes(account string, expireTime time.Duration, showCaptchaTime time.Duration) int
|
||||
LockAccount(account string, lockTime time.Duration)
|
||||
IsLock(account string) bool
|
||||
IsShowCaptcha(account string) bool
|
||||
DeleteShowCaptcha(account string)
|
||||
}
|
||||
|
||||
const (
|
||||
UserCacheKey = "login_error_times_"
|
||||
UserCacheLockKey = "login_lock_"
|
||||
UserCacheShowCaptchaKey = "login_show_captcha_"
|
||||
UserCacheMaxErrorTimes = 5
|
||||
UserCacheExpireTime = 5 * time.Minute
|
||||
UserCacheLockTime = 15 * time.Minute
|
||||
UserCacheShowCaptchaTime = 15 * time.Minute
|
||||
)
|
||||
|
||||
type UserData struct {
|
||||
Times int
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"github.com/zhenorzz/goploy/config"
|
||||
"github.com/zhenorzz/goploy/internal/cache"
|
||||
"github.com/zhenorzz/goploy/internal/cache/factory"
|
||||
"github.com/zhenorzz/goploy/internal/media/dingtalk/api"
|
||||
"github.com/zhenorzz/goploy/internal/media/dingtalk/api/access_token"
|
||||
"github.com/zhenorzz/goploy/internal/media/dingtalk/api/contact"
|
||||
@ -35,7 +34,7 @@ func (d *Dingtalk) Login(authCode string, _ string) (string, error) {
|
||||
d.Key = config.Toml.Dingtalk.AppKey
|
||||
d.Secret = config.Toml.Dingtalk.AppSecret
|
||||
d.Client = &http.Client{}
|
||||
d.Cache = factory.GetDingTalkAccessTokenCache()
|
||||
d.Cache = cache.GetDingTalkAccessTokenCache()
|
||||
|
||||
userAccessTokenInfo, err := d.GetUserAccessToken(authCode)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user