From cd7d9cf079f8f1ffc699f86bd0fbd0201450876f Mon Sep 17 00:00:00 2001 From: Wilfred Asomani Date: Thu, 7 Sep 2023 16:38:24 +0000 Subject: [PATCH] satellite/{console,payments}: unfreeze user on token payment This change unfreezes/unwarns users in either state after successful payment with tokens. Change-Id: I7494d6a33cf9383576f42af695df522d8f409e03 --- .../console/observerpayinvoicewithtokens.go | 46 ++++++++++++++++--- satellite/core.go | 10 +++- satellite/payments/billing/chore_test.go | 20 +++++++- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/satellite/console/observerpayinvoicewithtokens.go b/satellite/console/observerpayinvoicewithtokens.go index 091ba105d..556e646b5 100644 --- a/satellite/console/observerpayinvoicewithtokens.go +++ b/satellite/console/observerpayinvoicewithtokens.go @@ -14,15 +14,17 @@ var _ billing.Observer = (*InvoiceTokenPaymentObserver)(nil) // InvoiceTokenPaymentObserver used to pay pending payments with STORJ tokens. type InvoiceTokenPaymentObserver struct { - consoleDB DB - payments payments.Accounts + consoleDB DB + invoices payments.Invoices + freezeService *AccountFreezeService } // NewInvoiceTokenPaymentObserver creates new observer instance. -func NewInvoiceTokenPaymentObserver(consoleDB DB, payments payments.Accounts) *InvoiceTokenPaymentObserver { +func NewInvoiceTokenPaymentObserver(consoleDB DB, invoices payments.Invoices, freezeService *AccountFreezeService) *InvoiceTokenPaymentObserver { return &InvoiceTokenPaymentObserver{ - consoleDB: consoleDB, - payments: payments, + consoleDB: consoleDB, + invoices: invoices, + freezeService: freezeService, } } @@ -39,10 +41,42 @@ func (o *InvoiceTokenPaymentObserver) Process(ctx context.Context, transaction b return nil } - err = o.payments.Invoices().AttemptPayOverdueInvoicesWithTokens(ctx, user.ID) + err = o.invoices.AttemptPayOverdueInvoicesWithTokens(ctx, user.ID) if err != nil { return err } + freeze, warning, err := o.freezeService.GetAll(ctx, user.ID) + if err != nil { + return err + } + + if freeze == nil && warning == nil { + return nil + } + + invoices, err := o.invoices.List(ctx, user.ID) + if err != nil { + return err + } + + for _, inv := range invoices { + if inv.Status != payments.InvoiceStatusPaid { + return nil + } + } + + if freeze != nil { + err = o.freezeService.UnfreezeUser(ctx, user.ID) + if err != nil { + return err + } + } else if warning != nil { + err = o.freezeService.UnWarnUser(ctx, user.ID) + if err != nil { + return err + } + } + return nil } diff --git a/satellite/core.go b/satellite/core.go index 8db8b414c..59287d765 100644 --- a/satellite/core.go +++ b/satellite/core.go @@ -521,7 +521,15 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, choreObservers := billing.ChoreObservers{ UpgradeUser: console.NewUpgradeUserObserver(peer.DB.Console(), peer.DB.Billing(), config.Console.UsageLimits, config.Console.UserBalanceForUpgrade), - PayInvoices: console.NewInvoiceTokenPaymentObserver(peer.DB.Console(), peer.Payments.Accounts), + PayInvoices: console.NewInvoiceTokenPaymentObserver( + peer.DB.Console(), peer.Payments.Accounts.Invoices(), + console.NewAccountFreezeService( + peer.DB.Console().AccountFreezeEvents(), + peer.DB.Console().Users(), + peer.DB.Console().Projects(), + peer.Analytics.Service, + ), + ), } peer.Payments.BillingChore = billing.NewChore( diff --git a/satellite/payments/billing/chore_test.go b/satellite/payments/billing/chore_test.go index 72928f9c4..729c47aa0 100644 --- a/satellite/payments/billing/chore_test.go +++ b/satellite/payments/billing/chore_test.go @@ -250,6 +250,7 @@ func TestChore_PayInvoiceObserver(t *testing.T) { }, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) { sat := planet.Satellites[0] db := sat.DB + consoleDB := db.Console() invoicesDB := sat.Core.Payments.Accounts.Invoices() stripeClient := sat.API.Payments.StripeClient customerDB := sat.Core.DB.StripeCoinPayments().Customers() @@ -271,9 +272,11 @@ func TestChore_PayInvoiceObserver(t *testing.T) { err = sat.DB.Wallets().Add(ctx, userID, address) require.NoError(t, err) + freezeService := console.NewAccountFreezeService(consoleDB.AccountFreezeEvents(), consoleDB.Users(), consoleDB.Projects(), sat.Core.Analytics.Service) + choreObservers := billing.ChoreObservers{ - UpgradeUser: console.NewUpgradeUserObserver(db.Console(), db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade), - PayInvoices: console.NewInvoiceTokenPaymentObserver(db.Console(), sat.Core.Payments.Accounts), + UpgradeUser: console.NewUpgradeUserObserver(consoleDB, db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade), + PayInvoices: console.NewInvoiceTokenPaymentObserver(consoleDB, sat.Core.Payments.Accounts.Invoices(), freezeService), } amount := int64(2000) // $20 @@ -328,6 +331,9 @@ func TestChore_PayInvoiceObserver(t *testing.T) { require.Equal(t, inv.ID, invoices[0].ID) require.Equal(t, string(inv.Status), invoices[0].Status) + err = freezeService.FreezeUser(ctx, userID) + require.NoError(t, err) + chore.TransactionCycle.TriggerWait() // user balance would've been the value of amount ($20) but @@ -342,6 +348,11 @@ func TestChore_PayInvoiceObserver(t *testing.T) { // invoice remains unpaid since only $20 was paid. require.Equal(t, string(stripe.InvoiceStatusOpen), invoices[0].Status) + // user remains frozen since payment is not complete. + frozen, err := freezeService.IsUserFrozen(ctx, userID) + require.NoError(t, err) + require.True(t, frozen) + chore.TransactionCycle.TriggerWait() // the second transaction of $10 reflects at this point and @@ -350,6 +361,11 @@ func TestChore_PayInvoiceObserver(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, invoices) require.Equal(t, string(stripe.InvoiceStatusPaid), invoices[0].Status) + + // user is not frozen since payment is complete. + frozen, err = freezeService.IsUserFrozen(ctx, userID) + require.NoError(t, err) + require.False(t, frozen) }) }