Skip to content

Commit

Permalink
remove call to check reputation during wallet linking (#2069)
Browse files Browse the repository at this point in the history
* remove call to check reputation during wallet linking

* feat: allow non-reputable users to link (#2101)

* remove unused parameters

---------

Co-authored-by: clD11 <[email protected]>
  • Loading branch information
evq and clD11 authored Oct 11, 2023
1 parent 592bb42 commit f1282f3
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 103 deletions.
54 changes: 2 additions & 52 deletions services/wallet/controllers_v3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"testing"
"time"

"github.com/DATA-DOG/go-sqlmock"
sqlmock "github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand All @@ -34,7 +34,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/jmoiron/sqlx"
uuid "github.com/satori/go.uuid"
"gopkg.in/square/go-jose.v2"
jose "gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/jwt"
)

Expand Down Expand Up @@ -259,16 +259,6 @@ func TestLinkBitFlyerWalletV3(t *testing.T) {
ctx = context.WithValue(ctx, appctx.ReputationClientCTXKey, mockReputation)
ctx = context.WithValue(ctx, appctx.NoUnlinkPriorToDurationCTXKey, "-P1D")

mockReputation.EXPECT().IsLinkingReputable(
gomock.Any(), // ctx
gomock.Any(), // wallet id
gomock.Any(), // country
).Return(
true,
[]int{},
nil,
)

r = r.WithContext(ctx)

router := chi.NewRouter()
Expand Down Expand Up @@ -327,16 +317,6 @@ func TestLinkGeminiWalletV3RelinkBadRegion(t *testing.T) {
rw = httptest.NewRecorder()
)

mockReputationClient.EXPECT().IsLinkingReputable(
gomock.Any(), // ctx
gomock.Any(), // wallet id
gomock.Any(), // country
).Return(
true,
[]int{},
nil,
)

ctx = context.WithValue(ctx, appctx.DatastoreCTXKey, datastore)
ctx = context.WithValue(ctx, appctx.ReputationClientCTXKey, mockReputationClient)
ctx = context.WithValue(ctx, appctx.GeminiClientCTXKey, mockGeminiClient)
Expand Down Expand Up @@ -557,16 +537,6 @@ func TestLinkGeminiWalletV3FirstLinking(t *testing.T) {
rw = httptest.NewRecorder()
)

mockReputationClient.EXPECT().IsLinkingReputable(
gomock.Any(), // ctx
gomock.Any(), // wallet id
gomock.Any(), // country
).Return(
true,
[]int{},
nil,
)

ctx = context.WithValue(ctx, appctx.DatastoreCTXKey, datastore)
ctx = context.WithValue(ctx, appctx.ReputationClientCTXKey, mockReputationClient)
ctx = context.WithValue(ctx, appctx.GeminiClientCTXKey, mockGeminiClient)
Expand Down Expand Up @@ -770,16 +740,6 @@ func TestLinkZebPayWalletV3(t *testing.T) {
)),
)

mockReputationClient.EXPECT().IsLinkingReputable(
gomock.Any(), // ctx
gomock.Any(), // wallet id
gomock.Any(), // country
).Return(
true,
[]int{},
nil,
)

mockSQLCustodianLink(mock, "zebpay")

// begin linking tx
Expand Down Expand Up @@ -887,16 +847,6 @@ func TestLinkGeminiWalletV3(t *testing.T) {
nil,
)

mockReputationClient.EXPECT().IsLinkingReputable(
gomock.Any(), // ctx
gomock.Any(), // wallet id
gomock.Any(), // country
).Return(
true,
[]int{},
nil,
)

mockSQLCustodianLink(mock, "gemini")

// begin linking tx
Expand Down
41 changes: 2 additions & 39 deletions services/wallet/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func init() {
// Datastore holds the interface for the wallet datastore
type Datastore interface {
datastore.Datastore
LinkWallet(ctx context.Context, ID string, providerID string, providerLinkingID uuid.UUID, anonymousAddress *uuid.UUID, depositProvider, country string) error
LinkWallet(ctx context.Context, ID string, providerID string, providerLinkingID uuid.UUID, depositProvider string) error
GetLinkingLimitInfo(ctx context.Context, providerLinkingID string) (map[string]LinkingInfo, error)
HasPriorLinking(ctx context.Context, walletID uuid.UUID, providerLinkingID uuid.UUID) (bool, error)
// GetLinkingsByProviderLinkingID gets the wallet linking info by provider linking id
Expand Down Expand Up @@ -561,47 +561,10 @@ var (
)

// LinkWallet links a wallet together
func (pg *Postgres) LinkWallet(ctx context.Context, ID string, userDepositDestination string, providerLinkingID uuid.UUID, anonymousAddress *uuid.UUID, depositProvider, country string) error {
func (pg *Postgres) LinkWallet(ctx context.Context, ID string, userDepositDestination string, providerLinkingID uuid.UUID, depositProvider string) error {
sublogger := logger(ctx).With().Str("wallet_id", ID).Logger()
sublogger.Debug().Msg("linking wallet")

// rep check
if repClient, ok := ctx.Value(appctx.ReputationClientCTXKey).(reputation.Client); ok {
walletID, err := uuid.FromString(ID)
if err != nil {
sublogger.Warn().Err(err).Msg("invalid wallet id")
return fmt.Errorf("invalid wallet id, not uuid: %w", err)
}
// we have a client, check the value for ID
reputable, cohorts, err := repClient.IsLinkingReputable(ctx, walletID, country)
if err != nil {
sublogger.Warn().Err(err).Msg("failed to check reputation")
return fmt.Errorf("failed to check wallet rep: %w", err)
}

var (
isTooYoung = false
geoResetDifferent = false
)
for _, v := range cohorts {
if isTooYoung = (v == reputation.CohortTooYoung); isTooYoung {
break
}
if geoResetDifferent = (v == reputation.CohortGeoResetDifferent); geoResetDifferent {
break
}
}

if !reputable && !isTooYoung && !geoResetDifferent {
sublogger.Info().Msg("wallet linking attempt failed - unusual activity")
countLinkingFlaggedUnusual.Inc()
return ErrUnusualActivity
} else if geoResetDifferent {
sublogger.Info().Msg("wallet linking attempt failed - geo reset is different")
return ErrGeoResetDifferent
}
}

ctx, tx, rollback, commit, err := getTx(ctx, pg)
if err != nil {
sublogger.Error().Err(err).Msg("error getting tx")
Expand Down
6 changes: 3 additions & 3 deletions services/wallet/datastore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func (suite *WalletPostgresTestSuite) TestLinkWallet_Concurrent_InsertUpdate() {
go func() {
defer wg.Done()
err = pg.LinkWallet(context.WithValue(context.Background(), appctx.NoUnlinkPriorToDurationCTXKey, "-P1D"),
walletInfo.ID, userDepositDestination, providerLinkingID, walletInfo.AnonymousAddress, walletInfo.Provider, "")
walletInfo.ID, userDepositDestination, providerLinkingID, walletInfo.Provider)
}()
}

Expand Down Expand Up @@ -260,7 +260,7 @@ func (suite *WalletPostgresTestSuite) seedWallet(pg Datastore) (string, uuid.UUI
suite.Require().NoError(err, "save wallet should succeed")

err = pg.LinkWallet(context.WithValue(context.Background(), appctx.NoUnlinkPriorToDurationCTXKey, "-P1D"),
walletInfo.ID, userDepositDestination, providerLinkingID, walletInfo.AnonymousAddress, "uphold", "")
walletInfo.ID, userDepositDestination, providerLinkingID, "uphold")
suite.Require().NoError(err, "link wallet should succeed")
}

Expand Down Expand Up @@ -303,7 +303,7 @@ func (suite *WalletPostgresTestSuite) TestLinkWallet_Concurrent_MaxLinkCount() {
go func(index int) {
defer wg.Done()
err = pg.LinkWallet(context.WithValue(context.Background(), appctx.NoUnlinkPriorToDurationCTXKey, "-P1D"),
wallets[index].ID, userDepositDestination, providerLinkingID, wallets[index].AnonymousAddress, wallets[index].Provider, "")
wallets[index].ID, userDepositDestination, providerLinkingID, wallets[index].Provider)
}(i)
}

Expand Down
8 changes: 4 additions & 4 deletions services/wallet/instrumented_datastore.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions services/wallet/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ func (service *Service) LinkBitFlyerWallet(ctx context.Context, walletID uuid.UU
// we also validated that this "info" signed the request to perform the linking with http signature
// we assume that since we got linkingInfo signed from BF that they are KYC
providerLinkingID := uuid.NewV5(ClaimNamespace, accountHash)
err = service.Datastore.LinkWallet(ctx, walletID.String(), depositID, providerLinkingID, nil, depositProvider, country)
err = service.Datastore.LinkWallet(ctx, walletID.String(), depositID, providerLinkingID, depositProvider)
if err != nil {
if errors.Is(err, ErrUnusualActivity) {
return "", handlers.WrapError(err, "unable to link - unusual activity", http.StatusBadRequest)
Expand Down Expand Up @@ -497,7 +497,7 @@ func (service *Service) LinkZebPayWallet(ctx context.Context, walletID uuid.UUID
}

providerLinkingID := uuid.NewV5(ClaimNamespace, claims.AccountID)
if err := service.Datastore.LinkWallet(ctx, walletID.String(), claims.DepositID, providerLinkingID, nil, depositProvider, country); err != nil {
if err := service.Datastore.LinkWallet(ctx, walletID.String(), claims.DepositID, providerLinkingID, depositProvider); err != nil {
if errors.Is(err, ErrUnusualActivity) {
return "", handlers.WrapError(err, "unable to link - unusual activity", http.StatusBadRequest)
}
Expand Down Expand Up @@ -567,7 +567,7 @@ func (service *Service) LinkGeminiWallet(ctx context.Context, walletID uuid.UUID

// we assume that since we got linking_info(VerificationToken) signed from Gemini that they are KYC
providerLinkingID := uuid.NewV5(ClaimNamespace, accountID)
err = service.Datastore.LinkWallet(ctx, walletID.String(), depositID, providerLinkingID, nil, depositProvider, country)
err = service.Datastore.LinkWallet(ctx, walletID.String(), depositID, providerLinkingID, depositProvider)
if err != nil {
if errors.Is(err, ErrUnusualActivity) {
return "", handlers.WrapError(err, "unable to link - unusual activity", http.StatusBadRequest)
Expand All @@ -589,7 +589,7 @@ func (service *Service) LinkGeminiWallet(ctx context.Context, walletID uuid.UUID
}

// LinkUpholdWallet links an uphold.Wallet and transfers funds.
func (service *Service) LinkUpholdWallet(ctx context.Context, wallet uphold.Wallet, transaction string, anonymousAddress *uuid.UUID) (string, error) {
func (service *Service) LinkUpholdWallet(ctx context.Context, wallet uphold.Wallet, transaction string, _ *uuid.UUID) (string, error) {
const depositProvider = "uphold"
// do not confirm this transaction yet
info := wallet.GetWalletInfo()
Expand Down Expand Up @@ -669,7 +669,7 @@ func (service *Service) LinkUpholdWallet(ctx context.Context, wallet uphold.Wall

providerLinkingID := uuid.NewV5(ClaimNamespace, userID)
// tx.Destination will be stored as UserDepositDestination in the wallet info upon linking
err = service.Datastore.LinkWallet(ctx, info.ID, transactionInfo.Destination, providerLinkingID, anonymousAddress, depositProvider, country)
err = service.Datastore.LinkWallet(ctx, info.ID, transactionInfo.Destination, providerLinkingID, depositProvider)
if err != nil {
if errors.Is(err, ErrUnusualActivity) {
return "", handlers.WrapError(err, "unable to link - unusual activity", http.StatusBadRequest)
Expand Down

0 comments on commit f1282f3

Please sign in to comment.