diff --git a/go.mod b/go.mod index 4f05109..f77180b 100644 --- a/go.mod +++ b/go.mod @@ -108,7 +108,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect - github.com/onsi/ginkgo/v2 v2.13.1 // indirect + github.com/onsi/ginkgo/v2 v2.13.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opencontainers/runc v1.1.10 // indirect diff --git a/go.sum b/go.sum index f3a72cc..d4ea897 100644 --- a/go.sum +++ b/go.sum @@ -286,8 +286,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU= -github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= diff --git a/tokenomics/contract.go b/tokenomics/contract.go index f9cb4d6..3cf0d47 100644 --- a/tokenomics/contract.go +++ b/tokenomics/contract.go @@ -259,8 +259,9 @@ type ( kycConfigJSON struct { FaceAuth struct { - DisabledVersions []string `json:"disabledVersions"` - Enabled bool `json:"enabled"` + DisabledVersions []string `json:"disabledVersions"` + ForceKYCForUserIds []string `json:"forceKYCForUserIds"` + Enabled bool `json:"enabled"` } `json:"face-auth"` WebFaceAuth struct { Enabled bool `json:"enabled"` diff --git a/tokenomics/kyc.go b/tokenomics/kyc.go index ef665e4..f964090 100644 --- a/tokenomics/kyc.go +++ b/tokenomics/kyc.go @@ -76,7 +76,7 @@ func (r *repository) syncKYCConfigJSON(ctx context.Context) error { if err = json.UnmarshalContext(ctx, data, &kycConfig); err != nil { return errors.Wrapf(err, "failed to unmarshal into %#v, data: %v", kycConfig, string(data)) } - if !kycConfig.FaceAuth.Enabled && len(kycConfig.FaceAuth.DisabledVersions) == 0 && !kycConfig.WebFaceAuth.Enabled { + if !kycConfig.FaceAuth.Enabled && len(kycConfig.FaceAuth.DisabledVersions) == 0 && len(kycConfig.FaceAuth.ForceKYCForUserIds) == 0 && !kycConfig.WebFaceAuth.Enabled { if body := string(data); !strings.Contains(body, "face-auth") && !strings.Contains(body, "web-face-auth") { return errors.Errorf("there's something wrong with the KYCConfigJSON body: %v", body) } @@ -115,7 +115,7 @@ func (r *repository) validateKYC(ctx context.Context, state *getCurrentMiningSes isAfterFirstWindow = time.Now().Sub(*r.livenessLoadDistributionStartDate.Time) > r.cfg.KYC.LivenessDelay isReservedForToday = r.cfg.KYC.LivenessDelay <= r.cfg.MiningSessionDuration.Max || isAfterFirstWindow || int64((time.Now().Sub(*r.livenessLoadDistributionStartDate.Time)%r.cfg.KYC.LivenessDelay)/r.cfg.MiningSessionDuration.Max) >= state.ID%int64(r.cfg.KYC.LivenessDelay/r.cfg.MiningSessionDuration.Max) //nolint:lll // . ) - if atLeastOneMiningStarted && isReservedForToday && r.isKYCEnabled(ctx, state.LatestDevice, users.FacialRecognitionKYCStep) { + if r.isFaceAuthForced(state.UserID) || (atLeastOneMiningStarted && isReservedForToday && r.isKYCEnabled(ctx, state.LatestDevice, users.FacialRecognitionKYCStep)) { return terror.New(ErrKYCRequired, map[string]any{ "kycSteps": []users.KYCStep{users.FacialRecognitionKYCStep, users.LivenessDetectionKYCStep}, }) @@ -184,6 +184,26 @@ func (r *repository) isFaceAuthEnabledForDevice(device string) bool { return true } +func (r *repository) isFaceAuthForced(userID string) bool { + if userID == "" { + return false + } + var forceKYCForUserIds []string + if cfgVal := r.cfg.kycConfigJSON.Load(); cfgVal != nil { + forceKYCForUserIds = cfgVal.FaceAuth.ForceKYCForUserIds + } + if len(forceKYCForUserIds) == 0 { + return false + } + for _, uID := range forceKYCForUserIds { + if strings.EqualFold(userID, strings.TrimSpace(uID)) { + return true + } + } + + return false +} + /* Because existing users have empty KYCState in dragonfly cuz usersTableSource might not have updated it yet. And because we might need to reset any kyc steps for the user prior to starting to mine.