From faae2997cdf09977d30bc7d7f05bbced111a4a60 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Wed, 30 Apr 2025 14:32:16 +0300 Subject: [PATCH 01/19] added redis limiter methods and unit tests --- redis/interface.go | 8 ++++++ redis/redisLimiter.go | 20 +++++++++++++ redis/redisLimiter_test.go | 58 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/redis/interface.go b/redis/interface.go index f9e2a1dc..a3f7aa35 100644 --- a/redis/interface.go +++ b/redis/interface.go @@ -14,6 +14,14 @@ const ( SecurityMode ) +type Status int + +const ( + NotSet Status = iota + ManualSet + AutomaticallySet +) + // RateLimiter defines the behaviour of a rate limiter component type RateLimiter interface { CheckAllowedAndIncreaseTrials(key string, mode Mode) (*RateLimiterResult, error) diff --git a/redis/redisLimiter.go b/redis/redisLimiter.go index 0eccfd9f..bfa9e008 100644 --- a/redis/redisLimiter.go +++ b/redis/redisLimiter.go @@ -2,6 +2,7 @@ package redis import ( "context" + "errors" "fmt" "sync" "time" @@ -214,6 +215,25 @@ func (rl *rateLimiter) SetSecurityModeNoExpire(key string) error { return nil } +// GetSecurityStatus will return the security status based on the expiry time of the key +func (rl *rateLimiter) GetSecurityStatus(key string) Status { + ctx, cancel := context.WithTimeout(context.Background(), rl.operationTimeout) + defer cancel() + + return rl.getSecurityStatus(ctx, key) +} + +func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) Status { + expTime, err := rl.storer.ExpireTime(ctx, key) + if errors.Is(err, ErrKeyNotExists) { + return NotSet + } else if expTime == core.NoExpiryValue { + return ManualSet + } else { + return AutomaticallySet + } +} + // UnsetSecurityModeNoExpire will set the key from persistent to volatile func (rl *rateLimiter) UnsetSecurityModeNoExpire(key string) error { ctx, cancel := context.WithTimeout(context.Background(), rl.operationTimeout) diff --git a/redis/redisLimiter_test.go b/redis/redisLimiter_test.go index dca79030..1adcc5e5 100644 --- a/redis/redisLimiter_test.go +++ b/redis/redisLimiter_test.go @@ -508,6 +508,64 @@ func TestUnsetSecurityModeNoExpire(t *testing.T) { }) } +func TestGetSecurityStatus(t *testing.T) { + t.Parallel() + + t.Run("should return NotSet", func(t *testing.T) { + t.Parallel() + + args := createMockRateLimiterArgs() + redisClient := &testscommon.RedisClientStub{ + ExpireTimeCalled: func(ctx context.Context, key string) (time.Duration, error) { + return 0, redis.ErrKeyNotExists + }, + } + args.Storer = redisClient + + rl, err := redis.NewRateLimiter(args) + require.Nil(t, err) + + actualStatus := rl.GetSecurityStatus("key") + require.Equal(t, redis.NotSet, actualStatus) + }) + + t.Run("should return ManualSet", func(t *testing.T) { + t.Parallel() + + args := createMockRateLimiterArgs() + redisClient := &testscommon.RedisClientStub{ + ExpireTimeCalled: func(ctx context.Context, key string) (time.Duration, error) { + return -1, nil + }, + } + args.Storer = redisClient + + rl, err := redis.NewRateLimiter(args) + require.Nil(t, err) + + actualStatus := rl.GetSecurityStatus("key") + require.Equal(t, redis.ManualSet, actualStatus) + }) + + t.Run("should return AutomaticallySet", func(t *testing.T) { + t.Parallel() + + args := createMockRateLimiterArgs() + redisClient := &testscommon.RedisClientStub{ + ExpireTimeCalled: func(ctx context.Context, key string) (time.Duration, error) { + return 10, nil + }, + } + args.Storer = redisClient + + rl, err := redis.NewRateLimiter(args) + require.Nil(t, err) + + actualStatus := rl.GetSecurityStatus("key") + require.Equal(t, redis.AutomaticallySet, actualStatus) + }) +} + func TestDecrementSecurityFailedTrials(t *testing.T) { t.Parallel() From 20f72fad463a49b114742dda2fb2cf35c68535b0 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Wed, 30 Apr 2025 17:35:44 +0300 Subject: [PATCH 02/19] added security status endpoint --- api/groups/guardianGroup.go | 52 ++++++++++++++++++++++++ api/shared/interface.go | 1 + core/constants.go | 8 ++++ core/interface.go | 1 + core/requests/types.go | 11 +++++ facade/guardianFacade.go | 5 +++ handlers/interface.go | 1 + handlers/secureOtp/secureOtpHandler.go | 5 +++ redis/interface.go | 11 ++--- redis/redisLimiter.go | 15 +++---- redis/redisLimiter_test.go | 6 +-- resolver/serviceResolver.go | 29 +++++++++++++ testscommon/facade/guardianFacadeStub.go | 9 ++++ testscommon/rateLimiterMock.go | 6 +++ testscommon/rateLimiterStub.go | 10 +++++ testscommon/secureOtpHandlerStub.go | 14 ++++++- testscommon/serviceResolverStub.go | 10 +++++ 17 files changed, 175 insertions(+), 19 deletions(-) diff --git a/api/groups/guardianGroup.go b/api/groups/guardianGroup.go index 8d7768e0..8ec7646b 100644 --- a/api/groups/guardianGroup.go +++ b/api/groups/guardianGroup.go @@ -30,6 +30,7 @@ const ( signMultipleTransactionsPath = "/sign-multiple-transactions" setSecurityModeNoExpirePath = "/set-security-mode" unsetSecurityModeNoExpirePath = "/unset-security-mode" + getSecurityStatus = "/security-status" registerPath = "/register" verifyCodePath = "/verify-code" registeredUsersPath = "/registered-users" @@ -103,6 +104,11 @@ func NewGuardianGroup(facade shared.FacadeHandler) (*guardianGroup, error) { Method: http.MethodGet, Handler: gg.config, }, + { + Path: getSecurityStatus, + Method: http.MethodGet, + Handler: gg.getSecurityStatus, + }, } gg.endpoints = endpoints @@ -237,6 +243,52 @@ func (gg *guardianGroup) unsetSecurityModeNoExpire(c *gin.Context) { returnStatus(c, nil, http.StatusOK, "", chainApiShared.ReturnCodeSuccess) } +func (gg *guardianGroup) getSecurityStatus(c *gin.Context) { + var request requests.UserStatusRequest + var debugErr error + + userIp := c.GetString(mfaMiddleware.UserIpKey) + userAgent := c.GetString(mfaMiddleware.UserAgentKey) + defer func() { + logUserStatusRequest(userIp, userAgent, &request, debugErr) + }() + + err := json.NewDecoder(c.Request.Body).Decode(&request) + if err != nil { + debugErr = fmt.Errorf("%w while decoding request", err) + returnStatus(c, nil, http.StatusBadRequest, err.Error(), chainApiShared.ReturnCodeRequestError) + return + } + status, err := gg.facade.GetSecurityStatus(request) + if err != nil { + debugErr = fmt.Errorf("%w while interrogating security status", err) + handleErrorAndReturn(c, status, err.Error()) + return + + } + + returnStatus(c, status, http.StatusOK, "", chainApiShared.ReturnCodeSuccess) +} + +func logUserStatusRequest(userIp string, userAgent string, request *requests.UserStatusRequest, debugErr error) { + logArgs := []interface{}{ + "route", getSecurityStatus, + "ip", userIp, + "user agent", userAgent, + "userAddr", getPrintableData(request.UserAddr), + } + defer func() { + guardianLog.Info("Request info", logArgs...) + }() + + if debugErr == nil { + logArgs = append(logArgs, "result", "success") + return + } + + logArgs = append(logArgs, "error", debugErr.Error()) +} + // signTransaction returns the transaction signed by the guardian if the verification passed func (gg *guardianGroup) signTransaction(c *gin.Context) { var request requests.SignTransaction diff --git a/api/shared/interface.go b/api/shared/interface.go index ada45584..91d5908a 100644 --- a/api/shared/interface.go +++ b/api/shared/interface.go @@ -28,6 +28,7 @@ type FacadeHandler interface { SignMultipleTransactions(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) SetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) + GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) RegisteredUsers() (uint32, error) TcsConfig() *tcsCore.TcsConfig GetMetrics() map[string]*requests.EndpointMetricsResponse diff --git a/core/constants.go b/core/constants.go index a6ef2c91..7c3a2112 100644 --- a/core/constants.go +++ b/core/constants.go @@ -30,3 +30,11 @@ const ( // NoExpiryValue is the returned value for a persistent key expiry time const NoExpiryValue = -1 + +type Status int + +const ( + NotSet Status = iota + ManualSet + AutomaticallySet +) diff --git a/core/interface.go b/core/interface.go index 8013a7fe..6a65734a 100644 --- a/core/interface.go +++ b/core/interface.go @@ -37,6 +37,7 @@ type ServiceResolver interface { SignMessage(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) + GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) SignTransaction(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactions(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) RegisteredUsers() (uint32, error) diff --git a/core/requests/types.go b/core/requests/types.go index 99695760..b584aad8 100644 --- a/core/requests/types.go +++ b/core/requests/types.go @@ -24,6 +24,17 @@ type SecurityModeNoExpire struct { UserAddr string `json:"user"` } +// UserStatusRequest is the JSON request the service is receiving +// for the user status interrogation +type UserStatusRequest struct { + UserAddr string `json:"user"` +} + +// UserStatusResponse - is the JSON response for the user status interrogation +type UserStatusResponse struct { + SecurityStatus int `json:"code"` +} + // SignMessageResponse is the service response to the sign message request type SignMessageResponse struct { Message string `json:"message"` diff --git a/facade/guardianFacade.go b/facade/guardianFacade.go index 6bccac7e..88b8963e 100644 --- a/facade/guardianFacade.go +++ b/facade/guardianFacade.go @@ -65,6 +65,11 @@ func (gf *guardianFacade) UnsetSecurityModeNoExpire(userIp string, request reque return gf.serviceResolver.UnsetSecurityModeNoExpire(userIp, request) } +// GetSecurityStatus gets the user's security status +func (gf *guardianFacade) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + return gf.serviceResolver.GetSecurityStatus(request) +} + // SignMultipleTransactions validates user's transactions, then adds guardian signature and returns the transaction func (gf *guardianFacade) SignMultipleTransactions(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) { return gf.serviceResolver.SignMultipleTransactions(userIp, request) diff --git a/handlers/interface.go b/handlers/interface.go index a5f604df..aba4b09d 100644 --- a/handlers/interface.go +++ b/handlers/interface.go @@ -22,6 +22,7 @@ type SecureOtpHandler interface { SecurityModeMaxFailures() uint64 SetSecurityModeNoExpire(key string) error UnsetSecurityModeNoExpire(key string) error + GetSecurityStatus(key string) core.Status IsVerificationAllowedAndIncreaseTrials(account string, ip string) (*requests.OTPCodeVerifyData, error) Reset(account string, ip string) DecrementSecurityModeFailedTrials(account string) error diff --git a/handlers/secureOtp/secureOtpHandler.go b/handlers/secureOtp/secureOtpHandler.go index 8c9ed673..a8919148 100644 --- a/handlers/secureOtp/secureOtpHandler.go +++ b/handlers/secureOtp/secureOtpHandler.go @@ -114,6 +114,11 @@ func (totp *secureOtpHandler) UnsetSecurityModeNoExpire(key string) error { return totp.rateLimiter.UnsetSecurityModeNoExpire(key) } +// GetSecurityStatus - returns the status of the security mode +func (totp *secureOtpHandler) GetSecurityStatus(key string) core.Status { + return totp.rateLimiter.GetSecurityStatus(key) +} + // Reset removes the account and ip from local cache func (totp *secureOtpHandler) Reset(account string, ip string) { key := computeVerificationKey(account, ip) diff --git a/redis/interface.go b/redis/interface.go index a3f7aa35..7ef3630b 100644 --- a/redis/interface.go +++ b/redis/interface.go @@ -3,6 +3,8 @@ package redis import ( "context" "time" + + "github.com/multiversx/mx-multi-factor-auth-go-service/core" ) type Mode int @@ -14,20 +16,13 @@ const ( SecurityMode ) -type Status int - -const ( - NotSet Status = iota - ManualSet - AutomaticallySet -) - // RateLimiter defines the behaviour of a rate limiter component type RateLimiter interface { CheckAllowedAndIncreaseTrials(key string, mode Mode) (*RateLimiterResult, error) Reset(key string) error SetSecurityModeNoExpire(key string) error UnsetSecurityModeNoExpire(key string) error + GetSecurityStatus(key string) core.Status DecrementSecurityFailedTrials(key string) error Period(mode Mode) time.Duration Rate(mode Mode) int diff --git a/redis/redisLimiter.go b/redis/redisLimiter.go index bfa9e008..de3305de 100644 --- a/redis/redisLimiter.go +++ b/redis/redisLimiter.go @@ -216,22 +216,23 @@ func (rl *rateLimiter) SetSecurityModeNoExpire(key string) error { } // GetSecurityStatus will return the security status based on the expiry time of the key -func (rl *rateLimiter) GetSecurityStatus(key string) Status { +func (rl *rateLimiter) GetSecurityStatus(key string) core.Status { ctx, cancel := context.WithTimeout(context.Background(), rl.operationTimeout) defer cancel() return rl.getSecurityStatus(ctx, key) } -func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) Status { +func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) core.Status { expTime, err := rl.storer.ExpireTime(ctx, key) if errors.Is(err, ErrKeyNotExists) { - return NotSet - } else if expTime == core.NoExpiryValue { - return ManualSet - } else { - return AutomaticallySet + return core.NotSet } + if expTime == core.NoExpiryValue { + return core.ManualSet + } + + return core.AutomaticallySet } // UnsetSecurityModeNoExpire will set the key from persistent to volatile diff --git a/redis/redisLimiter_test.go b/redis/redisLimiter_test.go index 1adcc5e5..897e2cfd 100644 --- a/redis/redisLimiter_test.go +++ b/redis/redisLimiter_test.go @@ -526,7 +526,7 @@ func TestGetSecurityStatus(t *testing.T) { require.Nil(t, err) actualStatus := rl.GetSecurityStatus("key") - require.Equal(t, redis.NotSet, actualStatus) + require.Equal(t, core.NotSet, actualStatus) }) t.Run("should return ManualSet", func(t *testing.T) { @@ -544,7 +544,7 @@ func TestGetSecurityStatus(t *testing.T) { require.Nil(t, err) actualStatus := rl.GetSecurityStatus("key") - require.Equal(t, redis.ManualSet, actualStatus) + require.Equal(t, core.ManualSet, actualStatus) }) t.Run("should return AutomaticallySet", func(t *testing.T) { @@ -562,7 +562,7 @@ func TestGetSecurityStatus(t *testing.T) { require.Nil(t, err) actualStatus := rl.GetSecurityStatus("key") - require.Equal(t, redis.AutomaticallySet, actualStatus) + require.Equal(t, core.AutomaticallySet, actualStatus) }) } diff --git a/resolver/serviceResolver.go b/resolver/serviceResolver.go index e6af204a..97ebf440 100644 --- a/resolver/serviceResolver.go +++ b/resolver/serviceResolver.go @@ -289,6 +289,18 @@ func (resolver *serviceResolver) UnsetSecurityModeNoExpire(userIp string, reques return verifyCodeData, resolver.secureOtpHandler.UnsetSecurityModeNoExpire(request.UserAddr) } +// GetSecurityStatus gets the user's security status +func (resolver *serviceResolver) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + status, err := resolver.verifyUserReturningSecurityStatus(request.UserAddr) + if err != nil { + return &requests.UserStatusResponse{}, err + } + + return &requests.UserStatusResponse{ + SecurityStatus: int(status), + }, nil +} + // SignTransaction validates user's transaction, then adds guardian signature and returns the transaction func (resolver *serviceResolver) SignTransaction(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) { guardian, otpCodeVerifyData, err := resolver.validateTxRequestReturningGuardian(userIp, request.Code, request.SecondCode, []transaction.FrontendTransaction{request.Tx}) @@ -485,6 +497,23 @@ func (resolver *serviceResolver) validateTxRequestReturningGuardian( return resolver.verifyCodesReturningGuardian(userAddress, txs[0].GuardianAddr, userIp, code, secondCode) } +func (resolver *serviceResolver) verifyUserReturningSecurityStatus(userAddr string) (core.Status, error) { + userAddress, err := sdkData.NewAddressFromBech32String(userAddr) + if err != nil { + return 0, err + } + + addressBytes := userAddress.AddressBytes() + resolver.userCritSection.RLock(string(addressBytes)) + _, err = resolver.getUserInfo(addressBytes) + resolver.userCritSection.RUnlock(string(addressBytes)) + if err != nil { + return -1, nil + } + + return resolver.secureOtpHandler.GetSecurityStatus(userAddr), nil +} + func (resolver *serviceResolver) verifyCodesReturningGuardian( userAddress sdkCore.AddressHandler, guardianAddr string, diff --git a/testscommon/facade/guardianFacadeStub.go b/testscommon/facade/guardianFacadeStub.go index a8fe4845..5f2e88f1 100644 --- a/testscommon/facade/guardianFacadeStub.go +++ b/testscommon/facade/guardianFacadeStub.go @@ -14,6 +14,7 @@ type GuardianFacadeStub struct { SignMessageCalled func(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) + GetSecurityStatusCalled func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) SignTransactionCalled func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactionsCalled func(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) RegisteredUsersCalled func() (uint32, error) @@ -62,6 +63,14 @@ func (stub *GuardianFacadeStub) UnsetSecurityModeNoExpire(userIp string, request return nil, nil } +// GetSecurityStatus - +func (stub *GuardianFacadeStub) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + if stub.GetSecurityStatusCalled != nil { + return stub.GetSecurityStatusCalled(request) + } + return &requests.UserStatusResponse{}, nil +} + // SignTransaction - func (stub *GuardianFacadeStub) SignTransaction(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) { if stub.SignTransactionCalled != nil { diff --git a/testscommon/rateLimiterMock.go b/testscommon/rateLimiterMock.go index 4df6fc16..e46a39d7 100644 --- a/testscommon/rateLimiterMock.go +++ b/testscommon/rateLimiterMock.go @@ -4,6 +4,7 @@ import ( "sync" "time" + "github.com/multiversx/mx-multi-factor-auth-go-service/core" "github.com/multiversx/mx-multi-factor-auth-go-service/redis" ) @@ -59,6 +60,11 @@ func (r *RateLimiterMock) UnsetSecurityModeNoExpire(key string) error { return nil } +// GetSecurityStatus - +func (r *RateLimiterMock) GetSecurityStatus(key string) core.Status { + return 0 +} + // Reset - func (r *RateLimiterMock) Reset(key string) error { r.mutTrials.Lock() diff --git a/testscommon/rateLimiterStub.go b/testscommon/rateLimiterStub.go index e10945a4..cd54ec80 100644 --- a/testscommon/rateLimiterStub.go +++ b/testscommon/rateLimiterStub.go @@ -3,6 +3,7 @@ package testscommon import ( "time" + "github.com/multiversx/mx-multi-factor-auth-go-service/core" "github.com/multiversx/mx-multi-factor-auth-go-service/redis" ) @@ -15,6 +16,7 @@ type RateLimiterStub struct { RateCalled func(mode redis.Mode) int SetSecurityModeNoExpireCalled func(key string) error UnsetSecurityModeNoExpireCalled func(key string) error + GetSecurityStatusCalled func(key string) core.Status ExtendSecurityModeCalled func(key string) error } @@ -52,6 +54,14 @@ func (r *RateLimiterStub) UnsetSecurityModeNoExpire(key string) error { return nil } +// GetSecurityStatus - +func (r *RateLimiterStub) GetSecurityStatus(key string) core.Status { + if r.GetSecurityStatusCalled != nil { + return r.GetSecurityStatusCalled(key) + } + return -1 +} + // Reset - func (r *RateLimiterStub) Reset(key string) error { if r.ResetCalled != nil { diff --git a/testscommon/secureOtpHandlerStub.go b/testscommon/secureOtpHandlerStub.go index 3d067221..fa56b7ec 100644 --- a/testscommon/secureOtpHandlerStub.go +++ b/testscommon/secureOtpHandlerStub.go @@ -1,6 +1,9 @@ package testscommon -import "github.com/multiversx/mx-multi-factor-auth-go-service/core/requests" +import ( + "github.com/multiversx/mx-multi-factor-auth-go-service/core" + "github.com/multiversx/mx-multi-factor-auth-go-service/core/requests" +) // SecureOtpHandlerStub is a stub implementation of the SecureOtpHandler interface type SecureOtpHandlerStub struct { @@ -9,6 +12,7 @@ type SecureOtpHandlerStub struct { DecrementSecurityModeFailedTrialsCalled func(account string) error SetSecurityModeNoExpireCalled func(key string) error UnsetSecurityModeNoExpireCalled func(key string) error + GetSecurityStatusCalled func(key string) core.Status FreezeBackoffTimeCalled func() uint64 FreezeMaxFailuresCalled func() uint64 SecurityModeBackOffTimeCalled func() uint64 @@ -41,6 +45,14 @@ func (stub *SecureOtpHandlerStub) UnsetSecurityModeNoExpire(key string) error { return nil } +// GetSecurityStatus - +func (stub *SecureOtpHandlerStub) GetSecurityStatus(key string) core.Status { + if stub.GetSecurityStatusCalled != nil { + return stub.GetSecurityStatusCalled(key) + } + return core.NotSet +} + // Reset removes the account and ip from local cache func (stub *SecureOtpHandlerStub) Reset(account string, ip string) { if stub.ResetCalled != nil { diff --git a/testscommon/serviceResolverStub.go b/testscommon/serviceResolverStub.go index 0dbadf2f..dd1be593 100644 --- a/testscommon/serviceResolverStub.go +++ b/testscommon/serviceResolverStub.go @@ -14,6 +14,7 @@ type ServiceResolverStub struct { VerifyCodeCalled func(userAddress core.AddressHandler, userIp string, request requests.VerificationPayload) (*requests.OTPCodeVerifyData, error) SetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) + GetSecurityStatusCalled func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) SignMessageCalled func(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SignTransactionCalled func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactionsCalled func(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) @@ -61,6 +62,15 @@ func (stub *ServiceResolverStub) UnsetSecurityModeNoExpire(userIp string, reques return nil, nil } +// GetSecurityStatus - +func (stub *ServiceResolverStub) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + if stub.GetSecurityStatusCalled != nil { + return stub.GetSecurityStatusCalled(request) + } + + return &requests.UserStatusResponse{}, nil +} + // SignTransaction - func (stub *ServiceResolverStub) SignTransaction(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) { if stub.SignTransactionCalled != nil { From 65bbe3722fa88c5c22909cd70467a5cc744951f9 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Fri, 2 May 2025 12:06:15 +0300 Subject: [PATCH 03/19] added unit tests --- api/groups/common_test.go | 1 + api/groups/guardianGroup_test.go | 89 ++++++++++++++ cmd/multi-factor-auth/config/api.toml | 1 + facade/guardianFacade_test.go | 13 ++ go.mod | 4 +- handlers/secureOtp/secureOtpHandler_test.go | 15 +++ resolver/serviceResolver.go | 7 +- resolver/serviceResolver_test.go | 128 ++++++++++++++++++++ 8 files changed, 252 insertions(+), 6 deletions(-) diff --git a/api/groups/common_test.go b/api/groups/common_test.go index 5f6f77b8..eeb42bc8 100644 --- a/api/groups/common_test.go +++ b/api/groups/common_test.go @@ -48,6 +48,7 @@ func getServiceRoutesConfig() config.ApiRoutesConfig { {Name: "/sign-multiple-transactions", Open: true}, {Name: "/set-security-mode", Open: true}, {Name: "/unset-security-mode", Open: true}, + {Name: "/security-status", Open: true}, {Name: "/debug", Open: true}, {Name: "/verify-code", Open: true}, {Name: "/registered-users", Open: true}, diff --git a/api/groups/guardianGroup_test.go b/api/groups/guardianGroup_test.go index 87b68e16..319fac38 100644 --- a/api/groups/guardianGroup_test.go +++ b/api/groups/guardianGroup_test.go @@ -516,6 +516,95 @@ func TestGuardianGroup_UnsetSecurityModeNoExpire(t *testing.T) { }) } +func TestGuardianGroup_getSecurityStatus(t *testing.T) { + t.Parallel() + + t.Run("empty body", func(t *testing.T) { + t.Parallel() + + gg, _ := groups.NewGuardianGroup(&mockFacade.GuardianFacadeStub{}) + + ws := startWebServer(gg, "guardian", getServiceRoutesConfig(), providedAddr) + + req, _ := http.NewRequest("GET", "/guardian/security-status", strings.NewReader("")) + resp := httptest.NewRecorder() + ws.ServeHTTP(resp, req) + + statusRsp := generalResponse{} + loadResponse(resp.Body, &statusRsp) + + assert.Nil(t, statusRsp.Data) + assert.True(t, strings.Contains(statusRsp.Error, "EOF")) + require.Equal(t, http.StatusBadRequest, resp.Code) + }) + + t.Run("facade returns error", func(t *testing.T) { + t.Parallel() + + facade := mockFacade.GuardianFacadeStub{ + GetSecurityStatusCalled: func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + return &requests.UserStatusResponse{SecurityStatus: -1}, expectedError + }, + } + + gg, _ := groups.NewGuardianGroup(&facade) + + ws := startWebServer(gg, "guardian", getServiceRoutesConfig(), providedAddr) + + request := requests.UserStatusRequest{ + UserAddr: providedAddr, + } + req, _ := http.NewRequest("GET", "/guardian/security-status", requestToReader(request)) + resp := httptest.NewRecorder() + ws.ServeHTTP(resp, req) + + statusRsp := generalResponse{} + loadResponse(resp.Body, &statusRsp) + + expectedGenResponse := createExpectedGeneralResponse(&requests.UserStatusResponse{ + SecurityStatus: -1, + }, "") + + assert.Equal(t, expectedGenResponse.Data, statusRsp.Data) + assert.True(t, strings.Contains(statusRsp.Error, expectedError.Error())) + require.Equal(t, http.StatusInternalServerError, resp.Code) + }) + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + facade := mockFacade.GuardianFacadeStub{ + GetSecurityStatusCalled: func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + return &requests.UserStatusResponse{ + SecurityStatus: 1, + }, nil + }, + } + + gg, _ := groups.NewGuardianGroup(&facade) + + ws := startWebServer(gg, "guardian", getServiceRoutesConfig(), providedAddr) + + request := requests.SecurityModeNoExpire{ + UserAddr: providedAddr, + } + req, _ := http.NewRequest("GET", "/guardian/security-status", requestToReader(request)) + resp := httptest.NewRecorder() + ws.ServeHTTP(resp, req) + + statusRsp := generalResponse{} + loadResponse(resp.Body, &statusRsp) + + expectedGenResponse := createExpectedGeneralResponse(&requests.UserStatusResponse{ + SecurityStatus: 1, + }, "") + + assert.Equal(t, expectedGenResponse.Data, statusRsp.Data) + assert.Equal(t, "", statusRsp.Error) + require.Equal(t, http.StatusOK, resp.Code) + }) +} + func TestGuardianGroup_signMultipleTransaction(t *testing.T) { t.Parallel() diff --git a/cmd/multi-factor-auth/config/api.toml b/cmd/multi-factor-auth/config/api.toml index ec02bf86..2a5a6acf 100644 --- a/cmd/multi-factor-auth/config/api.toml +++ b/cmd/multi-factor-auth/config/api.toml @@ -21,6 +21,7 @@ RestApiInterface = ":8080" # The interface `address and port` to which the REST { Name = "/sign-multiple-transactions", Open = true, Auth = false, MaxContentLength = 1500000 }, { Name = "/set-security-mode", Open = true, Auth = false, MaxContentLength = 200 }, { Name = "/unset-security-mode", Open = true, Auth = false, MaxContentLength = 200 }, + { Name = "/security-status", Open = true, Auth = false, MaxContentLength = 200 }, { Name = "/verify-code", Open = true, Auth = true, MaxContentLength = 200 }, { Name = "/registered-users", Open = true, Auth = false }, { Name = "/config", Open = true, Auth = false }, diff --git a/facade/guardianFacade_test.go b/facade/guardianFacade_test.go index cd276ea5..5ff2e426 100644 --- a/facade/guardianFacade_test.go +++ b/facade/guardianFacade_test.go @@ -113,6 +113,11 @@ func TestGuardianFacade_Getters(t *testing.T) { } wasUnsetSecurityModeNoExpireCalled := false + providedUserStatusRequest := requests.UserStatusRequest{ + UserAddr: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + } + expectedUserStatusResponse := requests.UserStatusResponse{SecurityStatus: 1} + args.ServiceResolver = &testscommon.ServiceResolverStub{ VerifyCodeCalled: func(userAddress sdkCore.AddressHandler, userIp string, request requests.VerificationPayload) (*requests.OTPCodeVerifyData, error) { assert.Equal(t, providedVerifyCodeReq, request) @@ -142,6 +147,10 @@ func TestGuardianFacade_Getters(t *testing.T) { wasUnsetSecurityModeNoExpireCalled = true return nil, nil }, + GetSecurityStatusCalled: func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + assert.Equal(t, providedUserStatusRequest, request) + return &expectedUserStatusResponse, nil + }, SignTransactionCalled: func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) { assert.Equal(t, providedIp, userIp) assert.Equal(t, providedSignTxReq, request) @@ -207,6 +216,10 @@ func TestGuardianFacade_Getters(t *testing.T) { assert.Nil(t, err) assert.True(t, wasUnsetSecurityModeNoExpireCalled) + userStatus, err := facadeInstance.GetSecurityStatus(providedUserStatusRequest) + assert.Nil(t, err) + assert.Equal(t, expectedUserStatusResponse, userStatus) + signedTxs, _, err := facadeInstance.SignMultipleTransactions(providedIp, providedSignMultipleTxsReq) assert.Nil(t, err) assert.Equal(t, expectedSignMultipleTxsResponse, signedTxs) diff --git a/go.mod b/go.mod index dfd4cbb3..394a63ba 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/multiversx/mx-multi-factor-auth-go-service -go 1.18 +go 1.21 + +toolchain go1.23.0 require ( github.com/alicebob/miniredis/v2 v2.30.3 diff --git a/handlers/secureOtp/secureOtpHandler_test.go b/handlers/secureOtp/secureOtpHandler_test.go index 4e140129..06633d06 100644 --- a/handlers/secureOtp/secureOtpHandler_test.go +++ b/handlers/secureOtp/secureOtpHandler_test.go @@ -412,6 +412,21 @@ func TestSecureOtpHandler_UnsetSecurityModeNoExpireShouldErr(t *testing.T) { require.Equal(t, expectedErr, err) } +func TestSecureOtpHandler_GetSecurityStatusShouldWork(t *testing.T) { + t.Parallel() + + args := createMockArgsSecureOtpHandler() + args.RateLimiter = &testscommon.RateLimiterStub{ + GetSecurityStatusCalled: func(key string) core.Status { + return core.NotSet + }, + } + totp, _ := secureOtp.NewSecureOtpHandler(args) + require.NotNil(t, totp) + + require.Equal(t, core.NotSet, totp.GetSecurityStatus(account)) +} + func TestSecureOtpHandler_Getters(t *testing.T) { t.Parallel() diff --git a/resolver/serviceResolver.go b/resolver/serviceResolver.go index 97ebf440..1b137b6c 100644 --- a/resolver/serviceResolver.go +++ b/resolver/serviceResolver.go @@ -292,13 +292,10 @@ func (resolver *serviceResolver) UnsetSecurityModeNoExpire(userIp string, reques // GetSecurityStatus gets the user's security status func (resolver *serviceResolver) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { status, err := resolver.verifyUserReturningSecurityStatus(request.UserAddr) - if err != nil { - return &requests.UserStatusResponse{}, err - } return &requests.UserStatusResponse{ SecurityStatus: int(status), - }, nil + }, err } // SignTransaction validates user's transaction, then adds guardian signature and returns the transaction @@ -508,7 +505,7 @@ func (resolver *serviceResolver) verifyUserReturningSecurityStatus(userAddr stri _, err = resolver.getUserInfo(addressBytes) resolver.userCritSection.RUnlock(string(addressBytes)) if err != nil { - return -1, nil + return -1, err } return resolver.secureOtpHandler.GetSecurityStatus(userAddr), nil diff --git a/resolver/serviceResolver_test.go b/resolver/serviceResolver_test.go index d1bd50c2..d88c0e2d 100644 --- a/resolver/serviceResolver_test.go +++ b/resolver/serviceResolver_test.go @@ -2735,6 +2735,134 @@ func TestServiceResolver_UnsetSecurityModeNoExpire(t *testing.T) { } +func TestServiceResolver_GetSecurityStatus(t *testing.T) { + t.Parallel() + + providedSender := "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" + providedRequest := requests.UserStatusRequest{ + UserAddr: providedSender, + } + + t.Run("should return err because of getUserInfo", func(t *testing.T) { + t.Parallel() + providedRequestCopy := providedRequest + + args := createMockArgs() + args.RegisteredUsersDB = &testscommon.ShardedStorageWithIndexStub{ + GetCalled: func(key []byte) ([]byte, error) { + return nil, expectedErr + }, + } + + resolver, _ := NewServiceResolver(args) + assert.NotNil(t, resolver) + + expectedStatus := &requests.UserStatusResponse{ + SecurityStatus: -1, + } + statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + + assert.Equal(t, expectedStatus, statusReturned) + assert.Equal(t, expectedErr, err) + }) + + t.Run("should return 0", func(t *testing.T) { + t.Parallel() + providedRequestCopy := providedRequest + providedUserInfoCopy := *providedUserInfo + + args := createMockArgs() + args.RegisteredUsersDB = &testscommon.ShardedStorageWithIndexStub{ + GetCalled: func(key []byte) ([]byte, error) { + encryptedUser, err := args.UserEncryptor.EncryptUserInfo(&providedUserInfoCopy) + require.Nil(t, err) + return args.UserDataMarshaller.Marshal(encryptedUser) + }, + } + + args.SecureOtpHandler = &testscommon.SecureOtpHandlerStub{ + GetSecurityStatusCalled: func(key string) core.Status { + return core.NotSet + }, + } + + resolver, _ := NewServiceResolver(args) + assert.NotNil(t, resolver) + + expectedStatus := &requests.UserStatusResponse{ + SecurityStatus: 0, + } + statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + + assert.Nil(t, err) + assert.Equal(t, expectedStatus, statusReturned) + }) + + t.Run("should return 1", func(t *testing.T) { + t.Parallel() + providedRequestCopy := providedRequest + providedUserInfoCopy := *providedUserInfo + + args := createMockArgs() + args.RegisteredUsersDB = &testscommon.ShardedStorageWithIndexStub{ + GetCalled: func(key []byte) ([]byte, error) { + encryptedUser, err := args.UserEncryptor.EncryptUserInfo(&providedUserInfoCopy) + require.Nil(t, err) + return args.UserDataMarshaller.Marshal(encryptedUser) + }, + } + + args.SecureOtpHandler = &testscommon.SecureOtpHandlerStub{ + GetSecurityStatusCalled: func(key string) core.Status { + return core.ManualSet + }, + } + + resolver, _ := NewServiceResolver(args) + assert.NotNil(t, resolver) + + expectedStatus := &requests.UserStatusResponse{ + SecurityStatus: 1, + } + statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + + assert.Nil(t, err) + assert.Equal(t, expectedStatus, statusReturned) + }) + + t.Run("should return 2", func(t *testing.T) { + t.Parallel() + providedRequestCopy := providedRequest + providedUserInfoCopy := *providedUserInfo + + args := createMockArgs() + args.RegisteredUsersDB = &testscommon.ShardedStorageWithIndexStub{ + GetCalled: func(key []byte) ([]byte, error) { + encryptedUser, err := args.UserEncryptor.EncryptUserInfo(&providedUserInfoCopy) + require.Nil(t, err) + return args.UserDataMarshaller.Marshal(encryptedUser) + }, + } + + args.SecureOtpHandler = &testscommon.SecureOtpHandlerStub{ + GetSecurityStatusCalled: func(key string) core.Status { + return core.AutomaticallySet + }, + } + + resolver, _ := NewServiceResolver(args) + assert.NotNil(t, resolver) + + expectedStatus := &requests.UserStatusResponse{ + SecurityStatus: 2, + } + statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + + assert.Nil(t, err) + assert.Equal(t, expectedStatus, statusReturned) + }) +} + func TestServiceResolver_SignMultipleTransactions(t *testing.T) { t.Parallel() From 2c4b6c6561c3b2d10745d9bf7af9c88a64f22fb3 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Fri, 2 May 2025 12:13:32 +0300 Subject: [PATCH 04/19] fix --- facade/guardianFacade_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/facade/guardianFacade_test.go b/facade/guardianFacade_test.go index 5ff2e426..5c70352f 100644 --- a/facade/guardianFacade_test.go +++ b/facade/guardianFacade_test.go @@ -218,7 +218,7 @@ func TestGuardianFacade_Getters(t *testing.T) { userStatus, err := facadeInstance.GetSecurityStatus(providedUserStatusRequest) assert.Nil(t, err) - assert.Equal(t, expectedUserStatusResponse, userStatus) + assert.Equal(t, &expectedUserStatusResponse, userStatus) signedTxs, _, err := facadeInstance.SignMultipleTransactions(providedIp, providedSignMultipleTxsReq) assert.Nil(t, err) From 64c67ab1f78353945e285ed6efab3eaeee0fdfe7 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Fri, 2 May 2025 12:16:47 +0300 Subject: [PATCH 05/19] fix go.mod --- go.mod | 4 +-- go.sum | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 394a63ba..dfd4cbb3 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/multiversx/mx-multi-factor-auth-go-service -go 1.21 - -toolchain go1.23.0 +go 1.18 require ( github.com/alicebob/miniredis/v2 v2.30.3 diff --git a/go.sum b/go.sum index f5c89227..34e7f0e9 100644 --- a/go.sum +++ b/go.sum @@ -9,9 +9,13 @@ github.com/alicebob/miniredis/v2 v2.30.3/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6u github.com/beevik/ntp v1.3.0 h1:/w5VhpW5BGKS37vFm1p9oVk/t4HnnkKZAZIubHM6F7Q= github.com/beevik/ntp v1.3.0/go.mod h1:vD6h1um4kzXpqmLTuu0cCLcC+NfvC0IC+ltmEDA8E78= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= +github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= +github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= @@ -46,7 +50,9 @@ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -55,18 +61,24 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= @@ -86,10 +98,14 @@ github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -104,13 +120,16 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -135,8 +154,10 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -145,23 +166,37 @@ github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlI github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/herumi/bls-go-binary v1.28.2 h1:F0AezsC0M1a9aZjk7g0l2hMb1F56Xtpfku97pDndNZE= +github.com/herumi/bls-go-binary v1.28.2/go.mod h1:O4Vp1AfR4raRGwFeQpr9X/PQtncEicMoOe6BQt1oX0Y= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= +github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= +github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -179,6 +214,7 @@ github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuV github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -193,20 +229,35 @@ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ic github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.28.2 h1:lO/g0ccVru6nUVHyLE7C1VRr7B2AFp9cvHhf+l+Te6w= +github.com/libp2p/go-libp2p v0.28.2/go.mod h1:fOLgCNgLiWFdmtXyQBwmuCpukaYOA+yw4rnBiScDNmI= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= +github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= +github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= +github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= +github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= +github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= +github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -214,9 +265,13 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -228,15 +283,25 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= +github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= +github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUYwbO0993uPI= github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o= github.com/multiversx/mx-chain-communication-go v1.1.1 h1:y4DoQeQOJTaSUsRzczQFazf8JYQmInddypApqA3AkwM= @@ -269,6 +334,7 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -278,8 +344,11 @@ github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9 github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= @@ -293,24 +362,34 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= +github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us= github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= +github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/redis/go-redis/v9 v9.0.4 h1:FC82T+CHJ/Q/PdyLW++GeCO+Ol59Y4T7R4jbgjvktgc= github.com/redis/go-redis/v9 v9.0.4/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sec51/convert v1.0.2 h1:NoKWIRARjM3rQglNypMpcXSLLqPsN/uTTzaGeqDKbeg= @@ -320,7 +399,9 @@ github.com/sec51/gf256 v0.0.0-20160126143050-2454accbeb9e/go.mod h1:hCjOqSOB9PBw github.com/sec51/qrcode v0.0.0-20160126144534-b7779abbcaf1 h1:CI9zS8HvMiibvXM/F3IthY797GW77fNYgioJl/8Xzzk= github.com/sec51/qrcode v0.0.0-20160126144534-b7779abbcaf1/go.mod h1:uPm44Rj3uXSSOvmKmoeRuAUNUgwH2JHW5KIzqFFS/j4= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -343,8 +424,11 @@ github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDd github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= @@ -358,7 +442,9 @@ github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= @@ -373,16 +459,25 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= +go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= +go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= @@ -397,11 +492,13 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -484,12 +581,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -520,5 +619,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= From 45770319026682e9c7a9f2668b3756de2f31f5a2 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Fri, 2 May 2025 17:34:00 +0300 Subject: [PATCH 06/19] added getter for value of redis key and consider --- integrationTests/otpRateLimiting_test.go | 68 +++++++++++++++++++++- redis/interface.go | 1 + redis/redisClient.go | 13 +++++ redis/redisClient_test.go | 8 +++ redis/redisLimiter.go | 22 +++++-- redis/redisLimiter_test.go | 73 +++++++++++++++++++++--- testscommon/redisClientStub.go | 9 +++ 7 files changed, 181 insertions(+), 13 deletions(-) diff --git a/integrationTests/otpRateLimiting_test.go b/integrationTests/otpRateLimiting_test.go index f7b3a1b4..61a8fa16 100644 --- a/integrationTests/otpRateLimiting_test.go +++ b/integrationTests/otpRateLimiting_test.go @@ -421,12 +421,14 @@ func TestSecurityMode(t *testing.T) { securityModePeriodLimit := 86400 t.Run("test set security mode", func(t *testing.T) { - secureOtpHandler, redisServer := createRateLimiter(t, maxFailures, periodLimit, securityModeMaxFailures, securityModePeriodLimit) userAddress := "addr2" userIp := "ip2" + status := secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err := secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData := &requests.OTPCodeVerifyData{ @@ -437,6 +439,9 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + err = secureOtpHandler.SetSecurityModeNoExpire(userAddress) require.Nil(t, err) @@ -451,6 +456,9 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) + redisServer.FastForward(time.Second * time.Duration(expOtpVerifyData.ResetAfter)) otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) @@ -461,6 +469,10 @@ func TestSecurityMode(t *testing.T) { SecurityModeResetAfter: -1, } require.Equal(t, expOtpVerifyData, otpVerifyData) + + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) + }) t.Run("test unset when security mode is activated by user", func(t *testing.T) { @@ -469,6 +481,9 @@ func TestSecurityMode(t *testing.T) { userAddress := "addr2" userIp := "ip2" + status := secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err := secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData := &requests.OTPCodeVerifyData{ @@ -482,6 +497,9 @@ func TestSecurityMode(t *testing.T) { err = secureOtpHandler.SetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -492,9 +510,15 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) + err = secureOtpHandler.UnsetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -513,6 +537,9 @@ func TestSecurityMode(t *testing.T) { userAddress := "addr2" userIp := "ip2" + status := secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err := secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData := &requests.OTPCodeVerifyData{ @@ -523,6 +550,9 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -533,6 +563,9 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -543,6 +576,9 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.AutomaticallySet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.NotNil(t, otpVerifyData) require.Equal(t, core.ErrTooManyFailedAttempts, err) @@ -550,6 +586,9 @@ func TestSecurityMode(t *testing.T) { err = secureOtpHandler.UnsetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.AutomaticallySet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.NotNil(t, otpVerifyData) require.Equal(t, core.ErrTooManyFailedAttempts, err) @@ -571,9 +610,15 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status := secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + err = secureOtpHandler.SetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) + redisServer.FastForward(time.Second * time.Duration(expOtpVerifyData.ResetAfter)) otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) @@ -588,6 +633,9 @@ func TestSecurityMode(t *testing.T) { err = secureOtpHandler.SetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -597,6 +645,9 @@ func TestSecurityMode(t *testing.T) { SecurityModeResetAfter: -1, } require.Equal(t, expOtpVerifyData, otpVerifyData) + + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) }) t.Run("test unset multiple times", func(t *testing.T) { @@ -615,9 +666,15 @@ func TestSecurityMode(t *testing.T) { } require.Equal(t, expOtpVerifyData, otpVerifyData) + status := secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + err = secureOtpHandler.SetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.ManualSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -631,6 +688,9 @@ func TestSecurityMode(t *testing.T) { err = secureOtpHandler.UnsetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -644,6 +704,9 @@ func TestSecurityMode(t *testing.T) { err = secureOtpHandler.UnsetSecurityModeNoExpire(userAddress) require.Nil(t, err) + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.NotSet, status) + otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Equal(t, core.ErrTooManyFailedAttempts, err) expOtpVerifyData = &requests.OTPCodeVerifyData{ @@ -653,6 +716,9 @@ func TestSecurityMode(t *testing.T) { SecurityModeResetAfter: 86400, } require.Equal(t, expOtpVerifyData, otpVerifyData) + + status = secureOtpHandler.GetSecurityStatus(userAddress) + require.Equal(t, core.AutomaticallySet, status) }) } diff --git a/redis/interface.go b/redis/interface.go index 7ef3630b..98a26abf 100644 --- a/redis/interface.go +++ b/redis/interface.go @@ -38,6 +38,7 @@ type RedisStorer interface { SetExpireIfNotExists(ctx context.Context, key string, ttl time.Duration) (bool, error) SetPersist(ctx context.Context, key string) (bool, error) SetGreaterExpireTTL(ctx context.Context, key string, ttl time.Duration) (bool, error) + Get(ctx context.Context, key string) (string, error) ResetCounterAndKeepTTL(ctx context.Context, key string) error ExpireTime(ctx context.Context, key string) (time.Duration, error) IsConnected(ctx context.Context) bool diff --git a/redis/redisClient.go b/redis/redisClient.go index d5963cf3..ebe7e414 100644 --- a/redis/redisClient.go +++ b/redis/redisClient.go @@ -2,6 +2,7 @@ package redis import ( "context" + "errors" "time" "github.com/redis/go-redis/v9" @@ -37,6 +38,18 @@ func (r *redisClientWrapper) Decrement(ctx context.Context, key string) (int64, return r.client.Decr(ctx, key).Result() } +func (r *redisClientWrapper) Get(ctx context.Context, key string) (string, error) { + val, err := r.client.Get(ctx, key).Result() + if errors.Is(err, redis.Nil) { + return "", ErrKeyNotExists + } + if err != nil { + return "", err + } + + return val, nil +} + // SetExpire will run expire for the specified key, setting the specified ttl func (r *redisClientWrapper) SetExpire(ctx context.Context, key string, ttl time.Duration) (bool, error) { return r.client.Expire(ctx, key, ttl).Result() diff --git a/redis/redisClient_test.go b/redis/redisClient_test.go index c0f63ff9..fb3259ae 100644 --- a/redis/redisClient_test.go +++ b/redis/redisClient_test.go @@ -86,6 +86,14 @@ func TestOperations(t *testing.T) { require.Nil(t, err) require.Equal(t, int64(2), retries) + value, err := rcw.Get(context.TODO(), "key1") + require.Nil(t, err) + require.Equal(t, "2", value) + + value, err = rcw.Get(context.TODO(), "invalidKey") + require.Equal(t, redis.ErrKeyNotExists, err) + require.Equal(t, "", value) + wasSet, err = rcw.SetPersist(context.TODO(), "key1") require.Nil(t, err) require.True(t, wasSet) diff --git a/redis/redisLimiter.go b/redis/redisLimiter.go index de3305de..aa2b236b 100644 --- a/redis/redisLimiter.go +++ b/redis/redisLimiter.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strconv" "sync" "time" @@ -224,15 +225,28 @@ func (rl *rateLimiter) GetSecurityStatus(key string) core.Status { } func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) core.Status { - expTime, err := rl.storer.ExpireTime(ctx, key) + _, maxFailures := rl.getFailConfig(SecurityMode) + + dbVal, err := rl.storer.Get(ctx, key) if errors.Is(err, ErrKeyNotExists) { return core.NotSet } - if expTime == core.NoExpiryValue { - return core.ManualSet + + expTime, err := rl.storer.ExpireTime(ctx, key) + if err != nil { + return core.NotSet + } + + trials, err := strconv.ParseInt(dbVal, 10, 64) + if trials < maxFailures && expTime != core.NoExpiryValue { + return core.NotSet + } + + if trials >= maxFailures && expTime != core.NoExpiryValue { + return core.AutomaticallySet } - return core.AutomaticallySet + return core.ManualSet } // UnsetSecurityModeNoExpire will set the key from persistent to volatile diff --git a/redis/redisLimiter_test.go b/redis/redisLimiter_test.go index 897e2cfd..6c15b312 100644 --- a/redis/redisLimiter_test.go +++ b/redis/redisLimiter_test.go @@ -511,13 +511,13 @@ func TestUnsetSecurityModeNoExpire(t *testing.T) { func TestGetSecurityStatus(t *testing.T) { t.Parallel() - t.Run("should return NotSet", func(t *testing.T) { + t.Run("should return NotSet because ErrKeyNotExists", func(t *testing.T) { t.Parallel() args := createMockRateLimiterArgs() redisClient := &testscommon.RedisClientStub{ - ExpireTimeCalled: func(ctx context.Context, key string) (time.Duration, error) { - return 0, redis.ErrKeyNotExists + GetCalled: func(ctx context.Context, key string) (string, error) { + return "", redis.ErrKeyNotExists }, } args.Storer = redisClient @@ -529,13 +529,26 @@ func TestGetSecurityStatus(t *testing.T) { require.Equal(t, core.NotSet, actualStatus) }) - t.Run("should return ManualSet", func(t *testing.T) { + t.Run("should return NotSet because security mode wasn't activate neither manually or automatically", func(t *testing.T) { t.Parallel() + maxFailures := 3 + maxDuration := 9 + securityModeMaxFailures := 100 + securityModeMaxDuration := 86400 + args := createMockRateLimiterArgs() + args.FreezeFailureConfig.MaxFailures = int64(maxFailures) + args.FreezeFailureConfig.LimitPeriodInSec = uint64(maxDuration) + args.SecurityModeFailureConfig.MaxFailures = int64(securityModeMaxFailures) + args.SecurityModeFailureConfig.LimitPeriodInSec = uint64(securityModeMaxDuration) + redisClient := &testscommon.RedisClientStub{ ExpireTimeCalled: func(ctx context.Context, key string) (time.Duration, error) { - return -1, nil + return time.Duration(securityModeMaxDuration), nil + }, + GetCalled: func(ctx context.Context, key string) (string, error) { + return "99", nil }, } args.Storer = redisClient @@ -544,16 +557,29 @@ func TestGetSecurityStatus(t *testing.T) { require.Nil(t, err) actualStatus := rl.GetSecurityStatus("key") - require.Equal(t, core.ManualSet, actualStatus) + require.Equal(t, core.NotSet, actualStatus) }) - t.Run("should return AutomaticallySet", func(t *testing.T) { + t.Run("should return Automatically set when failures is exceeded", func(t *testing.T) { t.Parallel() + maxFailures := 3 + maxDuration := 9 + securityModeMaxFailures := 100 + securityModeMaxDuration := 86400 + args := createMockRateLimiterArgs() + args.FreezeFailureConfig.MaxFailures = int64(maxFailures) + args.FreezeFailureConfig.LimitPeriodInSec = uint64(maxDuration) + args.SecurityModeFailureConfig.MaxFailures = int64(securityModeMaxFailures) + args.SecurityModeFailureConfig.LimitPeriodInSec = uint64(securityModeMaxDuration) + redisClient := &testscommon.RedisClientStub{ ExpireTimeCalled: func(ctx context.Context, key string) (time.Duration, error) { - return 10, nil + return time.Duration(securityModeMaxDuration), nil + }, + GetCalled: func(ctx context.Context, key string) (string, error) { + return "100", nil }, } args.Storer = redisClient @@ -564,6 +590,37 @@ func TestGetSecurityStatus(t *testing.T) { actualStatus := rl.GetSecurityStatus("key") require.Equal(t, core.AutomaticallySet, actualStatus) }) + + t.Run("should return Manual set when key is persistent", func(t *testing.T) { + t.Parallel() + + maxFailures := 3 + maxDuration := 9 + securityModeMaxFailures := 100 + securityModeMaxDuration := 86400 + + args := createMockRateLimiterArgs() + args.FreezeFailureConfig.MaxFailures = int64(maxFailures) + args.FreezeFailureConfig.LimitPeriodInSec = uint64(maxDuration) + args.SecurityModeFailureConfig.MaxFailures = int64(securityModeMaxFailures) + args.SecurityModeFailureConfig.LimitPeriodInSec = uint64(securityModeMaxDuration) + + redisClient := &testscommon.RedisClientStub{ + ExpireTimeCalled: func(ctx context.Context, key string) (time.Duration, error) { + return -1, nil + }, + GetCalled: func(ctx context.Context, key string) (string, error) { + return "100", nil + }, + } + args.Storer = redisClient + + rl, err := redis.NewRateLimiter(args) + require.Nil(t, err) + + actualStatus := rl.GetSecurityStatus("key") + require.Equal(t, core.ManualSet, actualStatus) + }) } func TestDecrementSecurityFailedTrials(t *testing.T) { diff --git a/testscommon/redisClientStub.go b/testscommon/redisClientStub.go index cde47dd1..0743f8ec 100644 --- a/testscommon/redisClientStub.go +++ b/testscommon/redisClientStub.go @@ -9,6 +9,7 @@ import ( type RedisClientStub struct { IncrementCalled func(ctx context.Context, key string) (int64, error) DecrementCalled func(ctx context.Context, key string) (int64, error) + GetCalled func(ctx context.Context, key string) (string, error) SetExpireCalled func(ctx context.Context, key string, ttl time.Duration) (bool, error) SetExpireIfNotExistsCalled func(ctx context.Context, key string, ttl time.Duration) (bool, error) SetPersistCalled func(ctx context.Context, key string) (bool, error) @@ -35,6 +36,14 @@ func (r *RedisClientStub) Decrement(ctx context.Context, key string) (int64, err return 0, nil } +// Get - +func (r *RedisClientStub) Get(ctx context.Context, key string) (string, error) { + if r.GetCalled != nil { + return r.GetCalled(ctx, key) + } + return "", nil +} + // SetExpire - func (r *RedisClientStub) SetExpire(ctx context.Context, key string, ttl time.Duration) (bool, error) { if r.SetExpireCalled != nil { From bec08bc81bec60c437aa4b7ba7b4f2333ef5fd69 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Fri, 2 May 2025 17:37:33 +0300 Subject: [PATCH 07/19] linter fix --- redis/redisLimiter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis/redisLimiter.go b/redis/redisLimiter.go index aa2b236b..4535196a 100644 --- a/redis/redisLimiter.go +++ b/redis/redisLimiter.go @@ -237,7 +237,7 @@ func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) core.S return core.NotSet } - trials, err := strconv.ParseInt(dbVal, 10, 64) + trials, _ := strconv.ParseInt(dbVal, 10, 64) if trials < maxFailures && expTime != core.NoExpiryValue { return core.NotSet } From 44790bf25e3cc5ff6a817b8f6dc1491658393a47 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Mon, 5 May 2025 10:12:46 +0300 Subject: [PATCH 08/19] small fix --- core/requests/types.go | 2 +- facade/guardianFacade.go | 2 +- redis/redisClient.go | 1 + redis/redisLimiter_test.go | 8 ++++---- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/core/requests/types.go b/core/requests/types.go index b584aad8..bb3e91c3 100644 --- a/core/requests/types.go +++ b/core/requests/types.go @@ -32,7 +32,7 @@ type UserStatusRequest struct { // UserStatusResponse - is the JSON response for the user status interrogation type UserStatusResponse struct { - SecurityStatus int `json:"code"` + SecurityStatus int `json:"status"` } // SignMessageResponse is the service response to the sign message request diff --git a/facade/guardianFacade.go b/facade/guardianFacade.go index 88b8963e..37983fbe 100644 --- a/facade/guardianFacade.go +++ b/facade/guardianFacade.go @@ -65,7 +65,7 @@ func (gf *guardianFacade) UnsetSecurityModeNoExpire(userIp string, request reque return gf.serviceResolver.UnsetSecurityModeNoExpire(userIp, request) } -// GetSecurityStatus gets the user's security status +// GetSecurityStatus returns the user's security status func (gf *guardianFacade) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { return gf.serviceResolver.GetSecurityStatus(request) } diff --git a/redis/redisClient.go b/redis/redisClient.go index ebe7e414..03a11e63 100644 --- a/redis/redisClient.go +++ b/redis/redisClient.go @@ -38,6 +38,7 @@ func (r *redisClientWrapper) Decrement(ctx context.Context, key string) (int64, return r.client.Decr(ctx, key).Result() } +// Get will return the value corresponding to the specified key func (r *redisClientWrapper) Get(ctx context.Context, key string) (string, error) { val, err := r.client.Get(ctx, key).Result() if errors.Is(err, redis.Nil) { diff --git a/redis/redisLimiter_test.go b/redis/redisLimiter_test.go index 6c15b312..909972a7 100644 --- a/redis/redisLimiter_test.go +++ b/redis/redisLimiter_test.go @@ -529,7 +529,7 @@ func TestGetSecurityStatus(t *testing.T) { require.Equal(t, core.NotSet, actualStatus) }) - t.Run("should return NotSet because security mode wasn't activate neither manually or automatically", func(t *testing.T) { + t.Run("should return NotSet because security mode wasn't activate neither manually nor automatically", func(t *testing.T) { t.Parallel() maxFailures := 3 @@ -548,7 +548,7 @@ func TestGetSecurityStatus(t *testing.T) { return time.Duration(securityModeMaxDuration), nil }, GetCalled: func(ctx context.Context, key string) (string, error) { - return "99", nil + return string(rune(securityModeMaxFailures - 1)), nil }, } args.Storer = redisClient @@ -579,7 +579,7 @@ func TestGetSecurityStatus(t *testing.T) { return time.Duration(securityModeMaxDuration), nil }, GetCalled: func(ctx context.Context, key string) (string, error) { - return "100", nil + return string(rune(securityModeMaxFailures)), nil }, } args.Storer = redisClient @@ -610,7 +610,7 @@ func TestGetSecurityStatus(t *testing.T) { return -1, nil }, GetCalled: func(ctx context.Context, key string) (string, error) { - return "100", nil + return string(rune(securityModeMaxFailures)), nil }, } args.Storer = redisClient From 27d71fe87c40d1be8bbca7bb511e7a24c9db5642 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Mon, 5 May 2025 10:25:10 +0300 Subject: [PATCH 09/19] fixes and swagger --- cmd/multi-factor-auth/swagger/data.go | 28 +++++++++++++++++++++++++++ redis/redisLimiter_test.go | 7 ++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/cmd/multi-factor-auth/swagger/data.go b/cmd/multi-factor-auth/swagger/data.go index 27aeffe0..b66bbcfd 100644 --- a/cmd/multi-factor-auth/swagger/data.go +++ b/cmd/multi-factor-auth/swagger/data.go @@ -289,3 +289,31 @@ type _ struct { // required:true Payload requests.SecurityModeNoExpire } + +// swagger:route GET /security-status Guardian getSecurityStatus +// Returns the security status. +// This request does not need the Authorization header +// +// responses: +// 200: userStatusResponse + +// The status of the operation +// swagger:response userStatusResponse +type _ struct { + // in:body + Body struct { + // UserStatusResponse + // HTTP status code + Status string `json:"status"` + // Internal error + Error string `json:"error"` + } +} + +// swagger:parameters userStatusRequest +type _ struct { + // UserStatusRequest payload + // in:body + // required:true + Payload requests.UserStatusRequest +} diff --git a/redis/redisLimiter_test.go b/redis/redisLimiter_test.go index 909972a7..0545208f 100644 --- a/redis/redisLimiter_test.go +++ b/redis/redisLimiter_test.go @@ -3,6 +3,7 @@ package redis_test import ( "context" "errors" + "strconv" "sync" "testing" "time" @@ -548,7 +549,7 @@ func TestGetSecurityStatus(t *testing.T) { return time.Duration(securityModeMaxDuration), nil }, GetCalled: func(ctx context.Context, key string) (string, error) { - return string(rune(securityModeMaxFailures - 1)), nil + return strconv.Itoa(securityModeMaxFailures - 1), nil }, } args.Storer = redisClient @@ -579,7 +580,7 @@ func TestGetSecurityStatus(t *testing.T) { return time.Duration(securityModeMaxDuration), nil }, GetCalled: func(ctx context.Context, key string) (string, error) { - return string(rune(securityModeMaxFailures)), nil + return strconv.Itoa(securityModeMaxFailures), nil }, } args.Storer = redisClient @@ -610,7 +611,7 @@ func TestGetSecurityStatus(t *testing.T) { return -1, nil }, GetCalled: func(ctx context.Context, key string) (string, error) { - return string(rune(securityModeMaxFailures)), nil + return strconv.Itoa(securityModeMaxFailures), nil }, } args.Storer = redisClient From 7c9c4d3103630e7d5b3eba6490492c4940320b8d Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Mon, 5 May 2025 17:29:57 +0300 Subject: [PATCH 10/19] fixes after review --- api/groups/common_test.go | 2 +- api/groups/guardianGroup.go | 27 +++--- api/groups/guardianGroup_test.go | 33 +------- api/shared/interface.go | 2 +- cmd/multi-factor-auth/config/api.toml | 2 +- cmd/multi-factor-auth/swagger/data.go | 12 +-- core/constants.go | 6 +- core/interface.go | 2 +- core/requests/types.go | 8 +- facade/guardianFacade.go | 6 +- facade/guardianFacade_test.go | 11 ++- go.sum | 100 ----------------------- handlers/secureOtp/secureOtpHandler.go | 2 +- integrationTests/otpRateLimiting_test.go | 16 ++-- redis/redisLimiter.go | 14 +++- redis/redisLimiter_test.go | 2 +- resolver/serviceResolver.go | 10 +-- resolver/serviceResolver_test.go | 17 ++-- testscommon/facade/guardianFacadeStub.go | 6 +- testscommon/rateLimiterMock.go | 2 +- testscommon/rateLimiterStub.go | 2 +- testscommon/serviceResolverStub.go | 6 +- 22 files changed, 73 insertions(+), 215 deletions(-) diff --git a/api/groups/common_test.go b/api/groups/common_test.go index eeb42bc8..f50e148d 100644 --- a/api/groups/common_test.go +++ b/api/groups/common_test.go @@ -48,7 +48,7 @@ func getServiceRoutesConfig() config.ApiRoutesConfig { {Name: "/sign-multiple-transactions", Open: true}, {Name: "/set-security-mode", Open: true}, {Name: "/unset-security-mode", Open: true}, - {Name: "/security-status", Open: true}, + {Name: "/user-status/:address", Open: true}, {Name: "/debug", Open: true}, {Name: "/verify-code", Open: true}, {Name: "/registered-users", Open: true}, diff --git a/api/groups/guardianGroup.go b/api/groups/guardianGroup.go index 8ec7646b..bde9a35b 100644 --- a/api/groups/guardianGroup.go +++ b/api/groups/guardianGroup.go @@ -30,7 +30,7 @@ const ( signMultipleTransactionsPath = "/sign-multiple-transactions" setSecurityModeNoExpirePath = "/set-security-mode" unsetSecurityModeNoExpirePath = "/unset-security-mode" - getSecurityStatus = "/security-status" + getUserStatusPath = "/user-status/:address" registerPath = "/register" verifyCodePath = "/verify-code" registeredUsersPath = "/registered-users" @@ -105,9 +105,9 @@ func NewGuardianGroup(facade shared.FacadeHandler) (*guardianGroup, error) { Handler: gg.config, }, { - Path: getSecurityStatus, + Path: getUserStatusPath, Method: http.MethodGet, - Handler: gg.getSecurityStatus, + Handler: gg.getUserStatus, }, } gg.endpoints = endpoints @@ -243,23 +243,18 @@ func (gg *guardianGroup) unsetSecurityModeNoExpire(c *gin.Context) { returnStatus(c, nil, http.StatusOK, "", chainApiShared.ReturnCodeSuccess) } -func (gg *guardianGroup) getSecurityStatus(c *gin.Context) { - var request requests.UserStatusRequest +func (gg *guardianGroup) getUserStatus(c *gin.Context) { var debugErr error userIp := c.GetString(mfaMiddleware.UserIpKey) userAgent := c.GetString(mfaMiddleware.UserAgentKey) + userAddr := c.Param("address") + defer func() { - logUserStatusRequest(userIp, userAgent, &request, debugErr) + logUserStatusRequest(userIp, userAgent, userAddr, debugErr) }() - err := json.NewDecoder(c.Request.Body).Decode(&request) - if err != nil { - debugErr = fmt.Errorf("%w while decoding request", err) - returnStatus(c, nil, http.StatusBadRequest, err.Error(), chainApiShared.ReturnCodeRequestError) - return - } - status, err := gg.facade.GetSecurityStatus(request) + status, err := gg.facade.GetUserStatus(userAddr) if err != nil { debugErr = fmt.Errorf("%w while interrogating security status", err) handleErrorAndReturn(c, status, err.Error()) @@ -270,12 +265,12 @@ func (gg *guardianGroup) getSecurityStatus(c *gin.Context) { returnStatus(c, status, http.StatusOK, "", chainApiShared.ReturnCodeSuccess) } -func logUserStatusRequest(userIp string, userAgent string, request *requests.UserStatusRequest, debugErr error) { +func logUserStatusRequest(userIp string, userAgent string, userAddr string, debugErr error) { logArgs := []interface{}{ - "route", getSecurityStatus, + "route", getUserStatusPath, "ip", userIp, "user agent", userAgent, - "userAddr", getPrintableData(request.UserAddr), + "userAddr", userAddr, } defer func() { guardianLog.Info("Request info", logArgs...) diff --git a/api/groups/guardianGroup_test.go b/api/groups/guardianGroup_test.go index 319fac38..55b13b9d 100644 --- a/api/groups/guardianGroup_test.go +++ b/api/groups/guardianGroup_test.go @@ -519,30 +519,11 @@ func TestGuardianGroup_UnsetSecurityModeNoExpire(t *testing.T) { func TestGuardianGroup_getSecurityStatus(t *testing.T) { t.Parallel() - t.Run("empty body", func(t *testing.T) { - t.Parallel() - - gg, _ := groups.NewGuardianGroup(&mockFacade.GuardianFacadeStub{}) - - ws := startWebServer(gg, "guardian", getServiceRoutesConfig(), providedAddr) - - req, _ := http.NewRequest("GET", "/guardian/security-status", strings.NewReader("")) - resp := httptest.NewRecorder() - ws.ServeHTTP(resp, req) - - statusRsp := generalResponse{} - loadResponse(resp.Body, &statusRsp) - - assert.Nil(t, statusRsp.Data) - assert.True(t, strings.Contains(statusRsp.Error, "EOF")) - require.Equal(t, http.StatusBadRequest, resp.Code) - }) - t.Run("facade returns error", func(t *testing.T) { t.Parallel() facade := mockFacade.GuardianFacadeStub{ - GetSecurityStatusCalled: func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + GetSecurityStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { return &requests.UserStatusResponse{SecurityStatus: -1}, expectedError }, } @@ -551,10 +532,7 @@ func TestGuardianGroup_getSecurityStatus(t *testing.T) { ws := startWebServer(gg, "guardian", getServiceRoutesConfig(), providedAddr) - request := requests.UserStatusRequest{ - UserAddr: providedAddr, - } - req, _ := http.NewRequest("GET", "/guardian/security-status", requestToReader(request)) + req, _ := http.NewRequest("GET", "/guardian/user-status/"+providedAddr, nil) resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) @@ -574,7 +552,7 @@ func TestGuardianGroup_getSecurityStatus(t *testing.T) { t.Parallel() facade := mockFacade.GuardianFacadeStub{ - GetSecurityStatusCalled: func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { + GetSecurityStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { return &requests.UserStatusResponse{ SecurityStatus: 1, }, nil @@ -585,10 +563,7 @@ func TestGuardianGroup_getSecurityStatus(t *testing.T) { ws := startWebServer(gg, "guardian", getServiceRoutesConfig(), providedAddr) - request := requests.SecurityModeNoExpire{ - UserAddr: providedAddr, - } - req, _ := http.NewRequest("GET", "/guardian/security-status", requestToReader(request)) + req, _ := http.NewRequest("GET", "/guardian/user-status/"+providedAddr, nil) resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) diff --git a/api/shared/interface.go b/api/shared/interface.go index 91d5908a..110bf477 100644 --- a/api/shared/interface.go +++ b/api/shared/interface.go @@ -28,7 +28,7 @@ type FacadeHandler interface { SignMultipleTransactions(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) SetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) - GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) + GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) RegisteredUsers() (uint32, error) TcsConfig() *tcsCore.TcsConfig GetMetrics() map[string]*requests.EndpointMetricsResponse diff --git a/cmd/multi-factor-auth/config/api.toml b/cmd/multi-factor-auth/config/api.toml index 2a5a6acf..78d7fa05 100644 --- a/cmd/multi-factor-auth/config/api.toml +++ b/cmd/multi-factor-auth/config/api.toml @@ -21,7 +21,7 @@ RestApiInterface = ":8080" # The interface `address and port` to which the REST { Name = "/sign-multiple-transactions", Open = true, Auth = false, MaxContentLength = 1500000 }, { Name = "/set-security-mode", Open = true, Auth = false, MaxContentLength = 200 }, { Name = "/unset-security-mode", Open = true, Auth = false, MaxContentLength = 200 }, - { Name = "/security-status", Open = true, Auth = false, MaxContentLength = 200 }, + { Name = "/user-status/:address", Open = true, Auth = false }, { Name = "/verify-code", Open = true, Auth = true, MaxContentLength = 200 }, { Name = "/registered-users", Open = true, Auth = false }, { Name = "/config", Open = true, Auth = false }, diff --git a/cmd/multi-factor-auth/swagger/data.go b/cmd/multi-factor-auth/swagger/data.go index b66bbcfd..80065e5c 100644 --- a/cmd/multi-factor-auth/swagger/data.go +++ b/cmd/multi-factor-auth/swagger/data.go @@ -290,8 +290,8 @@ type _ struct { Payload requests.SecurityModeNoExpire } -// swagger:route GET /security-status Guardian getSecurityStatus -// Returns the security status. +// swagger:route GET /user-status Guardian getSecurityStatus +// Returns the security status of the user. // This request does not need the Authorization header // // responses: @@ -309,11 +309,3 @@ type _ struct { Error string `json:"error"` } } - -// swagger:parameters userStatusRequest -type _ struct { - // UserStatusRequest payload - // in:body - // required:true - Payload requests.UserStatusRequest -} diff --git a/core/constants.go b/core/constants.go index 7c3a2112..574def7e 100644 --- a/core/constants.go +++ b/core/constants.go @@ -31,10 +31,14 @@ const ( // NoExpiryValue is the returned value for a persistent key expiry time const NoExpiryValue = -1 +// Status represents the status of the security mode type Status int const ( + // NotSet means that security mode is not activated NotSet Status = iota - ManualSet + // ManuallySet means that security mode was activated because of failures + ManuallySet + // AutomaticallySet means that security mode was activated by user with SetSecurityModeNoExpire AutomaticallySet ) diff --git a/core/interface.go b/core/interface.go index 6a65734a..d19f3a48 100644 --- a/core/interface.go +++ b/core/interface.go @@ -37,7 +37,7 @@ type ServiceResolver interface { SignMessage(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpire(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) - GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) + GetUserStatus(userAddr string) (*requests.UserStatusResponse, error) SignTransaction(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactions(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) RegisteredUsers() (uint32, error) diff --git a/core/requests/types.go b/core/requests/types.go index bb3e91c3..14ef4f77 100644 --- a/core/requests/types.go +++ b/core/requests/types.go @@ -24,13 +24,7 @@ type SecurityModeNoExpire struct { UserAddr string `json:"user"` } -// UserStatusRequest is the JSON request the service is receiving -// for the user status interrogation -type UserStatusRequest struct { - UserAddr string `json:"user"` -} - -// UserStatusResponse - is the JSON response for the user status interrogation +// UserStatusResponse is the JSON response for the user status interrogation type UserStatusResponse struct { SecurityStatus int `json:"status"` } diff --git a/facade/guardianFacade.go b/facade/guardianFacade.go index 37983fbe..04693047 100644 --- a/facade/guardianFacade.go +++ b/facade/guardianFacade.go @@ -65,9 +65,9 @@ func (gf *guardianFacade) UnsetSecurityModeNoExpire(userIp string, request reque return gf.serviceResolver.UnsetSecurityModeNoExpire(userIp, request) } -// GetSecurityStatus returns the user's security status -func (gf *guardianFacade) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { - return gf.serviceResolver.GetSecurityStatus(request) +// GetUserStatus returns the user's security status +func (gf *guardianFacade) GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) { + return gf.serviceResolver.GetUserStatus(userAddress) } // SignMultipleTransactions validates user's transactions, then adds guardian signature and returns the transaction diff --git a/facade/guardianFacade_test.go b/facade/guardianFacade_test.go index 5c70352f..c0aeef35 100644 --- a/facade/guardianFacade_test.go +++ b/facade/guardianFacade_test.go @@ -113,9 +113,8 @@ func TestGuardianFacade_Getters(t *testing.T) { } wasUnsetSecurityModeNoExpireCalled := false - providedUserStatusRequest := requests.UserStatusRequest{ - UserAddr: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", - } + providedUserAddr := "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" + expectedUserStatusResponse := requests.UserStatusResponse{SecurityStatus: 1} args.ServiceResolver = &testscommon.ServiceResolverStub{ @@ -147,8 +146,8 @@ func TestGuardianFacade_Getters(t *testing.T) { wasUnsetSecurityModeNoExpireCalled = true return nil, nil }, - GetSecurityStatusCalled: func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { - assert.Equal(t, providedUserStatusRequest, request) + GetSecurityStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { + assert.Equal(t, providedUserAddr, providedUserAddr) return &expectedUserStatusResponse, nil }, SignTransactionCalled: func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) { @@ -216,7 +215,7 @@ func TestGuardianFacade_Getters(t *testing.T) { assert.Nil(t, err) assert.True(t, wasUnsetSecurityModeNoExpireCalled) - userStatus, err := facadeInstance.GetSecurityStatus(providedUserStatusRequest) + userStatus, err := facadeInstance.GetUserStatus(providedUserAddr) assert.Nil(t, err) assert.Equal(t, &expectedUserStatusResponse, userStatus) diff --git a/go.sum b/go.sum index 34e7f0e9..f5c89227 100644 --- a/go.sum +++ b/go.sum @@ -9,13 +9,9 @@ github.com/alicebob/miniredis/v2 v2.30.3/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6u github.com/beevik/ntp v1.3.0 h1:/w5VhpW5BGKS37vFm1p9oVk/t4HnnkKZAZIubHM6F7Q= github.com/beevik/ntp v1.3.0/go.mod h1:vD6h1um4kzXpqmLTuu0cCLcC+NfvC0IC+ltmEDA8E78= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= -github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= -github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= -github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= @@ -50,9 +46,7 @@ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -61,24 +55,18 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= @@ -98,14 +86,10 @@ github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -120,16 +104,13 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -154,10 +135,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -166,37 +145,23 @@ github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlI github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= -github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/herumi/bls-go-binary v1.28.2 h1:F0AezsC0M1a9aZjk7g0l2hMb1F56Xtpfku97pDndNZE= -github.com/herumi/bls-go-binary v1.28.2/go.mod h1:O4Vp1AfR4raRGwFeQpr9X/PQtncEicMoOe6BQt1oX0Y= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ipfs/boxo v0.8.1 h1:3DkKBCK+3rdEB5t77WDShUXXhktYwH99mkAsgajsKrU= -github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= -github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= -github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= -github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -214,7 +179,6 @@ github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuV github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= -github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -229,35 +193,20 @@ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ic github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.28.2 h1:lO/g0ccVru6nUVHyLE7C1VRr7B2AFp9cvHhf+l+Te6w= -github.com/libp2p/go-libp2p v0.28.2/go.mod h1:fOLgCNgLiWFdmtXyQBwmuCpukaYOA+yw4rnBiScDNmI= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.23.0 h1:sxE6LxLopp79eLeV695n7+c77V/Vn4AMF28AdM/XFqM= -github.com/libp2p/go-libp2p-kad-dht v0.23.0/go.mod h1:oO5N308VT2msnQI6qi5M61wzPmJYg7Tr9e16m5n7uDU= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= -github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= -github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= -github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= -github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= -github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= -github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -265,13 +214,9 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= -github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -283,25 +228,15 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= -github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= -github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= -github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= -github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= -github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= -github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= -github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUYwbO0993uPI= github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o= github.com/multiversx/mx-chain-communication-go v1.1.1 h1:y4DoQeQOJTaSUsRzczQFazf8JYQmInddypApqA3AkwM= @@ -334,7 +269,6 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= -github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -344,11 +278,8 @@ github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9 github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= @@ -362,34 +293,24 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= -github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us= github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= -github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= -github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/redis/go-redis/v9 v9.0.4 h1:FC82T+CHJ/Q/PdyLW++GeCO+Ol59Y4T7R4jbgjvktgc= github.com/redis/go-redis/v9 v9.0.4/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sec51/convert v1.0.2 h1:NoKWIRARjM3rQglNypMpcXSLLqPsN/uTTzaGeqDKbeg= @@ -399,9 +320,7 @@ github.com/sec51/gf256 v0.0.0-20160126143050-2454accbeb9e/go.mod h1:hCjOqSOB9PBw github.com/sec51/qrcode v0.0.0-20160126144534-b7779abbcaf1 h1:CI9zS8HvMiibvXM/F3IthY797GW77fNYgioJl/8Xzzk= github.com/sec51/qrcode v0.0.0-20160126144534-b7779abbcaf1/go.mod h1:uPm44Rj3uXSSOvmKmoeRuAUNUgwH2JHW5KIzqFFS/j4= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= -github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -424,11 +343,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDd github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= -github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= -github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= @@ -442,9 +358,7 @@ github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= -github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= @@ -459,25 +373,16 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= -go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= @@ -492,13 +397,11 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45 golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -581,14 +484,12 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= -gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -619,6 +520,5 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/handlers/secureOtp/secureOtpHandler.go b/handlers/secureOtp/secureOtpHandler.go index a8919148..d67f1771 100644 --- a/handlers/secureOtp/secureOtpHandler.go +++ b/handlers/secureOtp/secureOtpHandler.go @@ -114,7 +114,7 @@ func (totp *secureOtpHandler) UnsetSecurityModeNoExpire(key string) error { return totp.rateLimiter.UnsetSecurityModeNoExpire(key) } -// GetSecurityStatus - returns the status of the security mode +// GetSecurityStatus returns the status of the security mode func (totp *secureOtpHandler) GetSecurityStatus(key string) core.Status { return totp.rateLimiter.GetSecurityStatus(key) } diff --git a/integrationTests/otpRateLimiting_test.go b/integrationTests/otpRateLimiting_test.go index 61a8fa16..6469af49 100644 --- a/integrationTests/otpRateLimiting_test.go +++ b/integrationTests/otpRateLimiting_test.go @@ -457,7 +457,7 @@ func TestSecurityMode(t *testing.T) { require.Equal(t, expOtpVerifyData, otpVerifyData) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) redisServer.FastForward(time.Second * time.Duration(expOtpVerifyData.ResetAfter)) otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) @@ -471,7 +471,7 @@ func TestSecurityMode(t *testing.T) { require.Equal(t, expOtpVerifyData, otpVerifyData) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) }) @@ -498,7 +498,7 @@ func TestSecurityMode(t *testing.T) { require.Nil(t, err) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) @@ -511,7 +511,7 @@ func TestSecurityMode(t *testing.T) { require.Equal(t, expOtpVerifyData, otpVerifyData) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) err = secureOtpHandler.UnsetSecurityModeNoExpire(userAddress) require.Nil(t, err) @@ -617,7 +617,7 @@ func TestSecurityMode(t *testing.T) { require.Nil(t, err) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) redisServer.FastForward(time.Second * time.Duration(expOtpVerifyData.ResetAfter)) otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) @@ -634,7 +634,7 @@ func TestSecurityMode(t *testing.T) { require.Nil(t, err) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) @@ -647,7 +647,7 @@ func TestSecurityMode(t *testing.T) { require.Equal(t, expOtpVerifyData, otpVerifyData) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) }) t.Run("test unset multiple times", func(t *testing.T) { @@ -673,7 +673,7 @@ func TestSecurityMode(t *testing.T) { require.Nil(t, err) status = secureOtpHandler.GetSecurityStatus(userAddress) - require.Equal(t, core.ManualSet, status) + require.Equal(t, core.ManuallySet, status) otpVerifyData, err = secureOtpHandler.IsVerificationAllowedAndIncreaseTrials(userAddress, userIp) require.Nil(t, err) diff --git a/redis/redisLimiter.go b/redis/redisLimiter.go index 4535196a..2686821e 100644 --- a/redis/redisLimiter.go +++ b/redis/redisLimiter.go @@ -237,16 +237,22 @@ func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) core.S return core.NotSet } - trials, _ := strconv.ParseInt(dbVal, 10, 64) - if trials < maxFailures && expTime != core.NoExpiryValue { + trials, err := strconv.ParseInt(dbVal, 10, 64) + if err != nil { + log.Debug("error when returning security status", "err", err) return core.NotSet } - if trials >= maxFailures && expTime != core.NoExpiryValue { + if expTime == core.NoExpiryValue { + return core.ManuallySet + } + + hasTrialsLeft := trials < maxFailures + if !hasTrialsLeft { return core.AutomaticallySet } - return core.ManualSet + return core.NotSet } // UnsetSecurityModeNoExpire will set the key from persistent to volatile diff --git a/redis/redisLimiter_test.go b/redis/redisLimiter_test.go index 0545208f..f14bff38 100644 --- a/redis/redisLimiter_test.go +++ b/redis/redisLimiter_test.go @@ -620,7 +620,7 @@ func TestGetSecurityStatus(t *testing.T) { require.Nil(t, err) actualStatus := rl.GetSecurityStatus("key") - require.Equal(t, core.ManualSet, actualStatus) + require.Equal(t, core.ManuallySet, actualStatus) }) } diff --git a/resolver/serviceResolver.go b/resolver/serviceResolver.go index 1b137b6c..e8f3bb90 100644 --- a/resolver/serviceResolver.go +++ b/resolver/serviceResolver.go @@ -289,9 +289,9 @@ func (resolver *serviceResolver) UnsetSecurityModeNoExpire(userIp string, reques return verifyCodeData, resolver.secureOtpHandler.UnsetSecurityModeNoExpire(request.UserAddr) } -// GetSecurityStatus gets the user's security status -func (resolver *serviceResolver) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { - status, err := resolver.verifyUserReturningSecurityStatus(request.UserAddr) +// GetUserStatus gets the user's security status +func (resolver *serviceResolver) GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) { + status, err := resolver.getUserStatus(userAddress) return &requests.UserStatusResponse{ SecurityStatus: int(status), @@ -494,10 +494,10 @@ func (resolver *serviceResolver) validateTxRequestReturningGuardian( return resolver.verifyCodesReturningGuardian(userAddress, txs[0].GuardianAddr, userIp, code, secondCode) } -func (resolver *serviceResolver) verifyUserReturningSecurityStatus(userAddr string) (core.Status, error) { +func (resolver *serviceResolver) getUserStatus(userAddr string) (core.Status, error) { userAddress, err := sdkData.NewAddressFromBech32String(userAddr) if err != nil { - return 0, err + return core.NotSet, err } addressBytes := userAddress.AddressBytes() diff --git a/resolver/serviceResolver_test.go b/resolver/serviceResolver_test.go index d88c0e2d..b52b2c53 100644 --- a/resolver/serviceResolver_test.go +++ b/resolver/serviceResolver_test.go @@ -2739,13 +2739,9 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { t.Parallel() providedSender := "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" - providedRequest := requests.UserStatusRequest{ - UserAddr: providedSender, - } t.Run("should return err because of getUserInfo", func(t *testing.T) { t.Parallel() - providedRequestCopy := providedRequest args := createMockArgs() args.RegisteredUsersDB = &testscommon.ShardedStorageWithIndexStub{ @@ -2760,7 +2756,7 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { expectedStatus := &requests.UserStatusResponse{ SecurityStatus: -1, } - statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + statusReturned, err := resolver.GetUserStatus(providedSender) assert.Equal(t, expectedStatus, statusReturned) assert.Equal(t, expectedErr, err) @@ -2768,7 +2764,6 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { t.Run("should return 0", func(t *testing.T) { t.Parallel() - providedRequestCopy := providedRequest providedUserInfoCopy := *providedUserInfo args := createMockArgs() @@ -2792,7 +2787,7 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { expectedStatus := &requests.UserStatusResponse{ SecurityStatus: 0, } - statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + statusReturned, err := resolver.GetUserStatus(providedSender) assert.Nil(t, err) assert.Equal(t, expectedStatus, statusReturned) @@ -2800,7 +2795,6 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { t.Run("should return 1", func(t *testing.T) { t.Parallel() - providedRequestCopy := providedRequest providedUserInfoCopy := *providedUserInfo args := createMockArgs() @@ -2814,7 +2808,7 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { args.SecureOtpHandler = &testscommon.SecureOtpHandlerStub{ GetSecurityStatusCalled: func(key string) core.Status { - return core.ManualSet + return core.ManuallySet }, } @@ -2824,7 +2818,7 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { expectedStatus := &requests.UserStatusResponse{ SecurityStatus: 1, } - statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + statusReturned, err := resolver.GetUserStatus(providedSender) assert.Nil(t, err) assert.Equal(t, expectedStatus, statusReturned) @@ -2832,7 +2826,6 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { t.Run("should return 2", func(t *testing.T) { t.Parallel() - providedRequestCopy := providedRequest providedUserInfoCopy := *providedUserInfo args := createMockArgs() @@ -2856,7 +2849,7 @@ func TestServiceResolver_GetSecurityStatus(t *testing.T) { expectedStatus := &requests.UserStatusResponse{ SecurityStatus: 2, } - statusReturned, err := resolver.GetSecurityStatus(providedRequestCopy) + statusReturned, err := resolver.GetUserStatus(providedSender) assert.Nil(t, err) assert.Equal(t, expectedStatus, statusReturned) diff --git a/testscommon/facade/guardianFacadeStub.go b/testscommon/facade/guardianFacadeStub.go index 5f2e88f1..313890f2 100644 --- a/testscommon/facade/guardianFacadeStub.go +++ b/testscommon/facade/guardianFacadeStub.go @@ -14,7 +14,7 @@ type GuardianFacadeStub struct { SignMessageCalled func(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) - GetSecurityStatusCalled func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) + GetSecurityStatusCalled func(userAddress string) (*requests.UserStatusResponse, error) SignTransactionCalled func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactionsCalled func(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) RegisteredUsersCalled func() (uint32, error) @@ -64,9 +64,9 @@ func (stub *GuardianFacadeStub) UnsetSecurityModeNoExpire(userIp string, request } // GetSecurityStatus - -func (stub *GuardianFacadeStub) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { +func (stub *GuardianFacadeStub) GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) { if stub.GetSecurityStatusCalled != nil { - return stub.GetSecurityStatusCalled(request) + return stub.GetSecurityStatusCalled(userAddress) } return &requests.UserStatusResponse{}, nil } diff --git a/testscommon/rateLimiterMock.go b/testscommon/rateLimiterMock.go index e46a39d7..c8c4c317 100644 --- a/testscommon/rateLimiterMock.go +++ b/testscommon/rateLimiterMock.go @@ -62,7 +62,7 @@ func (r *RateLimiterMock) UnsetSecurityModeNoExpire(key string) error { // GetSecurityStatus - func (r *RateLimiterMock) GetSecurityStatus(key string) core.Status { - return 0 + return core.NotSet } // Reset - diff --git a/testscommon/rateLimiterStub.go b/testscommon/rateLimiterStub.go index cd54ec80..916fab88 100644 --- a/testscommon/rateLimiterStub.go +++ b/testscommon/rateLimiterStub.go @@ -59,7 +59,7 @@ func (r *RateLimiterStub) GetSecurityStatus(key string) core.Status { if r.GetSecurityStatusCalled != nil { return r.GetSecurityStatusCalled(key) } - return -1 + return core.NotSet } // Reset - diff --git a/testscommon/serviceResolverStub.go b/testscommon/serviceResolverStub.go index dd1be593..4dcc97e9 100644 --- a/testscommon/serviceResolverStub.go +++ b/testscommon/serviceResolverStub.go @@ -14,7 +14,7 @@ type ServiceResolverStub struct { VerifyCodeCalled func(userAddress core.AddressHandler, userIp string, request requests.VerificationPayload) (*requests.OTPCodeVerifyData, error) SetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) - GetSecurityStatusCalled func(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) + GetSecurityStatusCalled func(userAddress string) (*requests.UserStatusResponse, error) SignMessageCalled func(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SignTransactionCalled func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactionsCalled func(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) @@ -63,9 +63,9 @@ func (stub *ServiceResolverStub) UnsetSecurityModeNoExpire(userIp string, reques } // GetSecurityStatus - -func (stub *ServiceResolverStub) GetSecurityStatus(request requests.UserStatusRequest) (*requests.UserStatusResponse, error) { +func (stub *ServiceResolverStub) GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) { if stub.GetSecurityStatusCalled != nil { - return stub.GetSecurityStatusCalled(request) + return stub.GetSecurityStatusCalled(userAddress) } return &requests.UserStatusResponse{}, nil From a32ad2a70ef9f1358ff2600b84b2f4a27bd0caea Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Mon, 5 May 2025 17:52:14 +0300 Subject: [PATCH 11/19] fixes after reviews --- api/groups/guardianGroup_test.go | 6 +++--- cmd/multi-factor-auth/swagger/data.go | 4 ++-- facade/guardianFacade_test.go | 2 +- redis/redisLimiter.go | 2 +- resolver/serviceResolver.go | 2 +- resolver/serviceResolver_test.go | 2 +- testscommon/facade/guardianFacadeStub.go | 8 ++++---- testscommon/serviceResolverStub.go | 8 ++++---- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/api/groups/guardianGroup_test.go b/api/groups/guardianGroup_test.go index 55b13b9d..e06d5760 100644 --- a/api/groups/guardianGroup_test.go +++ b/api/groups/guardianGroup_test.go @@ -516,14 +516,14 @@ func TestGuardianGroup_UnsetSecurityModeNoExpire(t *testing.T) { }) } -func TestGuardianGroup_getSecurityStatus(t *testing.T) { +func TestGuardianGroup_getUserStatus(t *testing.T) { t.Parallel() t.Run("facade returns error", func(t *testing.T) { t.Parallel() facade := mockFacade.GuardianFacadeStub{ - GetSecurityStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { + GetUserStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { return &requests.UserStatusResponse{SecurityStatus: -1}, expectedError }, } @@ -552,7 +552,7 @@ func TestGuardianGroup_getSecurityStatus(t *testing.T) { t.Parallel() facade := mockFacade.GuardianFacadeStub{ - GetSecurityStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { + GetUserStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { return &requests.UserStatusResponse{ SecurityStatus: 1, }, nil diff --git a/cmd/multi-factor-auth/swagger/data.go b/cmd/multi-factor-auth/swagger/data.go index 80065e5c..9e5039d4 100644 --- a/cmd/multi-factor-auth/swagger/data.go +++ b/cmd/multi-factor-auth/swagger/data.go @@ -290,8 +290,8 @@ type _ struct { Payload requests.SecurityModeNoExpire } -// swagger:route GET /user-status Guardian getSecurityStatus -// Returns the security status of the user. +// swagger:route GET /user-status Guardian getUsersStatus +// Returns the status of the user. // This request does not need the Authorization header // // responses: diff --git a/facade/guardianFacade_test.go b/facade/guardianFacade_test.go index c0aeef35..158fd90f 100644 --- a/facade/guardianFacade_test.go +++ b/facade/guardianFacade_test.go @@ -146,7 +146,7 @@ func TestGuardianFacade_Getters(t *testing.T) { wasUnsetSecurityModeNoExpireCalled = true return nil, nil }, - GetSecurityStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { + GetUserStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { assert.Equal(t, providedUserAddr, providedUserAddr) return &expectedUserStatusResponse, nil }, diff --git a/redis/redisLimiter.go b/redis/redisLimiter.go index 2686821e..d236b3a4 100644 --- a/redis/redisLimiter.go +++ b/redis/redisLimiter.go @@ -239,7 +239,7 @@ func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) core.S trials, err := strconv.ParseInt(dbVal, 10, 64) if err != nil { - log.Debug("error when returning security status", "err", err) + log.Debug("error when converting security status", "err", err) return core.NotSet } diff --git a/resolver/serviceResolver.go b/resolver/serviceResolver.go index e8f3bb90..e57cab1b 100644 --- a/resolver/serviceResolver.go +++ b/resolver/serviceResolver.go @@ -289,7 +289,7 @@ func (resolver *serviceResolver) UnsetSecurityModeNoExpire(userIp string, reques return verifyCodeData, resolver.secureOtpHandler.UnsetSecurityModeNoExpire(request.UserAddr) } -// GetUserStatus gets the user's security status +// GetUserStatus gets the user's status func (resolver *serviceResolver) GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) { status, err := resolver.getUserStatus(userAddress) diff --git a/resolver/serviceResolver_test.go b/resolver/serviceResolver_test.go index b52b2c53..1867639b 100644 --- a/resolver/serviceResolver_test.go +++ b/resolver/serviceResolver_test.go @@ -2735,7 +2735,7 @@ func TestServiceResolver_UnsetSecurityModeNoExpire(t *testing.T) { } -func TestServiceResolver_GetSecurityStatus(t *testing.T) { +func TestServiceResolver_GetUserStatus(t *testing.T) { t.Parallel() providedSender := "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" diff --git a/testscommon/facade/guardianFacadeStub.go b/testscommon/facade/guardianFacadeStub.go index 313890f2..18bfb21f 100644 --- a/testscommon/facade/guardianFacadeStub.go +++ b/testscommon/facade/guardianFacadeStub.go @@ -14,7 +14,7 @@ type GuardianFacadeStub struct { SignMessageCalled func(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) - GetSecurityStatusCalled func(userAddress string) (*requests.UserStatusResponse, error) + GetUserStatusCalled func(userAddress string) (*requests.UserStatusResponse, error) SignTransactionCalled func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactionsCalled func(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) RegisteredUsersCalled func() (uint32, error) @@ -63,10 +63,10 @@ func (stub *GuardianFacadeStub) UnsetSecurityModeNoExpire(userIp string, request return nil, nil } -// GetSecurityStatus - +// GetUserStatus - func (stub *GuardianFacadeStub) GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) { - if stub.GetSecurityStatusCalled != nil { - return stub.GetSecurityStatusCalled(userAddress) + if stub.GetUserStatusCalled != nil { + return stub.GetUserStatusCalled(userAddress) } return &requests.UserStatusResponse{}, nil } diff --git a/testscommon/serviceResolverStub.go b/testscommon/serviceResolverStub.go index 4dcc97e9..3ecd3a41 100644 --- a/testscommon/serviceResolverStub.go +++ b/testscommon/serviceResolverStub.go @@ -14,7 +14,7 @@ type ServiceResolverStub struct { VerifyCodeCalled func(userAddress core.AddressHandler, userIp string, request requests.VerificationPayload) (*requests.OTPCodeVerifyData, error) SetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) UnsetSecurityModeNoExpireCalled func(userIp string, request requests.SecurityModeNoExpire) (*requests.OTPCodeVerifyData, error) - GetSecurityStatusCalled func(userAddress string) (*requests.UserStatusResponse, error) + GetUserStatusCalled func(userAddress string) (*requests.UserStatusResponse, error) SignMessageCalled func(userIp string, request requests.SignMessage) ([]byte, *requests.OTPCodeVerifyData, error) SignTransactionCalled func(userIp string, request requests.SignTransaction) ([]byte, *requests.OTPCodeVerifyData, error) SignMultipleTransactionsCalled func(userIp string, request requests.SignMultipleTransactions) ([][]byte, *requests.OTPCodeVerifyData, error) @@ -62,10 +62,10 @@ func (stub *ServiceResolverStub) UnsetSecurityModeNoExpire(userIp string, reques return nil, nil } -// GetSecurityStatus - +// GetUserStatus - func (stub *ServiceResolverStub) GetUserStatus(userAddress string) (*requests.UserStatusResponse, error) { - if stub.GetSecurityStatusCalled != nil { - return stub.GetSecurityStatusCalled(userAddress) + if stub.GetUserStatusCalled != nil { + return stub.GetUserStatusCalled(userAddress) } return &requests.UserStatusResponse{}, nil From e1d40c45f27f57278bdcda996248d4e7d0d434b9 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 6 May 2025 13:36:07 +0300 Subject: [PATCH 12/19] fix native auth whitelister check --- api/middleware/nativeAuthWhitelistHandler.go | 27 +++++++++++++++++-- .../nativeAuthWhitelistHandler_test.go | 9 +++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/api/middleware/nativeAuthWhitelistHandler.go b/api/middleware/nativeAuthWhitelistHandler.go index 74fd3b0f..91c26fbf 100644 --- a/api/middleware/nativeAuthWhitelistHandler.go +++ b/api/middleware/nativeAuthWhitelistHandler.go @@ -2,6 +2,7 @@ package middleware import ( "fmt" + "strings" "github.com/multiversx/mx-multi-factor-auth-go-service/config" ) @@ -20,7 +21,8 @@ func NewNativeAuthWhitelistHandler(apiPackages map[string]config.APIPackageConfi for _, route := range groupCfg.Routes { if !route.Auth { fullPath := fmt.Sprintf("%s%s", groupPath, route.Name) - whitelistedRoutes[fullPath] = struct{}{} + basePath := trimPathPlaceholder(fullPath) + whitelistedRoutes[basePath] = struct{}{} } } } @@ -31,9 +33,30 @@ func NewNativeAuthWhitelistHandler(apiPackages map[string]config.APIPackageConfi } } +func trimPathPlaceholder(path string) string { + parts := strings.Split(path, ":") + if len(parts) > 0 { + return "/" + strings.Trim(parts[0], "/") + } + + return path +} + +func extractBaseRoutePath(path string) string { + parts := strings.Split(path, "/") + + if len(parts) > 2 { + return "/" + parts[1] + "/" + parts[2] // group and base path + } + + return path +} + // IsWhitelisted returns true if the provided route is whitelisted for native authentication func (handler *nativeAuthWhitelistHandler) IsWhitelisted(route string) bool { - _, found := handler.whitelistedRoutesMap[route] + baseRoute := extractBaseRoutePath(route) + _, found := handler.whitelistedRoutesMap[baseRoute] + log.Error("adas", "map", handler.whitelistedRoutesMap, "bb", baseRoute) return found } diff --git a/api/middleware/nativeAuthWhitelistHandler_test.go b/api/middleware/nativeAuthWhitelistHandler_test.go index ea08dd1c..08abfd0b 100644 --- a/api/middleware/nativeAuthWhitelistHandler_test.go +++ b/api/middleware/nativeAuthWhitelistHandler_test.go @@ -23,6 +23,11 @@ func TestNativeAuthWhitelistHandler(t *testing.T) { Open: true, Auth: false, }, + { + Name: "/user-status/:address", + Open: true, + Auth: false, + }, }, }, "status": { @@ -43,9 +48,13 @@ func TestNativeAuthWhitelistHandler(t *testing.T) { require.True(t, handler.IsWhitelisted("/guardian")) require.True(t, handler.IsWhitelisted("/status")) require.True(t, handler.IsWhitelisted("/log")) + require.True(t, handler.IsWhitelisted("/guardian/user-status/erd1")) + require.True(t, handler.IsWhitelisted("/guardian/user-status")) + require.True(t, handler.IsWhitelisted("/guardian/user-status/")) require.False(t, handler.IsWhitelisted("/guardian/register")) require.False(t, handler.IsWhitelisted("guardian/sign-transaction")) require.False(t, handler.IsWhitelisted("/sign-transaction")) + require.False(t, handler.IsWhitelisted("guardian/user-status/erd1")) require.False(t, handler.IsWhitelisted("guardian")) require.False(t, handler.IsWhitelisted("")) } From bf251d2210bcd24a407bc2a5932e8c74a6b9221d Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 6 May 2025 13:55:41 +0300 Subject: [PATCH 13/19] remove debug log --- api/middleware/nativeAuthWhitelistHandler.go | 1 - 1 file changed, 1 deletion(-) diff --git a/api/middleware/nativeAuthWhitelistHandler.go b/api/middleware/nativeAuthWhitelistHandler.go index 91c26fbf..9b630c55 100644 --- a/api/middleware/nativeAuthWhitelistHandler.go +++ b/api/middleware/nativeAuthWhitelistHandler.go @@ -56,7 +56,6 @@ func extractBaseRoutePath(path string) string { func (handler *nativeAuthWhitelistHandler) IsWhitelisted(route string) bool { baseRoute := extractBaseRoutePath(route) _, found := handler.whitelistedRoutesMap[baseRoute] - log.Error("adas", "map", handler.whitelistedRoutesMap, "bb", baseRoute) return found } From 62a028f46db600a6c2c639f2b7ae7825f2c1394a Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Tue, 6 May 2025 17:28:47 +0300 Subject: [PATCH 14/19] swagger update --- cmd/multi-factor-auth/swagger/ui/swagger.json | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/cmd/multi-factor-auth/swagger/ui/swagger.json b/cmd/multi-factor-auth/swagger/ui/swagger.json index 2cc032bb..22f119ba 100644 --- a/cmd/multi-factor-auth/swagger/ui/swagger.json +++ b/cmd/multi-factor-auth/swagger/ui/swagger.json @@ -207,6 +207,41 @@ } } }, + + + + + + + + + + + + + + + + + + + + + "/user-status": { + "get": { + "description": "This request does not need the Authorization header", + "tags": [ + "Guardian" + ], + "summary": "Returns the status of the user.", + "operationId": "getUsersStatus", + "responses": { + "200": { + "$ref": "#/responses/userStatusResponse" + } + } + } + }, "/verify-code": { "post": { "security": [ @@ -321,6 +356,14 @@ }, "x-go-name": "ReceiverUsername" }, + "relayer": { + "type": "string", + "x-go-name": "RelayerAddr" + }, + "relayerSignature": { + "type": "string", + "x-go-name": "RelayerSignature" + }, "sender": { "type": "string", "x-go-name": "Sender" @@ -782,6 +825,24 @@ } } }, + "userStatusResponse": { + "description": "The status of the operation", + "schema": { + "type": "object", + "properties": { + "error": { + "description": "Internal error", + "type": "string", + "x-go-name": "Error" + }, + "status": { + "description": "UserStatusResponse\nHTTP status code", + "type": "string", + "x-go-name": "Status" + } + } + } + }, "verifyCodeResponse": { "description": "Verification result", "schema": { From 18481a303395f9f1bead7345b7c6e4507428b530 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Mon, 30 Jun 2025 14:09:03 +0300 Subject: [PATCH 15/19] removed empty lines --- cmd/multi-factor-auth/swagger/ui/swagger.json | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/cmd/multi-factor-auth/swagger/ui/swagger.json b/cmd/multi-factor-auth/swagger/ui/swagger.json index 22f119ba..de0c307f 100644 --- a/cmd/multi-factor-auth/swagger/ui/swagger.json +++ b/cmd/multi-factor-auth/swagger/ui/swagger.json @@ -207,26 +207,6 @@ } } }, - - - - - - - - - - - - - - - - - - - - "/user-status": { "get": { "description": "This request does not need the Authorization header", From 603a2bcd4d9ccdcabebda79296d708d62ecea6ee Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Tue, 1 Jul 2025 10:46:29 +0300 Subject: [PATCH 16/19] fixed swagger --- cmd/multi-factor-auth/swagger/data.go | 11 ++++++++++- cmd/multi-factor-auth/swagger/ui/swagger.json | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/cmd/multi-factor-auth/swagger/data.go b/cmd/multi-factor-auth/swagger/data.go index 9e5039d4..1ec6e6fa 100644 --- a/cmd/multi-factor-auth/swagger/data.go +++ b/cmd/multi-factor-auth/swagger/data.go @@ -290,13 +290,22 @@ type _ struct { Payload requests.SecurityModeNoExpire } -// swagger:route GET /user-status Guardian getUsersStatus +// swagger:route GET /user-status/{address} Guardian getUsersStatus // Returns the status of the user. // This request does not need the Authorization header // // responses: // 200: userStatusResponse +// swagger:parameters getUsersStatus +type _ struct { + // address of an account + // + // in:path + // required:true + Address string `json:"address"` +} + // The status of the operation // swagger:response userStatusResponse type _ struct { diff --git a/cmd/multi-factor-auth/swagger/ui/swagger.json b/cmd/multi-factor-auth/swagger/ui/swagger.json index de0c307f..107a4bd8 100644 --- a/cmd/multi-factor-auth/swagger/ui/swagger.json +++ b/cmd/multi-factor-auth/swagger/ui/swagger.json @@ -207,7 +207,7 @@ } } }, - "/user-status": { + "/user-status/{address}": { "get": { "description": "This request does not need the Authorization header", "tags": [ @@ -215,6 +215,16 @@ ], "summary": "Returns the status of the user.", "operationId": "getUsersStatus", + "parameters": [ + { + "type": "string", + "x-go-name": "Address", + "description": "address of an account", + "name": "address", + "in": "path", + "required": true + } + ], "responses": { "200": { "$ref": "#/responses/userStatusResponse" From c640ac1b57f3682a381e2380a38f0f345f666105 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Tue, 1 Jul 2025 11:08:20 +0300 Subject: [PATCH 17/19] fixed swagger response for user-status --- cmd/multi-factor-auth/swagger/data.go | 1 + cmd/multi-factor-auth/swagger/ui/swagger.json | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cmd/multi-factor-auth/swagger/data.go b/cmd/multi-factor-auth/swagger/data.go index 1ec6e6fa..44847e9f 100644 --- a/cmd/multi-factor-auth/swagger/data.go +++ b/cmd/multi-factor-auth/swagger/data.go @@ -312,6 +312,7 @@ type _ struct { // in:body Body struct { // UserStatusResponse + Data requests.UserStatusResponse `json:"data"` // HTTP status code Status string `json:"status"` // Internal error diff --git a/cmd/multi-factor-auth/swagger/ui/swagger.json b/cmd/multi-factor-auth/swagger/ui/swagger.json index 107a4bd8..33e96bb1 100644 --- a/cmd/multi-factor-auth/swagger/ui/swagger.json +++ b/cmd/multi-factor-auth/swagger/ui/swagger.json @@ -632,6 +632,18 @@ }, "x-go-package": "github.com/multiversx/mx-multi-factor-auth-go-service/core/requests" }, + "UserStatusResponse": { + "description": "UserStatusResponse is the JSON response for the user status interrogation", + "type": "object", + "properties": { + "status": { + "type": "integer", + "format": "int64", + "x-go-name": "SecurityStatus" + } + }, + "x-go-package": "github.com/multiversx/mx-multi-factor-auth-go-service/core/requests" + }, "VerificationPayload": { "description": "VerificationPayload represents the JSON requests a user uses to validate the authentication code", "type": "object", @@ -820,13 +832,16 @@ "schema": { "type": "object", "properties": { + "data": { + "$ref": "#/definitions/UserStatusResponse" + }, "error": { "description": "Internal error", "type": "string", "x-go-name": "Error" }, "status": { - "description": "UserStatusResponse\nHTTP status code", + "description": "HTTP status code", "type": "string", "x-go-name": "Status" } From 6e80038a9ecc8fe5868bb127f47c19eb9b1856ad Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Tue, 1 Jul 2025 13:04:19 +0300 Subject: [PATCH 18/19] fixes after review --- api/groups/guardianGroup_test.go | 8 ++--- cmd/multi-factor-auth/swagger/data.go | 2 +- cmd/multi-factor-auth/swagger/ui/swagger.json | 2 +- core/constants.go | 6 ++-- core/requests/types.go | 2 +- facade/guardianFacade_test.go | 2 +- handlers/interface.go | 2 +- handlers/secureOtp/secureOtpHandler.go | 2 +- handlers/secureOtp/secureOtpHandler_test.go | 2 +- redis/interface.go | 2 +- redis/redisLimiter.go | 4 +-- resolver/serviceResolver.go | 17 ++-------- resolver/serviceResolver_test.go | 34 ++++--------------- testscommon/rateLimiterMock.go | 2 +- testscommon/rateLimiterStub.go | 4 +-- testscommon/secureOtpHandlerStub.go | 4 +-- 16 files changed, 30 insertions(+), 65 deletions(-) diff --git a/api/groups/guardianGroup_test.go b/api/groups/guardianGroup_test.go index e06d5760..32c831ca 100644 --- a/api/groups/guardianGroup_test.go +++ b/api/groups/guardianGroup_test.go @@ -524,7 +524,7 @@ func TestGuardianGroup_getUserStatus(t *testing.T) { facade := mockFacade.GuardianFacadeStub{ GetUserStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { - return &requests.UserStatusResponse{SecurityStatus: -1}, expectedError + return &requests.UserStatusResponse{SecurityModeStatus: -1}, expectedError }, } @@ -540,7 +540,7 @@ func TestGuardianGroup_getUserStatus(t *testing.T) { loadResponse(resp.Body, &statusRsp) expectedGenResponse := createExpectedGeneralResponse(&requests.UserStatusResponse{ - SecurityStatus: -1, + SecurityModeStatus: -1, }, "") assert.Equal(t, expectedGenResponse.Data, statusRsp.Data) @@ -554,7 +554,7 @@ func TestGuardianGroup_getUserStatus(t *testing.T) { facade := mockFacade.GuardianFacadeStub{ GetUserStatusCalled: func(userAddress string) (*requests.UserStatusResponse, error) { return &requests.UserStatusResponse{ - SecurityStatus: 1, + SecurityModeStatus: 1, }, nil }, } @@ -571,7 +571,7 @@ func TestGuardianGroup_getUserStatus(t *testing.T) { loadResponse(resp.Body, &statusRsp) expectedGenResponse := createExpectedGeneralResponse(&requests.UserStatusResponse{ - SecurityStatus: 1, + SecurityModeStatus: 1, }, "") assert.Equal(t, expectedGenResponse.Data, statusRsp.Data) diff --git a/cmd/multi-factor-auth/swagger/data.go b/cmd/multi-factor-auth/swagger/data.go index 44847e9f..8abd637d 100644 --- a/cmd/multi-factor-auth/swagger/data.go +++ b/cmd/multi-factor-auth/swagger/data.go @@ -306,7 +306,7 @@ type _ struct { Address string `json:"address"` } -// The status of the operation +// The status of the user // swagger:response userStatusResponse type _ struct { // in:body diff --git a/cmd/multi-factor-auth/swagger/ui/swagger.json b/cmd/multi-factor-auth/swagger/ui/swagger.json index 33e96bb1..4409c56d 100644 --- a/cmd/multi-factor-auth/swagger/ui/swagger.json +++ b/cmd/multi-factor-auth/swagger/ui/swagger.json @@ -828,7 +828,7 @@ } }, "userStatusResponse": { - "description": "The status of the operation", + "description": "The security status of the user", "schema": { "type": "object", "properties": { diff --git a/core/constants.go b/core/constants.go index 574def7e..b291891f 100644 --- a/core/constants.go +++ b/core/constants.go @@ -31,12 +31,12 @@ const ( // NoExpiryValue is the returned value for a persistent key expiry time const NoExpiryValue = -1 -// Status represents the status of the security mode -type Status int +// EnhancedSecurityModeStatus represents the status of the security mode +type EnhancedSecurityModeStatus int const ( // NotSet means that security mode is not activated - NotSet Status = iota + NotSet EnhancedSecurityModeStatus = iota // ManuallySet means that security mode was activated because of failures ManuallySet // AutomaticallySet means that security mode was activated by user with SetSecurityModeNoExpire diff --git a/core/requests/types.go b/core/requests/types.go index 14ef4f77..54a66ab5 100644 --- a/core/requests/types.go +++ b/core/requests/types.go @@ -26,7 +26,7 @@ type SecurityModeNoExpire struct { // UserStatusResponse is the JSON response for the user status interrogation type UserStatusResponse struct { - SecurityStatus int `json:"status"` + SecurityModeStatus int `json:"security-mode-status"` } // SignMessageResponse is the service response to the sign message request diff --git a/facade/guardianFacade_test.go b/facade/guardianFacade_test.go index 158fd90f..3e9ee7db 100644 --- a/facade/guardianFacade_test.go +++ b/facade/guardianFacade_test.go @@ -115,7 +115,7 @@ func TestGuardianFacade_Getters(t *testing.T) { providedUserAddr := "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" - expectedUserStatusResponse := requests.UserStatusResponse{SecurityStatus: 1} + expectedUserStatusResponse := requests.UserStatusResponse{SecurityModeStatus: 1} args.ServiceResolver = &testscommon.ServiceResolverStub{ VerifyCodeCalled: func(userAddress sdkCore.AddressHandler, userIp string, request requests.VerificationPayload) (*requests.OTPCodeVerifyData, error) { diff --git a/handlers/interface.go b/handlers/interface.go index aba4b09d..4f3b749c 100644 --- a/handlers/interface.go +++ b/handlers/interface.go @@ -22,7 +22,7 @@ type SecureOtpHandler interface { SecurityModeMaxFailures() uint64 SetSecurityModeNoExpire(key string) error UnsetSecurityModeNoExpire(key string) error - GetSecurityStatus(key string) core.Status + GetSecurityStatus(key string) core.EnhancedSecurityModeStatus IsVerificationAllowedAndIncreaseTrials(account string, ip string) (*requests.OTPCodeVerifyData, error) Reset(account string, ip string) DecrementSecurityModeFailedTrials(account string) error diff --git a/handlers/secureOtp/secureOtpHandler.go b/handlers/secureOtp/secureOtpHandler.go index d67f1771..5d1a0114 100644 --- a/handlers/secureOtp/secureOtpHandler.go +++ b/handlers/secureOtp/secureOtpHandler.go @@ -115,7 +115,7 @@ func (totp *secureOtpHandler) UnsetSecurityModeNoExpire(key string) error { } // GetSecurityStatus returns the status of the security mode -func (totp *secureOtpHandler) GetSecurityStatus(key string) core.Status { +func (totp *secureOtpHandler) GetSecurityStatus(key string) core.EnhancedSecurityModeStatus { return totp.rateLimiter.GetSecurityStatus(key) } diff --git a/handlers/secureOtp/secureOtpHandler_test.go b/handlers/secureOtp/secureOtpHandler_test.go index 06633d06..922afc98 100644 --- a/handlers/secureOtp/secureOtpHandler_test.go +++ b/handlers/secureOtp/secureOtpHandler_test.go @@ -417,7 +417,7 @@ func TestSecureOtpHandler_GetSecurityStatusShouldWork(t *testing.T) { args := createMockArgsSecureOtpHandler() args.RateLimiter = &testscommon.RateLimiterStub{ - GetSecurityStatusCalled: func(key string) core.Status { + GetSecurityStatusCalled: func(key string) core.EnhancedSecurityModeStatus { return core.NotSet }, } diff --git a/redis/interface.go b/redis/interface.go index 98a26abf..20412b89 100644 --- a/redis/interface.go +++ b/redis/interface.go @@ -22,7 +22,7 @@ type RateLimiter interface { Reset(key string) error SetSecurityModeNoExpire(key string) error UnsetSecurityModeNoExpire(key string) error - GetSecurityStatus(key string) core.Status + GetSecurityStatus(key string) core.EnhancedSecurityModeStatus DecrementSecurityFailedTrials(key string) error Period(mode Mode) time.Duration Rate(mode Mode) int diff --git a/redis/redisLimiter.go b/redis/redisLimiter.go index d236b3a4..9c7930a4 100644 --- a/redis/redisLimiter.go +++ b/redis/redisLimiter.go @@ -217,14 +217,14 @@ func (rl *rateLimiter) SetSecurityModeNoExpire(key string) error { } // GetSecurityStatus will return the security status based on the expiry time of the key -func (rl *rateLimiter) GetSecurityStatus(key string) core.Status { +func (rl *rateLimiter) GetSecurityStatus(key string) core.EnhancedSecurityModeStatus { ctx, cancel := context.WithTimeout(context.Background(), rl.operationTimeout) defer cancel() return rl.getSecurityStatus(ctx, key) } -func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) core.Status { +func (rl *rateLimiter) getSecurityStatus(ctx context.Context, key string) core.EnhancedSecurityModeStatus { _, maxFailures := rl.getFailConfig(SecurityMode) dbVal, err := rl.storer.Get(ctx, key) diff --git a/resolver/serviceResolver.go b/resolver/serviceResolver.go index e57cab1b..57214b30 100644 --- a/resolver/serviceResolver.go +++ b/resolver/serviceResolver.go @@ -294,7 +294,7 @@ func (resolver *serviceResolver) GetUserStatus(userAddress string) (*requests.Us status, err := resolver.getUserStatus(userAddress) return &requests.UserStatusResponse{ - SecurityStatus: int(status), + SecurityModeStatus: int(status), }, err } @@ -494,20 +494,7 @@ func (resolver *serviceResolver) validateTxRequestReturningGuardian( return resolver.verifyCodesReturningGuardian(userAddress, txs[0].GuardianAddr, userIp, code, secondCode) } -func (resolver *serviceResolver) getUserStatus(userAddr string) (core.Status, error) { - userAddress, err := sdkData.NewAddressFromBech32String(userAddr) - if err != nil { - return core.NotSet, err - } - - addressBytes := userAddress.AddressBytes() - resolver.userCritSection.RLock(string(addressBytes)) - _, err = resolver.getUserInfo(addressBytes) - resolver.userCritSection.RUnlock(string(addressBytes)) - if err != nil { - return -1, err - } - +func (resolver *serviceResolver) getUserStatus(userAddr string) (core.EnhancedSecurityModeStatus, error) { return resolver.secureOtpHandler.GetSecurityStatus(userAddr), nil } diff --git a/resolver/serviceResolver_test.go b/resolver/serviceResolver_test.go index 1867639b..526234c4 100644 --- a/resolver/serviceResolver_test.go +++ b/resolver/serviceResolver_test.go @@ -2740,28 +2740,6 @@ func TestServiceResolver_GetUserStatus(t *testing.T) { providedSender := "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" - t.Run("should return err because of getUserInfo", func(t *testing.T) { - t.Parallel() - - args := createMockArgs() - args.RegisteredUsersDB = &testscommon.ShardedStorageWithIndexStub{ - GetCalled: func(key []byte) ([]byte, error) { - return nil, expectedErr - }, - } - - resolver, _ := NewServiceResolver(args) - assert.NotNil(t, resolver) - - expectedStatus := &requests.UserStatusResponse{ - SecurityStatus: -1, - } - statusReturned, err := resolver.GetUserStatus(providedSender) - - assert.Equal(t, expectedStatus, statusReturned) - assert.Equal(t, expectedErr, err) - }) - t.Run("should return 0", func(t *testing.T) { t.Parallel() providedUserInfoCopy := *providedUserInfo @@ -2776,7 +2754,7 @@ func TestServiceResolver_GetUserStatus(t *testing.T) { } args.SecureOtpHandler = &testscommon.SecureOtpHandlerStub{ - GetSecurityStatusCalled: func(key string) core.Status { + GetSecurityStatusCalled: func(key string) core.EnhancedSecurityModeStatus { return core.NotSet }, } @@ -2785,7 +2763,7 @@ func TestServiceResolver_GetUserStatus(t *testing.T) { assert.NotNil(t, resolver) expectedStatus := &requests.UserStatusResponse{ - SecurityStatus: 0, + SecurityModeStatus: 0, } statusReturned, err := resolver.GetUserStatus(providedSender) @@ -2807,7 +2785,7 @@ func TestServiceResolver_GetUserStatus(t *testing.T) { } args.SecureOtpHandler = &testscommon.SecureOtpHandlerStub{ - GetSecurityStatusCalled: func(key string) core.Status { + GetSecurityStatusCalled: func(key string) core.EnhancedSecurityModeStatus { return core.ManuallySet }, } @@ -2816,7 +2794,7 @@ func TestServiceResolver_GetUserStatus(t *testing.T) { assert.NotNil(t, resolver) expectedStatus := &requests.UserStatusResponse{ - SecurityStatus: 1, + SecurityModeStatus: 1, } statusReturned, err := resolver.GetUserStatus(providedSender) @@ -2838,7 +2816,7 @@ func TestServiceResolver_GetUserStatus(t *testing.T) { } args.SecureOtpHandler = &testscommon.SecureOtpHandlerStub{ - GetSecurityStatusCalled: func(key string) core.Status { + GetSecurityStatusCalled: func(key string) core.EnhancedSecurityModeStatus { return core.AutomaticallySet }, } @@ -2847,7 +2825,7 @@ func TestServiceResolver_GetUserStatus(t *testing.T) { assert.NotNil(t, resolver) expectedStatus := &requests.UserStatusResponse{ - SecurityStatus: 2, + SecurityModeStatus: 2, } statusReturned, err := resolver.GetUserStatus(providedSender) diff --git a/testscommon/rateLimiterMock.go b/testscommon/rateLimiterMock.go index c8c4c317..c9927639 100644 --- a/testscommon/rateLimiterMock.go +++ b/testscommon/rateLimiterMock.go @@ -61,7 +61,7 @@ func (r *RateLimiterMock) UnsetSecurityModeNoExpire(key string) error { } // GetSecurityStatus - -func (r *RateLimiterMock) GetSecurityStatus(key string) core.Status { +func (r *RateLimiterMock) GetSecurityStatus(key string) core.EnhancedSecurityModeStatus { return core.NotSet } diff --git a/testscommon/rateLimiterStub.go b/testscommon/rateLimiterStub.go index 916fab88..04821813 100644 --- a/testscommon/rateLimiterStub.go +++ b/testscommon/rateLimiterStub.go @@ -16,7 +16,7 @@ type RateLimiterStub struct { RateCalled func(mode redis.Mode) int SetSecurityModeNoExpireCalled func(key string) error UnsetSecurityModeNoExpireCalled func(key string) error - GetSecurityStatusCalled func(key string) core.Status + GetSecurityStatusCalled func(key string) core.EnhancedSecurityModeStatus ExtendSecurityModeCalled func(key string) error } @@ -55,7 +55,7 @@ func (r *RateLimiterStub) UnsetSecurityModeNoExpire(key string) error { } // GetSecurityStatus - -func (r *RateLimiterStub) GetSecurityStatus(key string) core.Status { +func (r *RateLimiterStub) GetSecurityStatus(key string) core.EnhancedSecurityModeStatus { if r.GetSecurityStatusCalled != nil { return r.GetSecurityStatusCalled(key) } diff --git a/testscommon/secureOtpHandlerStub.go b/testscommon/secureOtpHandlerStub.go index fa56b7ec..a30fc86f 100644 --- a/testscommon/secureOtpHandlerStub.go +++ b/testscommon/secureOtpHandlerStub.go @@ -12,7 +12,7 @@ type SecureOtpHandlerStub struct { DecrementSecurityModeFailedTrialsCalled func(account string) error SetSecurityModeNoExpireCalled func(key string) error UnsetSecurityModeNoExpireCalled func(key string) error - GetSecurityStatusCalled func(key string) core.Status + GetSecurityStatusCalled func(key string) core.EnhancedSecurityModeStatus FreezeBackoffTimeCalled func() uint64 FreezeMaxFailuresCalled func() uint64 SecurityModeBackOffTimeCalled func() uint64 @@ -46,7 +46,7 @@ func (stub *SecureOtpHandlerStub) UnsetSecurityModeNoExpire(key string) error { } // GetSecurityStatus - -func (stub *SecureOtpHandlerStub) GetSecurityStatus(key string) core.Status { +func (stub *SecureOtpHandlerStub) GetSecurityStatus(key string) core.EnhancedSecurityModeStatus { if stub.GetSecurityStatusCalled != nil { return stub.GetSecurityStatusCalled(key) } From 5b4b3541b7eb3b8e2921b43e8470676884730ff1 Mon Sep 17 00:00:00 2001 From: Daniel Radu Date: Tue, 1 Jul 2025 16:12:36 +0300 Subject: [PATCH 19/19] swagger fix --- cmd/multi-factor-auth/swagger/data.go | 2 +- cmd/multi-factor-auth/swagger/ui/swagger.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/multi-factor-auth/swagger/data.go b/cmd/multi-factor-auth/swagger/data.go index 8abd637d..8e1ccfa0 100644 --- a/cmd/multi-factor-auth/swagger/data.go +++ b/cmd/multi-factor-auth/swagger/data.go @@ -306,7 +306,7 @@ type _ struct { Address string `json:"address"` } -// The status of the user +// The security status of the user // swagger:response userStatusResponse type _ struct { // in:body diff --git a/cmd/multi-factor-auth/swagger/ui/swagger.json b/cmd/multi-factor-auth/swagger/ui/swagger.json index 4409c56d..49102339 100644 --- a/cmd/multi-factor-auth/swagger/ui/swagger.json +++ b/cmd/multi-factor-auth/swagger/ui/swagger.json @@ -636,10 +636,10 @@ "description": "UserStatusResponse is the JSON response for the user status interrogation", "type": "object", "properties": { - "status": { + "security-mode-status": { "type": "integer", "format": "int64", - "x-go-name": "SecurityStatus" + "x-go-name": "SecurityModeStatus" } }, "x-go-package": "github.com/multiversx/mx-multi-factor-auth-go-service/core/requests"