diff --git a/docker-compose.yaml b/docker-compose.yaml index f1cc173d73..f9ae2752ce 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,8 +15,8 @@ services: - "5432:5432" redis: - # redis:6.0 crashed randomly when I run k6 load test. - image: redis:6.2.6 + # Azure cache for Redis supports 6.0 only + image: redis:6.0.20 volumes: - redis_data:/data ports: diff --git a/pkg/auth/webapp/error_service.go b/pkg/auth/webapp/error_service.go index 6bc31c720b..40661ede95 100644 --- a/pkg/auth/webapp/error_service.go +++ b/pkg/auth/webapp/error_service.go @@ -7,10 +7,9 @@ import ( "net/http" "net/url" - goredis "github.com/go-redis/redis/v8" - "github.com/authgear/authgear-server/pkg/api/apierrors" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/crypto" "github.com/authgear/authgear-server/pkg/util/duration" @@ -76,7 +75,7 @@ func (c *ErrorService) GetRecoverableError(r *http.Request) (*ErrorState, bool) var redisValue string var err error - err = c.RedisHandle.WithConnContext(r.Context(), func(conn *goredis.Conn) error { + err = c.RedisHandle.WithConnContext(r.Context(), func(conn redis.Redis_6_0_Cmdable) error { redisValue, err = conn.Get(r.Context(), redisKey).Result() return err }) @@ -109,9 +108,18 @@ func (c *ErrorService) GetDelRecoverableError(w http.ResponseWriter, r *http.Req var redisValue string var err error - err = c.RedisHandle.WithConnContext(r.Context(), func(conn *goredis.Conn) error { - redisValue, err = conn.GetDel(r.Context(), redisKey).Result() - return err + err = c.RedisHandle.WithConnContext(r.Context(), func(conn redis.Redis_6_0_Cmdable) error { + redisValue, err = conn.Get(r.Context(), redisKey).Result() + if err != nil { + return err + } + + _, err = conn.Del(r.Context(), redisKey).Result() + if err != nil { + return err + } + + return nil }) if err != nil { return nil, false @@ -165,7 +173,7 @@ func (c *ErrorService) SetRecoverableError(r *http.Request, value *apierrors.API } redisValue := string(dataBytes) - err = c.RedisHandle.WithConnContext(r.Context(), func(conn *goredis.Conn) error { + err = c.RedisHandle.WithConnContext(r.Context(), func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Set(r.Context(), redisKey, redisValue, duration.WebError).Result() return err }) diff --git a/pkg/auth/webapp/session_store.go b/pkg/auth/webapp/session_store.go index 1a388dd35b..b9fee9c7e2 100644 --- a/pkg/auth/webapp/session_store.go +++ b/pkg/auth/webapp/session_store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/lib/interaction" ) @@ -28,7 +29,7 @@ func (s *SessionStoreRedis) Create(session *Session) (err error) { return } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ttl := SessionExpiryDuration _, err = conn.SetNX(ctx, key, bytes, ttl).Result() if errors.Is(err, goredis.Nil) { @@ -50,7 +51,7 @@ func (s *SessionStoreRedis) Update(session *Session) (err error) { return } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ttl := SessionExpiryDuration _, err = conn.SetXX(ctx, key, bytes, ttl).Result() if errors.Is(err, goredis.Nil) { @@ -67,7 +68,7 @@ func (s *SessionStoreRedis) Update(session *Session) (err error) { func (s *SessionStoreRedis) Get(id string) (session *Session, err error) { ctx := context.Background() key := sessionKey(string(s.AppID), id) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { err = ErrInvalidSession @@ -90,7 +91,7 @@ func (s *SessionStoreRedis) Get(id string) (session *Session, err error) { func (s *SessionStoreRedis) Delete(id string) error { ctx := context.Background() key := sessionKey(string(s.AppID), id) - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(ctx, key).Result() return err }) diff --git a/pkg/lib/accountmanagement/redis_store.go b/pkg/lib/accountmanagement/redis_store.go index 0cd7ef4a72..3b2335d3ca 100644 --- a/pkg/lib/accountmanagement/redis_store.go +++ b/pkg/lib/accountmanagement/redis_store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" "github.com/authgear/authgear-server/pkg/util/duration" @@ -54,7 +55,7 @@ func (s *RedisStore) GenerateToken(options GenerateTokenOptions) (string, error) tokenKey := tokenKey(token.AppID, token.TokenHash) - err = s.Redis.WithConnContext(s.Context, func(conn *goredis.Conn) error { + err = s.Redis.WithConnContext(s.Context, func(conn redis.Redis_6_0_Cmdable) error { _, err = conn.SetNX(s.Context, tokenKey, tokenBytes, ttl).Result() if errors.Is(err, goredis.Nil) { return errors.New("account management token collision") @@ -76,15 +77,21 @@ func (s *RedisStore) ConsumeToken(tokenStr string) (*Token, error) { tokenKey := tokenKey(string(s.AppID), tokenHash) var tokenBytes []byte - err := s.Redis.WithConnContext(s.Context, func(conn *goredis.Conn) error { + err := s.Redis.WithConnContext(s.Context, func(conn redis.Redis_6_0_Cmdable) error { var err error - tokenBytes, err = conn.GetDel(s.Context, tokenKey).Bytes() + tokenBytes, err = conn.Get(s.Context, tokenKey).Bytes() if errors.Is(err, goredis.Nil) { // Token Invalid return ErrOAuthTokenInvalid } else if err != nil { return err } + + _, err = conn.Del(s.Context, tokenKey).Result() + if err != nil { + return err + } + return nil }) if err != nil { diff --git a/pkg/lib/authenticationflow/store.go b/pkg/lib/authenticationflow/store.go index 873396788e..1c3640ee87 100644 --- a/pkg/lib/authenticationflow/store.go +++ b/pkg/lib/authenticationflow/store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -27,7 +28,7 @@ func (s *StoreImpl) CreateFlow(flow *Flow) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { flowKey := redisFlowKey(s.AppID, flow.FlowID) stateKey := redisFlowStateKey(s.AppID, flow.StateToken) ttl := Lifetime @@ -49,7 +50,7 @@ func (s *StoreImpl) CreateFlow(flow *Flow) error { func (s *StoreImpl) GetFlowByStateToken(stateToken string) (*Flow, error) { stateKey := redisFlowStateKey(s.AppID, stateToken) var flow Flow - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := conn.Get(s.Context, stateKey).Bytes() if errors.Is(err, goredis.Nil) { return ErrFlowNotFound @@ -80,7 +81,7 @@ func (s *StoreImpl) GetFlowByStateToken(stateToken string) (*Flow, error) { func (s *StoreImpl) DeleteFlow(flow *Flow) error { // We do not delete the states because there are many of them. // Deleting the flowID is enough to make GetFlowByStateToken to return ErrFlowNotFound. - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { flowKey := redisFlowKey(s.AppID, flow.FlowID) _, err := conn.Del(s.Context, flowKey).Result() @@ -98,7 +99,7 @@ func (s *StoreImpl) CreateSession(session *Session) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { sessionKey := redisFlowSessionKey(s.AppID, session.FlowID) ttl := Lifetime @@ -114,7 +115,7 @@ func (s *StoreImpl) CreateSession(session *Session) error { func (s *StoreImpl) GetSession(flowID string) (*Session, error) { sessionKey := redisFlowSessionKey(s.AppID, flowID) var session Session - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := conn.Get(s.Context, sessionKey).Bytes() if errors.Is(err, goredis.Nil) { return ErrFlowNotFound @@ -139,7 +140,7 @@ func (s *StoreImpl) UpdateSession(session *Session) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { sessionKey := redisFlowSessionKey(s.AppID, session.FlowID) ttl := Lifetime @@ -153,7 +154,7 @@ func (s *StoreImpl) UpdateSession(session *Session) error { } func (s *StoreImpl) DeleteSession(session *Session) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { sessionKey := redisFlowSessionKey(s.AppID, session.FlowID) _, err := conn.Del(s.Context, sessionKey).Result() diff --git a/pkg/lib/authn/authenticationinfo/store_redis.go b/pkg/lib/authn/authenticationinfo/store_redis.go index 518003ae90..b83eebbdc8 100644 --- a/pkg/lib/authn/authenticationinfo/store_redis.go +++ b/pkg/lib/authn/authenticationinfo/store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -29,7 +30,7 @@ func (s *StoreRedis) Save(entry *Entry) (err error) { key := authenticationInfoEntryKey(s.AppID, entry.ID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Set(s.Context, key, jsonBytes, ttl).Result() return err }) @@ -42,7 +43,7 @@ func (s *StoreRedis) Save(entry *Entry) (err error) { func (s *StoreRedis) Get(entryID string) (entry *Entry, err error) { key := authenticationInfoEntryKey(s.AppID, entryID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrNotFound @@ -62,7 +63,7 @@ func (s *StoreRedis) Get(entryID string) (entry *Entry, err error) { func (s *StoreRedis) Delete(entryID string) (err error) { key := authenticationInfoEntryKey(s.AppID, entryID) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(s.Context, key).Result() if err != nil { return err diff --git a/pkg/lib/authn/challenge/provider.go b/pkg/lib/authn/challenge/provider.go index c97f3bc0da..17bae15620 100644 --- a/pkg/lib/authn/challenge/provider.go +++ b/pkg/lib/authn/challenge/provider.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -36,7 +37,7 @@ func (p *Provider) Create(purpose Purpose) (*Challenge, error) { return nil, err } - err = p.Redis.WithConn(func(conn *goredis.Conn) error { + err = p.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err = conn.SetNX(ctx, key, data, ttl).Result() if errors.Is(err, goredis.Nil) { return errors.New("fail to create new challenge") @@ -59,7 +60,7 @@ func (p *Provider) Get(token string) (*Challenge, error) { c := &Challenge{} - err := p.Redis.WithConn(func(conn *goredis.Conn) error { + err := p.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrInvalidChallenge @@ -87,7 +88,7 @@ func (p *Provider) Consume(token string) (*Purpose, error) { c := &Challenge{} - err := p.Redis.WithConn(func(conn *goredis.Conn) error { + err := p.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrInvalidChallenge diff --git a/pkg/lib/authn/identity/anonymous/store_redis.go b/pkg/lib/authn/identity/anonymous/store_redis.go index e8d24e0d2a..f6dec850a5 100644 --- a/pkg/lib/authn/identity/anonymous/store_redis.go +++ b/pkg/lib/authn/identity/anonymous/store_redis.go @@ -10,6 +10,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -25,7 +26,7 @@ type StoreRedis struct { func (s *StoreRedis) GetPromotionCode(codeHash string) (*PromotionCode, error) { c := &PromotionCode{} - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := s.get(conn, promotionCodeKey(string(s.AppID), codeHash)) if err != nil { return err @@ -43,18 +44,18 @@ func (s *StoreRedis) GetPromotionCode(codeHash string) (*PromotionCode, error) { } func (s *StoreRedis) CreatePromotionCode(code *PromotionCode) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.save(conn, promotionCodeKey(code.AppID, code.CodeHash), code, code.ExpireAt) }) } func (s *StoreRedis) DeletePromotionCode(code *PromotionCode) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.del(conn, promotionCodeKey(code.AppID, code.CodeHash)) }) } -func (s *StoreRedis) get(conn *goredis.Conn, key string) ([]byte, error) { +func (s *StoreRedis) get(conn redis.Redis_6_0_Cmdable, key string) ([]byte, error) { ctx := context.Background() data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { @@ -65,7 +66,7 @@ func (s *StoreRedis) get(conn *goredis.Conn, key string) ([]byte, error) { return data, nil } -func (s *StoreRedis) save(conn *goredis.Conn, key string, value interface{}, expireAt time.Time) error { +func (s *StoreRedis) save(conn redis.Redis_6_0_Cmdable, key string, value interface{}, expireAt time.Time) error { ctx := context.Background() data, err := json.Marshal(value) if err != nil { @@ -82,7 +83,7 @@ func (s *StoreRedis) save(conn *goredis.Conn, key string, value interface{}, exp return nil } -func (s *StoreRedis) del(conn *goredis.Conn, key string) error { +func (s *StoreRedis) del(conn redis.Redis_6_0_Cmdable, key string) error { ctx := context.Background() _, err := conn.Del(ctx, key).Result() return err diff --git a/pkg/lib/authn/mfa/store_device_token_redis.go b/pkg/lib/authn/mfa/store_device_token_redis.go index e5246e1aaf..9bba0bd67e 100644 --- a/pkg/lib/authn/mfa/store_device_token_redis.go +++ b/pkg/lib/authn/mfa/store_device_token_redis.go @@ -10,6 +10,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -22,7 +23,7 @@ type StoreDeviceTokenRedis struct { func (s *StoreDeviceTokenRedis) Get(userID string, token string) (*DeviceToken, error) { var deviceToken *DeviceToken - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() key := redisDeviceTokensKey(s.AppID, userID) @@ -63,7 +64,7 @@ func (s *StoreDeviceTokenRedis) Get(userID string, token string) (*DeviceToken, } func (s *StoreDeviceTokenRedis) Create(token *DeviceToken) error { - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() key := redisDeviceTokensKey(s.AppID, token.UserID) @@ -96,7 +97,7 @@ func (s *StoreDeviceTokenRedis) Create(token *DeviceToken) error { } func (s *StoreDeviceTokenRedis) DeleteAll(userID string) error { - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := redisDeviceTokensKey(s.AppID, userID) ctx := context.Background() _, err := conn.Del(ctx, key).Result() @@ -109,7 +110,7 @@ func (s *StoreDeviceTokenRedis) DeleteAll(userID string) error { func (s *StoreDeviceTokenRedis) HasTokens(userID string) (bool, error) { hasTokens := false - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() key := redisDeviceTokensKey(s.AppID, userID) _, err := conn.Get(ctx, key).Bytes() @@ -127,7 +128,7 @@ func (s *StoreDeviceTokenRedis) HasTokens(userID string) (bool, error) { return hasTokens, err } -func (s *StoreDeviceTokenRedis) saveTokens(conn *goredis.Conn, key string, tokens map[string]*DeviceToken, ttl time.Duration) error { +func (s *StoreDeviceTokenRedis) saveTokens(conn redis.Redis_6_0_Cmdable, key string, tokens map[string]*DeviceToken, ttl time.Duration) error { ctx := context.Background() if len(tokens) > 0 { diff --git a/pkg/lib/authn/otp/attempt_tracker_redis.go b/pkg/lib/authn/otp/attempt_tracker_redis.go index a4c59c697b..4234bcf14a 100644 --- a/pkg/lib/authn/otp/attempt_tracker_redis.go +++ b/pkg/lib/authn/otp/attempt_tracker_redis.go @@ -8,6 +8,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -22,7 +23,7 @@ func (s *AttemptTrackerRedis) ResetFailedAttempts(kind Kind, target string) erro ctx := context.Background() purpose := kind.Purpose() - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(ctx, redisFailedAttemptsKey(s.AppID, purpose, target)).Result() return err }) @@ -33,7 +34,7 @@ func (s *AttemptTrackerRedis) GetFailedAttempts(kind Kind, target string) (int, purpose := kind.Purpose() var failedAttempts int - err := s.Redis.WithConn(func(conn *goredis.Conn) (err error) { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) (err error) { failedAttempts, err = conn.Get(ctx, redisFailedAttemptsKey(s.AppID, purpose, target)).Int() if errors.Is(err, goredis.Nil) { failedAttempts = 0 @@ -58,7 +59,7 @@ func (s *AttemptTrackerRedis) IncrementFailedAttempts(kind Kind, target string) expiration := kind.ValidPeriod() var failedAttempts int64 - err := s.Redis.WithConn(func(conn *goredis.Conn) (err error) { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) (err error) { failedAttempts, err = conn.Incr(ctx, key).Result() if err != nil { return err diff --git a/pkg/lib/authn/otp/code_store_redis.go b/pkg/lib/authn/otp/code_store_redis.go index 10ae1c1dae..1e0f9f0dd3 100644 --- a/pkg/lib/authn/otp/code_store_redis.go +++ b/pkg/lib/authn/otp/code_store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -26,7 +27,7 @@ func (s *CodeStoreRedis) set(purpose Purpose, code *Code) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { codeKey := redisCodeKey(s.AppID, purpose, code.Target) ttl := code.ExpireAt.Sub(s.Clock.NowUTC()) @@ -49,7 +50,7 @@ func (s *CodeStoreRedis) Get(purpose Purpose, target string) (*Code, error) { ctx := context.Background() key := redisCodeKey(s.AppID, purpose, target) var codeModel *Code - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrCodeNotFound @@ -73,7 +74,7 @@ func (s *CodeStoreRedis) Update(purpose Purpose, code *Code) error { func (s *CodeStoreRedis) Delete(purpose Purpose, target string) error { ctx := context.Background() - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := redisCodeKey(s.AppID, purpose, target) _, err := conn.Del(ctx, key).Result() if err != nil { diff --git a/pkg/lib/authn/otp/lookup_store_redis.go b/pkg/lib/authn/otp/lookup_store_redis.go index e0cf2e6c0a..26ec21d060 100644 --- a/pkg/lib/authn/otp/lookup_store_redis.go +++ b/pkg/lib/authn/otp/lookup_store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -23,7 +24,7 @@ func (s *LookupStoreRedis) Create(purpose Purpose, code string, target string, e ctx := context.Background() key := redisLookupKey(s.AppID, purpose, code) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ttl := expireAt.Sub(s.Clock.NowUTC()) _, err := conn.SetNX(ctx, key, target, ttl).Result() @@ -41,7 +42,7 @@ func (s *LookupStoreRedis) Get(purpose Purpose, code string) (target string, err ctx := context.Background() key := redisLookupKey(s.AppID, purpose, code) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { target, err = conn.Get(ctx, key).Result() if errors.Is(err, goredis.Nil) { return ErrCodeNotFound @@ -58,7 +59,7 @@ func (s *LookupStoreRedis) Delete(purpose Purpose, code string) error { ctx := context.Background() key := redisLookupKey(s.AppID, purpose, code) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(ctx, key).Result() if err != nil { return err diff --git a/pkg/lib/authn/sso/simple_store.go b/pkg/lib/authn/sso/simple_store.go index 66e859226c..9ec98ce97d 100644 --- a/pkg/lib/authn/sso/simple_store.go +++ b/pkg/lib/authn/sso/simple_store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" ) @@ -42,14 +43,19 @@ type SimpleStoreRedis struct { func (s *SimpleStoreRedis) GetDel(key string) (data string, err error) { storeKey := storageKey(s.appID, s.providerType, s.providerAlias, key) - err = s.redis.WithConnContext(s.context, func(conn *goredis.Conn) error { - data, err = conn.GetDel(s.context, storeKey).Result() + err = s.redis.WithConnContext(s.context, func(conn redis.Redis_6_0_Cmdable) error { + data, err = conn.Get(s.context, storeKey).Result() if err != nil { if errors.Is(err, goredis.Nil) { return nil } return err } + _, err = conn.Del(s.context, storeKey).Result() + if err != nil { + return err + } + return nil }) return @@ -57,7 +63,7 @@ func (s *SimpleStoreRedis) GetDel(key string) (data string, err error) { func (s *SimpleStoreRedis) SetWithTTL(key string, value string, ttl time.Duration) error { storeKey := storageKey(s.appID, s.providerType, s.providerAlias, key) - err := s.redis.WithConnContext(s.context, func(conn *goredis.Conn) error { + err := s.redis.WithConnContext(s.context, func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.SetEX(s.context, storeKey, []byte(value), ttl).Result() if err != nil { return err diff --git a/pkg/lib/feature/passkey/store.go b/pkg/lib/feature/passkey/store.go index fe46024731..e5aaf97f9f 100644 --- a/pkg/lib/feature/passkey/store.go +++ b/pkg/lib/feature/passkey/store.go @@ -11,6 +11,7 @@ import ( "github.com/go-webauthn/webauthn/protocol" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -28,7 +29,7 @@ func (s *Store) CreateSession(session *Session) error { return err } key := redisSessionKey(s.AppID, encodedChallenge) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ttl := duration.PerHour _, err = conn.SetNX(s.Context, key, bytes, ttl).Result() if err != nil { @@ -43,19 +44,17 @@ func (s *Store) ConsumeSession(challenge protocol.URLEncodedBase64) (*Session, e key := redisSessionKey(s.AppID, encodedChallenge) var bytes []byte - err := s.Redis.WithConn(func(conn *goredis.Conn) error { - pipeliner := conn.Pipeline() - getResult := pipeliner.Get(s.Context, key) - delResult := pipeliner.Del(s.Context, key) - _, err := pipeliner.Exec(s.Context) - if err != nil { - return err + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { + var err error + bytes, err = conn.Get(s.Context, key).Bytes() + if errors.Is(err, goredis.Nil) { + return ErrSessionNotFound } - bytes, err = getResult.Bytes() if err != nil { return err } - err = delResult.Err() + + _, err = conn.Del(s.Context, key).Result() if err != nil { return err } @@ -80,7 +79,7 @@ func (s *Store) PeekSession(challenge protocol.URLEncodedBase64) (*Session, erro key := redisSessionKey(s.AppID, encodedChallenge) var bytes []byte - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { var err error bytes, err = conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { diff --git a/pkg/lib/feature/siwe/store_redis.go b/pkg/lib/feature/siwe/store_redis.go index 0fc4e363e0..d3e537fcb7 100644 --- a/pkg/lib/feature/siwe/store_redis.go +++ b/pkg/lib/feature/siwe/store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -26,7 +27,7 @@ func (s *StoreRedis) Create(nonce *Nonce) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { nonceKey := redisNonceKey(s.AppID, nonce) ttl := nonce.ExpireAt.Sub(s.Clock.NowUTC()) _, err := conn.SetNX(s.Context, nonceKey, data, ttl).Result() @@ -44,7 +45,7 @@ func (s *StoreRedis) Get(nonce *Nonce) (*Nonce, error) { ctx := context.Background() key := redisNonceKey(s.AppID, nonce) var nonceModel *Nonce - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrNonceNotFound @@ -68,7 +69,7 @@ func (s *StoreRedis) Get(nonce *Nonce) (*Nonce, error) { func (s *StoreRedis) Delete(codeKey *Nonce) error { ctx := context.Background() - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := redisNonceKey(s.AppID, codeKey) _, err := conn.Del(ctx, key).Result() if err != nil { diff --git a/pkg/lib/infra/redis/handle.go b/pkg/lib/infra/redis/handle.go index ff10d08baf..fa6f0e36be 100644 --- a/pkg/lib/infra/redis/handle.go +++ b/pkg/lib/infra/redis/handle.go @@ -25,12 +25,12 @@ func NewHandle(pool *Pool, connectionOptions ConnectionOptions, logger *log.Logg } } -func (h *Handle) WithConn(f func(conn *goredis.Conn) error) error { +func (h *Handle) WithConn(f func(conn Redis_6_0_Cmdable) error) error { ctx := context.Background() return h.WithConnContext(ctx, f) } -func (h *Handle) WithConnContext(ctx context.Context, f func(conn *goredis.Conn) error) error { +func (h *Handle) WithConnContext(ctx context.Context, f func(conn Redis_6_0_Cmdable) error) error { h.logger.WithFields(map[string]interface{}{ "max_open_connection": *h.ConnectionOptions.MaxOpenConnection, "max_idle_connection": *h.ConnectionOptions.MaxIdleConnection, diff --git a/pkg/lib/infra/redis/redis_6_0.go b/pkg/lib/infra/redis/redis_6_0.go new file mode 100644 index 0000000000..42e5e33945 --- /dev/null +++ b/pkg/lib/infra/redis/redis_6_0.go @@ -0,0 +1,46 @@ +package redis + +import ( + "context" + "time" + + goredis "github.com/go-redis/redis/v8" +) + +type Redis_6_0_Cmdable interface { + Del(ctx context.Context, keys ...string) *goredis.IntCmd + + Get(ctx context.Context, key string) *goredis.StringCmd + + Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *goredis.StatusCmd + SetEX(ctx context.Context, key string, value interface{}, expiration time.Duration) *goredis.StatusCmd + SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *goredis.BoolCmd + SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *goredis.BoolCmd + + Expire(ctx context.Context, key string, expiration time.Duration) *goredis.BoolCmd + ExpireAt(ctx context.Context, key string, tm time.Time) *goredis.BoolCmd + + Incr(ctx context.Context, key string) *goredis.IntCmd + IncrBy(ctx context.Context, key string, value int64) *goredis.IntCmd + + PExpireAt(ctx context.Context, key string, tm time.Time) *goredis.BoolCmd + + XAdd(ctx context.Context, a *goredis.XAddArgs) *goredis.StringCmd + + HDel(ctx context.Context, key string, fields ...string) *goredis.IntCmd + HSet(ctx context.Context, key string, values ...interface{}) *goredis.IntCmd + HGetAll(ctx context.Context, key string) *goredis.StringStringMapCmd + + LPush(ctx context.Context, key string, values ...interface{}) *goredis.IntCmd + BRPop(ctx context.Context, timeout time.Duration, keys ...string) *goredis.StringSliceCmd + + // HyperLogLog. + PFCount(ctx context.Context, keys ...string) *goredis.IntCmd + PFAdd(ctx context.Context, key string, els ...interface{}) *goredis.IntCmd + + // For lua script + Eval(ctx context.Context, script string, keys []string, args ...interface{}) *goredis.Cmd + EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *goredis.Cmd + ScriptExists(ctx context.Context, hashes ...string) *goredis.BoolSliceCmd + ScriptLoad(ctx context.Context, script string) *goredis.StringCmd +} diff --git a/pkg/lib/infra/redisqueue/producer.go b/pkg/lib/infra/redisqueue/producer.go index 0c3f343c85..47d4962ed8 100644 --- a/pkg/lib/infra/redisqueue/producer.go +++ b/pkg/lib/infra/redisqueue/producer.go @@ -10,6 +10,7 @@ import ( goredis "github.com/go-redis/redis/v8" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/base32" "github.com/authgear/authgear-server/pkg/util/clock" @@ -49,7 +50,7 @@ func (p *Producer) NewTask(appID string, input json.RawMessage, taskIDPrefix str } func (p *Producer) EnqueueTask(ctx context.Context, task *Task) error { - return p.Redis.WithConnContext(ctx, func(conn *goredis.Conn) error { + return p.Redis.WithConnContext(ctx, func(conn redis.Redis_6_0_Cmdable) error { taskBytes, err := json.Marshal(task) if err != nil { return err @@ -80,7 +81,7 @@ func (p *Producer) EnqueueTask(ctx context.Context, task *Task) error { func (p *Producer) GetTask(ctx context.Context, item *QueueItem) (*Task, error) { var task Task - err := p.Redis.WithConnContext(ctx, func(conn *goredis.Conn) error { + err := p.Redis.WithConnContext(ctx, func(conn redis.Redis_6_0_Cmdable) error { taskBytes, err := conn.Get(ctx, item.RedisKey()).Bytes() if errors.Is(err, goredis.Nil) { return ErrTaskNotFound diff --git a/pkg/lib/infra/whatsapp/token_store_redis.go b/pkg/lib/infra/whatsapp/token_store_redis.go index 438408b61c..8fcd796cf8 100644 --- a/pkg/lib/infra/whatsapp/token_store_redis.go +++ b/pkg/lib/infra/whatsapp/token_store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" ) @@ -26,7 +27,7 @@ func (s *TokenStore) Set(token *UserToken) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := redisTokenKey(s.AppID, token.Endpoint, token.Username) ttl := token.ExpireAt.Sub(s.Clock.NowUTC()) @@ -43,7 +44,7 @@ func (s *TokenStore) Get(endpoint string, username string) (*UserToken, error) { ctx := context.Background() key := redisTokenKey(s.AppID, endpoint, username) var token *UserToken - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { return nil diff --git a/pkg/lib/interaction/store_redis.go b/pkg/lib/interaction/store_redis.go index b80be0e6da..5efa324b70 100644 --- a/pkg/lib/interaction/store_redis.go +++ b/pkg/lib/interaction/store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" ) @@ -32,7 +33,7 @@ func (s *StoreRedis) create(graph *Graph, ifNotExists bool) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { graphKey := redisGraphKey(s.AppID, graph.GraphID) instanceKey := redisInstanceKey(s.AppID, graph.InstanceID) ttl := GraphLifetime @@ -64,7 +65,7 @@ func (s *StoreRedis) GetGraphInstance(instanceID string) (*Graph, error) { ctx := context.Background() instanceKey := redisInstanceKey(s.AppID, instanceID) var graph Graph - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, instanceKey).Bytes() if errors.Is(err, goredis.Nil) { return ErrGraphNotFound @@ -92,7 +93,7 @@ func (s *StoreRedis) GetGraphInstance(instanceID string) (*Graph, error) { func (s *StoreRedis) DeleteGraph(graph *Graph) error { ctx := context.Background() - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { graphKey := redisGraphKey(s.AppID, graph.GraphID) _, err := conn.Del(ctx, graphKey).Result() if err != nil { diff --git a/pkg/lib/lockout/record.go b/pkg/lib/lockout/record.go index 2f83e7446f..324daa72bc 100644 --- a/pkg/lib/lockout/record.go +++ b/pkg/lib/lockout/record.go @@ -5,6 +5,8 @@ import ( "time" goredis "github.com/go-redis/redis/v8" + + "github.com/authgear/authgear-server/pkg/lib/infra/redis" ) type attemptResult struct { @@ -90,7 +92,8 @@ redis.call("HSET", record_key, contributor, contributor_total) redis.call("EXPIREAT", record_key, expire_at) if locked_until_epoch then - redis.call("SET", lock_key, locked_until_epoch, "EXAT", locked_until_epoch) + redis.call("SET", lock_key, locked_until_epoch) + redis.call("EXPIREAT", lock_key, locked_until_epoch) end return {is_success, locked_until_epoch} @@ -143,7 +146,7 @@ return 1 `) func makeAttempts( - ctx context.Context, conn *goredis.Conn, + ctx context.Context, conn redis.Redis_6_0_Cmdable, key string, historyDuration time.Duration, maxAttempts int, @@ -187,7 +190,7 @@ func makeAttempts( } func clearAttempts( - ctx context.Context, conn *goredis.Conn, + ctx context.Context, conn redis.Redis_6_0_Cmdable, key string, historyDuration time.Duration, contributor string) error { diff --git a/pkg/lib/lockout/storage_redis.go b/pkg/lib/lockout/storage_redis.go index e904256715..9be69a39cf 100644 --- a/pkg/lib/lockout/storage_redis.go +++ b/pkg/lib/lockout/storage_redis.go @@ -5,9 +5,8 @@ import ( "fmt" "time" - goredis "github.com/go-redis/redis/v8" - "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" ) @@ -19,7 +18,7 @@ type StorageRedis struct { var _ Storage = &StorageRedis{} func (s StorageRedis) Update(spec LockoutSpec, contributor string, delta int) (isSuccess bool, lockedUntil *time.Time, err error) { - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { r, err := makeAttempts(context.Background(), conn, redisRecordKey(s.AppID, spec), spec.HistoryDuration, @@ -42,7 +41,7 @@ func (s StorageRedis) Update(spec LockoutSpec, contributor string, delta int) (i } func (s StorageRedis) Clear(spec LockoutSpec, contributor string) (err error) { - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return clearAttempts(context.Background(), conn, redisRecordKey(s.AppID, spec), spec.HistoryDuration, diff --git a/pkg/lib/meter/read_store_redis.go b/pkg/lib/meter/read_store_redis.go index 4fb410cf83..b1de22ca92 100644 --- a/pkg/lib/meter/read_store_redis.go +++ b/pkg/lib/meter/read_store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/analyticredis" ) @@ -28,7 +29,7 @@ func (s *ReadStoreRedis) GetDailyPageViewCount( err = ErrMeterRedisIsNotConfigured return } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { pageViewKey := dailyPageView(appID, pageType, date) pageView, err = s.getCount(conn, pageViewKey) if err != nil { @@ -75,7 +76,7 @@ func (s *ReadStoreRedis) SetKeysExpire(keys []string, expiration time.Duration) if len(keys) == 0 { return nil } - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { for _, key := range keys { _, err := conn.Expire(s.Context, key, expiration).Result() if err != nil { @@ -90,7 +91,7 @@ func (s *ReadStoreRedis) SetKeysExpire(keys []string, expiration time.Duration) return nil } -func (s *ReadStoreRedis) getPFCountWithConn(conn *goredis.Conn, key string) (count int, err error) { +func (s *ReadStoreRedis) getPFCountWithConn(conn redis.Redis_6_0_Cmdable, key string) (count int, err error) { result, err := conn.PFCount(s.Context, key).Result() if err != nil { err = fmt.Errorf("failed to get pfcount: %w", err) @@ -105,7 +106,7 @@ func (s *ReadStoreRedis) getPFCount(key string) (count int, err error) { err = ErrMeterRedisIsNotConfigured return } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { count, err = s.getPFCountWithConn(conn, key) if err != nil { return err @@ -115,7 +116,7 @@ func (s *ReadStoreRedis) getPFCount(key string) (count int, err error) { return } -func (s *ReadStoreRedis) getCount(conn *goredis.Conn, key string) (count int, err error) { +func (s *ReadStoreRedis) getCount(conn redis.Redis_6_0_Cmdable, key string) (count int, err error) { countStr, err := conn.Get(s.Context, key).Result() if err != nil { if err == goredis.Nil { diff --git a/pkg/lib/meter/write_store_redis.go b/pkg/lib/meter/write_store_redis.go index a0ecf14cbc..5e2bb41bb0 100644 --- a/pkg/lib/meter/write_store_redis.go +++ b/pkg/lib/meter/write_store_redis.go @@ -5,9 +5,8 @@ import ( "fmt" "time" - goredis "github.com/go-redis/redis/v8" - "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/analyticredis" "github.com/authgear/authgear-server/pkg/util/clock" "github.com/authgear/authgear-server/pkg/util/log" @@ -47,7 +46,7 @@ func (s *WriteStoreRedis) TrackActiveUser(userID string) (err error) { weeklyActiveUserCount(s.AppID, year, week), dailyActiveUserCount(s.AppID, &now), } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { for _, key := range keys { _, err := conn.PFAdd(s.Context, key, userID).Result() if err != nil { @@ -65,7 +64,7 @@ func (s *WriteStoreRedis) TrackPageView(visitorID string, pageType PageType) (er return nil } now := s.Clock.NowUTC() - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { uniquePageViewKey := dailyUniquePageView(s.AppID, pageType, &now) _, err := conn.PFAdd(s.Context, uniquePageViewKey, visitorID).Result() if err != nil { diff --git a/pkg/lib/oauth/oauthsession/store_redis.go b/pkg/lib/oauth/oauthsession/store_redis.go index 79a922fd67..e876bf87bc 100644 --- a/pkg/lib/oauth/oauthsession/store_redis.go +++ b/pkg/lib/oauth/oauthsession/store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -29,7 +30,7 @@ func (s *StoreRedis) Save(entry *Entry) (err error) { key := oauthSessionEntryKey(s.AppID, entry.ID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Set(s.Context, key, jsonBytes, ttl).Result() return err }) @@ -42,7 +43,7 @@ func (s *StoreRedis) Save(entry *Entry) (err error) { func (s *StoreRedis) Get(entryID string) (entry *Entry, err error) { key := oauthSessionEntryKey(s.AppID, entryID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrNotFound @@ -62,7 +63,7 @@ func (s *StoreRedis) Get(entryID string) (entry *Entry, err error) { func (s *StoreRedis) Delete(entryID string) (err error) { key := oauthSessionEntryKey(s.AppID, entryID) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(s.Context, key).Result() if err != nil { return err diff --git a/pkg/lib/oauth/redis/store.go b/pkg/lib/oauth/redis/store.go index d2d4935416..7fd5b7607a 100644 --- a/pkg/lib/oauth/redis/store.go +++ b/pkg/lib/oauth/redis/store.go @@ -12,6 +12,7 @@ import ( "github.com/authgear/authgear-server/pkg/lib/config" "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/lib/oauth" "github.com/authgear/authgear-server/pkg/lib/session/access" @@ -35,7 +36,7 @@ type Store struct { Clock clock.Clock } -func (s *Store) loadData(conn *goredis.Conn, key string) ([]byte, error) { +func (s *Store) loadData(conn redis.Redis_6_0_Cmdable, key string) ([]byte, error) { ctx := context.Background() data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { @@ -112,7 +113,7 @@ func (s *Store) unmarshalPreAuthenticatedURLToken(data []byte) (*oauth.PreAuthen return &t, nil } -func (s *Store) save(conn *goredis.Conn, key string, value interface{}, expireAt time.Time, ifNotExists bool) error { +func (s *Store) save(conn redis.Redis_6_0_Cmdable, key string, value interface{}, expireAt time.Time, ifNotExists bool) error { ctx := context.Background() data, err := json.Marshal(value) if err != nil { @@ -137,7 +138,7 @@ func (s *Store) save(conn *goredis.Conn, key string, value interface{}, expireAt return nil } -func (s *Store) del(conn *goredis.Conn, key string) error { +func (s *Store) del(conn redis.Redis_6_0_Cmdable, key string) error { ctx := context.Background() _, err := conn.Del(ctx, key).Result() return err @@ -145,7 +146,7 @@ func (s *Store) del(conn *goredis.Conn, key string) error { func (s *Store) GetCodeGrant(codeHash string) (*oauth.CodeGrant, error) { var g *oauth.CodeGrant - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := s.loadData(conn, codeGrantKey(string(s.AppID), codeHash)) if err != nil { return err @@ -164,20 +165,20 @@ func (s *Store) GetCodeGrant(codeHash string) (*oauth.CodeGrant, error) { } func (s *Store) CreateCodeGrant(grant *oauth.CodeGrant) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.save(conn, codeGrantKey(grant.AppID, grant.CodeHash), grant, grant.ExpireAt, true) }) } func (s *Store) DeleteCodeGrant(grant *oauth.CodeGrant) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.del(conn, codeGrantKey(grant.AppID, grant.CodeHash)) }) } func (s *Store) GetSettingsActionGrant(codeHash string) (*oauth.SettingsActionGrant, error) { var g *oauth.SettingsActionGrant - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := s.loadData(conn, settingsActionGrantKey(string(s.AppID), codeHash)) if err != nil { return err @@ -196,20 +197,20 @@ func (s *Store) GetSettingsActionGrant(codeHash string) (*oauth.SettingsActionGr } func (s *Store) CreateSettingsActionGrant(grant *oauth.SettingsActionGrant) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.save(conn, settingsActionGrantKey(grant.AppID, grant.CodeHash), grant, grant.ExpireAt, true) }) } func (s *Store) DeleteSettingsActionGrant(grant *oauth.SettingsActionGrant) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.del(conn, settingsActionGrantKey(grant.AppID, grant.CodeHash)) }) } func (s *Store) GetAccessGrant(tokenHash string) (*oauth.AccessGrant, error) { var g *oauth.AccessGrant - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := s.loadData(conn, accessGrantKey(string(s.AppID), tokenHash)) if err != nil { return err @@ -230,20 +231,20 @@ func (s *Store) GetAccessGrant(tokenHash string) (*oauth.AccessGrant, error) { } func (s *Store) CreateAccessGrant(grant *oauth.AccessGrant) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.save(conn, accessGrantKey(grant.AppID, grant.TokenHash), grant, grant.ExpireAt, true) }) } func (s *Store) DeleteAccessGrant(grant *oauth.AccessGrant) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.del(conn, accessGrantKey(grant.AppID, grant.TokenHash)) }) } func (s *Store) GetOfflineGrantWithoutExpireAt(id string) (*oauth.OfflineGrant, error) { var g *oauth.OfflineGrant - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := s.loadData(conn, offlineGrantKey(string(s.AppID), id)) if err != nil { return err @@ -269,7 +270,7 @@ func (s *Store) CreateOfflineGrant(grant *oauth.OfflineGrant) error { return err } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err = conn.HSet(ctx, offlineGrantListKey(grant.AppID, grant.Attrs.UserID), grant.ID, expiry).Result() if err != nil { return fmt.Errorf("failed to update session list: %w", err) @@ -553,7 +554,7 @@ func (s *Store) updateOfflineGrant(grant *oauth.OfflineGrant, expireAt time.Time return err } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err = conn.HSet(ctx, offlineGrantListKey(grant.AppID, grant.Attrs.UserID), grant.ID, expiry).Result() if err != nil { return fmt.Errorf("failed to update session list: %w", err) @@ -575,7 +576,7 @@ func (s *Store) updateOfflineGrant(grant *oauth.OfflineGrant, expireAt time.Time func (s *Store) DeleteOfflineGrant(grant *oauth.OfflineGrant) error { ctx := context.Background() - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { err := s.del(conn, offlineGrantKey(grant.AppID, grant.ID)) if err != nil { return err @@ -600,7 +601,7 @@ func (s *Store) ListOfflineGrants(userID string) ([]*oauth.OfflineGrant, error) listKey := offlineGrantListKey(string(s.AppID), userID) var grants []*oauth.OfflineGrant - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { sessionList, err := conn.HGetAll(ctx, listKey).Result() if err != nil { return err @@ -662,7 +663,7 @@ func (s *Store) ListClientOfflineGrants(clientID string, userID string) ([]*oaut func (s *Store) GetAppSessionToken(tokenHash string) (*oauth.AppSessionToken, error) { t := &oauth.AppSessionToken{} - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := s.loadData(conn, appSessionTokenKey(string(s.AppID), tokenHash)) if err != nil { return err @@ -683,13 +684,13 @@ func (s *Store) GetAppSessionToken(tokenHash string) (*oauth.AppSessionToken, er } func (s *Store) CreateAppSessionToken(token *oauth.AppSessionToken) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.save(conn, appSessionTokenKey(token.AppID, token.TokenHash), token, token.ExpireAt, true) }) } func (s *Store) DeleteAppSessionToken(token *oauth.AppSessionToken) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.del(conn, appSessionTokenKey(token.AppID, token.TokenHash)) }) } @@ -697,7 +698,7 @@ func (s *Store) DeleteAppSessionToken(token *oauth.AppSessionToken) error { func (s *Store) GetAppSession(tokenHash string) (*oauth.AppSession, error) { var t *oauth.AppSession - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := s.loadData(conn, appSessionKey(string(s.AppID), tokenHash)) if err != nil { return err @@ -718,19 +719,19 @@ func (s *Store) GetAppSession(tokenHash string) (*oauth.AppSession, error) { } func (s *Store) CreateAppSession(session *oauth.AppSession) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.save(conn, appSessionKey(session.AppID, session.TokenHash), session, session.ExpireAt, true) }) } func (s *Store) DeleteAppSession(session *oauth.AppSession) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.del(conn, appSessionKey(session.AppID, session.TokenHash)) }) } func (s *Store) CreatePreAuthenticatedURLToken(token *oauth.PreAuthenticatedURLToken) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { return s.save(conn, preAuthenticatedURLTokenKey(token.AppID, token.TokenHash), token, token.ExpireAt, true) }) } @@ -738,7 +739,7 @@ func (s *Store) CreatePreAuthenticatedURLToken(token *oauth.PreAuthenticatedURLT func (s *Store) ConsumePreAuthenticatedURLToken(tokenHash string) (*oauth.PreAuthenticatedURLToken, error) { t := &oauth.PreAuthenticatedURLToken{} - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := preAuthenticatedURLTokenKey(string(s.AppID), tokenHash) data, err := s.loadData(conn, key) if err != nil { @@ -763,7 +764,7 @@ func (s *Store) CleanUpForDeletingUserID(userID string) (err error) { ctx := context.Background() listKey := offlineGrantListKey(string(s.AppID), userID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(ctx, listKey).Result() if err != nil { return err diff --git a/pkg/lib/ratelimit/gcra.go b/pkg/lib/ratelimit/gcra.go index e06f2abb60..836e55968d 100644 --- a/pkg/lib/ratelimit/gcra.go +++ b/pkg/lib/ratelimit/gcra.go @@ -5,6 +5,8 @@ import ( "time" goredis "github.com/go-redis/redis/v8" + + "github.com/authgear/authgear-server/pkg/lib/infra/redis" ) // ref: https://en.wikipedia.org/wiki/Generic_cell_rate_algorithm @@ -40,7 +42,8 @@ local allow_at = new_tat - dvt local is_conforming = now_timestamp >= allow_at local time_to_act = allow_at if is_conforming then - redis.call("SET", rate_limit_key, new_tat, "PXAT", new_tat) + redis.call("SET", rate_limit_key, new_tat) + redis.call("EXPIREAT", rate_limit_key, new_tat) time_to_act = allow_at + math.max(1, n) * emission_interval end @@ -52,7 +55,7 @@ type gcraResult struct { TimeToAct time.Time } -func gcra(ctx context.Context, conn *goredis.Conn, key string, period time.Duration, burst int, n int) (*gcraResult, error) { +func gcra(ctx context.Context, conn redis.Redis_6_0_Cmdable, key string, period time.Duration, burst int, n int) (*gcraResult, error) { result, err := gcraLuaScript.Run(ctx, conn, []string{key}, period.Milliseconds(), burst, n, diff --git a/pkg/lib/ratelimit/storage_redis.go b/pkg/lib/ratelimit/storage_redis.go index 601a64b403..0df0cb8e98 100644 --- a/pkg/lib/ratelimit/storage_redis.go +++ b/pkg/lib/ratelimit/storage_redis.go @@ -5,9 +5,8 @@ import ( "fmt" "time" - goredis "github.com/go-redis/redis/v8" - "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" ) @@ -17,7 +16,7 @@ type StorageRedis struct { } func (s StorageRedis) Update(spec BucketSpec, delta int) (ok bool, timeToAct time.Time, err error) { - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { result, err := gcra(context.Background(), conn, redisBucketKey(s.AppID, spec), spec.Period, spec.Burst, delta, ) diff --git a/pkg/lib/saml/samlsession/store_redis.go b/pkg/lib/saml/samlsession/store_redis.go index 63ff7006ff..643bd75848 100644 --- a/pkg/lib/saml/samlsession/store_redis.go +++ b/pkg/lib/saml/samlsession/store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -29,7 +30,7 @@ func (s *StoreRedis) Save(session *SAMLSession) (err error) { key := samlSessionEntryKey(s.AppID, session.ID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Set(s.Context, key, jsonBytes, ttl).Result() return err }) @@ -42,7 +43,7 @@ func (s *StoreRedis) Save(session *SAMLSession) (err error) { func (s *StoreRedis) Get(sessionID string) (entry *SAMLSession, err error) { key := samlSessionEntryKey(s.AppID, sessionID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrNotFound @@ -62,7 +63,7 @@ func (s *StoreRedis) Get(sessionID string) (entry *SAMLSession, err error) { func (s *StoreRedis) Delete(sessionID string) (err error) { key := samlSessionEntryKey(s.AppID, sessionID) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(s.Context, key).Result() if err != nil { return err diff --git a/pkg/lib/saml/samlslosession/store_redis.go b/pkg/lib/saml/samlslosession/store_redis.go index be2170736d..f69759f1fe 100644 --- a/pkg/lib/saml/samlslosession/store_redis.go +++ b/pkg/lib/saml/samlslosession/store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -29,7 +30,7 @@ func (s *StoreRedis) Save(session *SAMLSLOSession) (err error) { key := samlSLOSessionEntryKey(s.AppID, session.ID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Set(s.Context, key, jsonBytes, ttl).Result() return err }) @@ -42,7 +43,7 @@ func (s *StoreRedis) Save(session *SAMLSLOSession) (err error) { func (s *StoreRedis) Get(sessionID string) (entry *SAMLSLOSession, err error) { key := samlSLOSessionEntryKey(s.AppID, sessionID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrNotFound @@ -62,7 +63,7 @@ func (s *StoreRedis) Get(sessionID string) (entry *SAMLSLOSession, err error) { func (s *StoreRedis) Delete(sessionID string) (err error) { key := samlSLOSessionEntryKey(s.AppID, sessionID) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(s.Context, key).Result() if err != nil { return err diff --git a/pkg/lib/session/access/event_store_redis.go b/pkg/lib/session/access/event_store_redis.go index 4e33bbd0d1..5391e557b1 100644 --- a/pkg/lib/session/access/event_store_redis.go +++ b/pkg/lib/session/access/event_store_redis.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" ) @@ -40,7 +41,7 @@ func (s *EventStoreRedis) AppendEvent(sessionID string, expiry time.Time, event args.Approx = true } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() _, err = conn.XAdd(ctx, args).Result() if err != nil { @@ -59,7 +60,7 @@ func (s *EventStoreRedis) AppendEvent(sessionID string, expiry time.Time, event func (s *EventStoreRedis) ResetEventStream(sessionID string) error { streamKey := accessEventStreamKey(s.AppID, sessionID) - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() _, err := conn.Del(ctx, streamKey).Result() if err != nil { diff --git a/pkg/lib/session/idpsession/store_redis.go b/pkg/lib/session/idpsession/store_redis.go index 1ddf9487d2..66ed468a4a 100644 --- a/pkg/lib/session/idpsession/store_redis.go +++ b/pkg/lib/session/idpsession/store_redis.go @@ -12,6 +12,7 @@ import ( "github.com/sirupsen/logrus" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" "github.com/authgear/authgear-server/pkg/util/log" @@ -44,7 +45,7 @@ func (s *StoreRedis) Create(sess *IDPSession, expireAt time.Time) (err error) { listKey := sessionListKey(s.AppID, sess.Attrs.UserID) key := sessionKey(s.AppID, sess.ID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() _, err = conn.HSet(ctx, listKey, key, expiry).Result() @@ -86,7 +87,7 @@ func (s *StoreRedis) Update(sess *IDPSession, expireAt time.Time) (err error) { listKey := sessionListKey(s.AppID, sess.Attrs.UserID) key := sessionKey(s.AppID, sess.ID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err = conn.HSet(ctx, listKey, key, expiry).Result() if err != nil { return fmt.Errorf("failed to update session list: %w", err) @@ -128,7 +129,7 @@ func (s *StoreRedis) Get(id string) (*IDPSession, error) { key := sessionKey(s.AppID, id) var sess *IDPSession - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { data, err := conn.Get(ctx, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrSessionNotFound @@ -151,7 +152,7 @@ func (s *StoreRedis) Delete(session *IDPSession) (err error) { key := sessionKey(s.AppID, session.ID) listKey := sessionListKey(s.AppID, session.Attrs.UserID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(ctx, key).Result() if err == nil { _, err = conn.HDel(ctx, listKey, key).Result() @@ -172,7 +173,7 @@ func (s *StoreRedis) Delete(session *IDPSession) (err error) { func (s *StoreRedis) CleanUpForDeletingUserID(userID string) (err error) { ctx := context.Background() listKey := sessionListKey(s.AppID, userID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.Del(ctx, listKey).Result() if err != nil { return err @@ -188,7 +189,7 @@ func (s *StoreRedis) List(userID string) (sessions []*IDPSession, err error) { now := s.Clock.NowUTC() listKey := sessionListKey(s.AppID, userID) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { sessionList, err := conn.HGetAll(ctx, listKey).Result() if err != nil { return err diff --git a/pkg/lib/tester/store.go b/pkg/lib/tester/store.go index ce0b6af120..468a0391b3 100644 --- a/pkg/lib/tester/store.go +++ b/pkg/lib/tester/store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/globalredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -31,7 +32,7 @@ func (s *TesterStore) CreateToken( return nil, err } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := redisTokenKey(appID, token.TokenID) ttl := TokenLifetime @@ -56,7 +57,7 @@ func (s *TesterStore) GetToken( ) (*TesterToken, error) { key := redisTokenKey(appID, tokenID) var token TesterToken - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrTokenNotFound @@ -91,7 +92,7 @@ func (s *TesterStore) CreateResult( return nil, err } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := redisResultKey(appID, result.ID) ttl := ResultLifetime @@ -115,7 +116,7 @@ func (s *TesterStore) GetResult( ) (*TesterResult, error) { key := redisResultKey(appID, resultID) var result TesterResult - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrResultNotFound diff --git a/pkg/lib/usage/limit.go b/pkg/lib/usage/limit.go index de7a59f0ef..b06aff5a0e 100644 --- a/pkg/lib/usage/limit.go +++ b/pkg/lib/usage/limit.go @@ -5,9 +5,8 @@ import ( "fmt" "time" - goredis "github.com/go-redis/redis/v8" - "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/clock" "github.com/authgear/authgear-server/pkg/util/log" @@ -48,7 +47,7 @@ func (l *Limiter) Reserve(name LimitName, config *config.UsageLimitConfig) (*Res key := redisLimitKey(l.AppID, name) tokens := int64(0) - err := l.Redis.WithConn(func(conn *goredis.Conn) error { + err := l.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() usage, err := conn.IncrBy(ctx, key, 1).Result() if err != nil { @@ -88,7 +87,7 @@ func (l *Limiter) Cancel(r *Reservation) { key := redisLimitKey(l.AppID, r.name) - err := l.Redis.WithConn(func(conn *goredis.Conn) error { + err := l.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() _, err := conn.IncrBy(ctx, key, -1).Result() if err != nil { diff --git a/pkg/lib/webappoauth/store.go b/pkg/lib/webappoauth/store.go index 2048059cee..eacebddd7e 100644 --- a/pkg/lib/webappoauth/store.go +++ b/pkg/lib/webappoauth/store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/base32" "github.com/authgear/authgear-server/pkg/util/crypto" @@ -41,7 +42,7 @@ func (s *Store) GenerateState(state *WebappOAuthState) (stateToken string, err e stateToken, stateTokenHash := NewStateToken() key := stateKey(string(s.AppID), stateTokenHash) - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { _, err := conn.SetNX(s.Context, key, data, ttl).Result() if errors.Is(err, goredis.Nil) { err = fmt.Errorf("state string already exist: %w", err) @@ -63,15 +64,21 @@ func (s *Store) PopAndRecoverState(stateToken string) (state *WebappOAuthState, key := stateKey(string(s.AppID), stateTokenHash) var data []byte - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { var err error - data, err = conn.GetDel(s.Context, key).Bytes() + data, err = conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { err = ErrOAuthStateInvalid return err } else if err != nil { return err } + + _, err = conn.Del(s.Context, key).Result() + if err != nil { + return err + } + return nil }) if err != nil { diff --git a/pkg/lib/workflow/store.go b/pkg/lib/workflow/store.go index a942e91e8c..f29824b7b6 100644 --- a/pkg/lib/workflow/store.go +++ b/pkg/lib/workflow/store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/appredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -27,7 +28,7 @@ func (s *StoreImpl) CreateWorkflow(workflow *Workflow) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { workflowKey := redisWorkflowKey(s.AppID, workflow.WorkflowID) instanceKey := redisWorkflowInstanceKey(s.AppID, workflow.InstanceID) ttl := Lifetime @@ -49,7 +50,7 @@ func (s *StoreImpl) CreateWorkflow(workflow *Workflow) error { func (s *StoreImpl) GetWorkflowByInstanceID(instanceID string) (*Workflow, error) { instanceKey := redisWorkflowInstanceKey(s.AppID, instanceID) var workflow Workflow - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := conn.Get(s.Context, instanceKey).Bytes() if errors.Is(err, goredis.Nil) { return ErrWorkflowNotFound @@ -80,7 +81,7 @@ func (s *StoreImpl) GetWorkflowByInstanceID(instanceID string) (*Workflow, error func (s *StoreImpl) DeleteWorkflow(workflow *Workflow) error { // We do not delete the instances because there are many of them. // Deleting the workflowID is enough to make GetWorkflowByInstanceID to return ErrWorkflowNotFound. - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { workflowKey := redisWorkflowKey(s.AppID, workflow.WorkflowID) _, err := conn.Del(s.Context, workflowKey).Result() @@ -98,7 +99,7 @@ func (s *StoreImpl) CreateSession(session *Session) error { return err } - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { sessionKey := redisWorkflowSessionKey(s.AppID, session.WorkflowID) ttl := Lifetime @@ -114,7 +115,7 @@ func (s *StoreImpl) CreateSession(session *Session) error { func (s *StoreImpl) GetSession(workflowID string) (*Session, error) { sessionKey := redisWorkflowSessionKey(s.AppID, workflowID) var session Session - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := conn.Get(s.Context, sessionKey).Bytes() if errors.Is(err, goredis.Nil) { return ErrWorkflowNotFound @@ -134,7 +135,7 @@ func (s *StoreImpl) GetSession(workflowID string) (*Session, error) { } func (s *StoreImpl) DeleteSession(session *Session) error { - return s.Redis.WithConn(func(conn *goredis.Conn) error { + return s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { sessionKey := redisWorkflowSessionKey(s.AppID, session.WorkflowID) _, err := conn.Del(s.Context, sessionKey).Result() diff --git a/pkg/portal/appsecret/token_store.go b/pkg/portal/appsecret/token_store.go index 9591819e0b..392ec594dc 100644 --- a/pkg/portal/appsecret/token_store.go +++ b/pkg/portal/appsecret/token_store.go @@ -9,6 +9,7 @@ import ( goredis "github.com/go-redis/redis/v8" "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/globalredis" "github.com/authgear/authgear-server/pkg/util/duration" ) @@ -34,7 +35,7 @@ func (s *AppSecretVisitTokenStoreImpl) CreateToken( return nil, err } - err = s.Redis.WithConn(func(conn *goredis.Conn) error { + err = s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { key := redisTokenKey(appID, token.TokenID) ttl := Lifetime @@ -58,7 +59,7 @@ func (s *AppSecretVisitTokenStoreImpl) GetTokenByID( ) (*AppSecretVisitToken, error) { key := redisTokenKey(appID, tokenID) var token AppSecretVisitToken - err := s.Redis.WithConn(func(conn *goredis.Conn) error { + err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := conn.Get(s.Context, key).Bytes() if errors.Is(err, goredis.Nil) { return ErrTokenNotFound diff --git a/pkg/portal/libstripe/service.go b/pkg/portal/libstripe/service.go index c5d906fbd8..862103d7d7 100644 --- a/pkg/portal/libstripe/service.go +++ b/pkg/portal/libstripe/service.go @@ -11,11 +11,11 @@ import ( "time" relay "github.com/authgear/graphql-go-relay" - goredis "github.com/go-redis/redis/v8" "github.com/stripe/stripe-go/v72" "github.com/stripe/stripe-go/v72/client" "github.com/stripe/stripe-go/v72/webhook" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/globalredis" portalconfig "github.com/authgear/authgear-server/pkg/portal/config" "github.com/authgear/authgear-server/pkg/portal/model" @@ -75,7 +75,7 @@ func (s *Service) FetchSubscriptionPlans() (subscriptionPlans []*model.Subscript Do: s.fetchSubscriptionPlans, } - err = s.GlobalRedisHandle.WithConn(func(conn *goredis.Conn) error { + err = s.GlobalRedisHandle.WithConn(func(conn redis.Redis_6_0_Cmdable) error { bytes, err := s.Cache.Get(s.Context, conn, item) if err != nil { return err diff --git a/pkg/redisqueue/consumer.go b/pkg/redisqueue/consumer.go index d3700ca181..7d2392c5ea 100644 --- a/pkg/redisqueue/consumer.go +++ b/pkg/redisqueue/consumer.go @@ -12,6 +12,7 @@ import ( "github.com/authgear/authgear-server/pkg/api/apierrors" "github.com/authgear/authgear-server/pkg/lib/config/configsource" "github.com/authgear/authgear-server/pkg/lib/deps" + "github.com/authgear/authgear-server/pkg/lib/infra/redis" "github.com/authgear/authgear-server/pkg/lib/infra/redis/globalredis" "github.com/authgear/authgear-server/pkg/lib/infra/redisqueue" "github.com/authgear/authgear-server/pkg/util/backoff" @@ -117,7 +118,7 @@ func (c *Consumer) dequeue(ctx context.Context) (*redisqueue.Task, *deps.AppProv var task redisqueue.Task var appProvider *deps.AppProvider - err := c.redis.WithConnContext(ctx, func(conn *goredis.Conn) error { + err := c.redis.WithConnContext(ctx, func(conn redis.Redis_6_0_Cmdable) error { queueKey := redisqueue.RedisKeyForQueue(c.QueueName) strs, err := conn.BRPop(ctx, timeout, queueKey).Result() @@ -239,7 +240,7 @@ func (c *Consumer) work(ctx context.Context) { return } - err = c.redis.WithConnContext(ctx, func(conn *goredis.Conn) error { + err = c.redis.WithConnContext(ctx, func(conn redis.Redis_6_0_Cmdable) error { key := task.RedisKey() _, err := conn.Set(ctx, key, taskBytes, redisqueue.TTL).Result() if err != nil { diff --git a/resources/authgear/templates/en/web/authflowv2/__lockout.html b/resources/authgear/templates/en/web/authflowv2/__lockout.html index c910986018..a8560d74d7 100644 --- a/resources/authgear/templates/en/web/authflowv2/__lockout.html +++ b/resources/authgear/templates/en/web/authflowv2/__lockout.html @@ -5,7 +5,7 @@