satellite/{db,console,billing}: fix legal/violation freeze
This change fixes the behavior of legal freeze; it now does not allow lists and deletes for users in that freeze. It also fixes an issue where users who have been legal/violation frozen will have their limits upgraded, partially exiting freeze status when they pay with STORJ tokens. Issue: storj/storj-private/#517 storj/storj-private/#515 Change-Id: I6fa2b6353159984883c60a2888617da1ee51ce0a
This commit is contained in:
parent
e1c12674c5
commit
0590eadc17
@ -199,7 +199,8 @@ func TestProjectLimitCache(t *testing.T) {
|
||||
require.EqualValues(t, expectedSegmentLimit, *actualSegmentLimitFromDB)
|
||||
|
||||
// rate and burst limit
|
||||
require.NoError(t, projects.UpdateRateLimit(ctx, secondTestProject.ID, expectedRateLimit))
|
||||
rateLimit := expectedRateLimit
|
||||
require.NoError(t, projects.UpdateRateLimit(ctx, secondTestProject.ID, &rateLimit))
|
||||
require.NoError(t, projects.UpdateBurstLimit(ctx, secondTestProject.ID, expectedBurstLimit))
|
||||
|
||||
limits, err := projectLimitCache.GetLimits(ctx, secondTestProject.ID)
|
||||
|
@ -248,7 +248,7 @@ func (server *Server) putProjectLimit(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = server.db.Console().Projects().UpdateRateLimit(ctx, project.ID, *arguments.Rate)
|
||||
err = server.db.Console().Projects().UpdateRateLimit(ctx, project.ID, arguments.Rate)
|
||||
if err != nil {
|
||||
sendJSONError(w, "failed to update rate",
|
||||
err.Error(), http.StatusInternalServerError)
|
||||
|
@ -556,6 +556,11 @@ func (s *AccountFreezeService) LegalFreezeUser(ctx context.Context, userID uuid.
|
||||
return errs.New("User is already frozen due to ToS violation")
|
||||
}
|
||||
|
||||
var limits *AccountFreezeEventLimits
|
||||
if freezes.BillingFreeze != nil {
|
||||
limits = freezes.BillingFreeze.Limits
|
||||
}
|
||||
|
||||
userLimits := UsageLimits{
|
||||
Storage: user.ProjectStorageLimit,
|
||||
Bandwidth: user.ProjectBandwidthLimit,
|
||||
@ -564,13 +569,16 @@ func (s *AccountFreezeService) LegalFreezeUser(ctx context.Context, userID uuid.
|
||||
|
||||
legalFreeze := freezes.LegalFreeze
|
||||
if legalFreeze == nil {
|
||||
if limits == nil {
|
||||
limits = &AccountFreezeEventLimits{
|
||||
User: userLimits,
|
||||
Projects: make(map[uuid.UUID]UsageLimits),
|
||||
}
|
||||
}
|
||||
legalFreeze = &AccountFreezeEvent{
|
||||
UserID: userID,
|
||||
Type: LegalFreeze,
|
||||
Limits: &AccountFreezeEventLimits{
|
||||
User: userLimits,
|
||||
Projects: make(map[uuid.UUID]UsageLimits),
|
||||
},
|
||||
Limits: limits,
|
||||
}
|
||||
}
|
||||
|
||||
@ -595,9 +603,15 @@ func (s *AccountFreezeService) LegalFreezeUser(ctx context.Context, userID uuid.
|
||||
projLimits.Segment = *p.SegmentLimit
|
||||
}
|
||||
// If project limits have been zeroed already, we should not override what is in the freeze table.
|
||||
if projLimits != (UsageLimits{}) {
|
||||
legalFreeze.Limits.Projects[p.ID] = projLimits
|
||||
if projLimits == (UsageLimits{}) {
|
||||
if freezes.BillingFreeze == nil {
|
||||
continue
|
||||
}
|
||||
// if limits were zeroed in a billing freeze, we should use those
|
||||
projLimits = freezes.BillingFreeze.Limits.Projects[p.ID]
|
||||
}
|
||||
projLimits.RateLimit = p.RateLimit
|
||||
legalFreeze.Limits.Projects[p.ID] = projLimits
|
||||
}
|
||||
|
||||
_, err = tx.AccountFreezeEvents().Upsert(ctx, legalFreeze)
|
||||
@ -615,6 +629,13 @@ func (s *AccountFreezeService) LegalFreezeUser(ctx context.Context, userID uuid.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// zero project's rate limit to prevent lists/deletes
|
||||
zeroLimit := 0
|
||||
err = tx.Projects().UpdateRateLimit(ctx, proj.ID, &zeroLimit)
|
||||
if err != nil {
|
||||
return ErrAccountFreeze.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
if freezes.BillingWarning != nil {
|
||||
@ -662,6 +683,12 @@ func (s *AccountFreezeService) LegalUnfreezeUser(ctx context.Context, userID uui
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove rate limit
|
||||
err = tx.Projects().UpdateRateLimit(ctx, id, limits.RateLimit)
|
||||
if err != nil {
|
||||
return ErrAccountFreeze.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Users().UpdateUserProjectLimits(ctx, userID, event.Limits.User)
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/satellite"
|
||||
"storj.io/storj/satellite/console"
|
||||
"storj.io/uplink"
|
||||
)
|
||||
|
||||
func getUserLimits(u *console.User) console.UsageLimits {
|
||||
@ -31,6 +32,7 @@ func getProjectLimits(p *console.Project) console.UsageLimits {
|
||||
Storage: p.StorageLimit.Int64(),
|
||||
Bandwidth: p.BandwidthLimit.Int64(),
|
||||
Segment: *p.SegmentLimit,
|
||||
RateLimit: p.RateLimit,
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,18 +263,26 @@ func TestAccountLegalFreeze(t *testing.T) {
|
||||
require.NoError(t, usersDB.UpdateUserProjectLimits(ctx, user.ID, userLimits))
|
||||
|
||||
projLimits := randUsageLimits()
|
||||
rateLimit := 20000
|
||||
projLimits.RateLimit = &rateLimit
|
||||
proj, err := sat.AddProject(ctx, user.ID, "")
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, projectsDB.UpdateUsageLimits(ctx, proj.ID, projLimits))
|
||||
require.NoError(t, projectsDB.UpdateRateLimit(ctx, proj.ID, projLimits.RateLimit))
|
||||
|
||||
checkLimits := func(testT *testing.T) {
|
||||
checkLimits := func(t *testing.T) {
|
||||
user, err = usersDB.Get(ctx, user.ID)
|
||||
require.NoError(t, err)
|
||||
require.Zero(t, getUserLimits(user))
|
||||
|
||||
proj, err = projectsDB.Get(ctx, proj.ID)
|
||||
require.NoError(t, err)
|
||||
require.Zero(t, getProjectLimits(proj))
|
||||
usageLimits := getProjectLimits(proj)
|
||||
require.Zero(t, usageLimits.Segment)
|
||||
require.Zero(t, usageLimits.Storage)
|
||||
require.Zero(t, usageLimits.Bandwidth)
|
||||
zeroLimit := 0
|
||||
require.Equal(t, &zeroLimit, usageLimits.RateLimit)
|
||||
}
|
||||
|
||||
frozen, err := service.IsUserFrozen(ctx, user.ID, console.LegalFreeze)
|
||||
@ -322,6 +332,16 @@ func TestAccountLegalFreeze(t *testing.T) {
|
||||
require.Nil(t, freezes.LegalFreeze.DaysTillEscalation)
|
||||
|
||||
checkLimits(t)
|
||||
|
||||
require.NoError(t, service.LegalUnfreezeUser(ctx, user.ID))
|
||||
|
||||
user, err = usersDB.Get(ctx, user.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, userLimits, getUserLimits(user))
|
||||
|
||||
proj, err = projectsDB.Get(ctx, proj.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, projLimits, getProjectLimits(proj))
|
||||
})
|
||||
}
|
||||
|
||||
@ -490,6 +510,9 @@ func TestFreezeEffects(t *testing.T) {
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
config.AccountFreeze.Enabled = true
|
||||
// disable limit caching
|
||||
config.ProjectLimit.CacheCapacity = 0
|
||||
config.Metainfo.RateLimiter.CacheCapacity = 0
|
||||
},
|
||||
},
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
@ -520,67 +543,86 @@ func TestFreezeEffects(t *testing.T) {
|
||||
shouldNotUploadAndDownload := func(testT *testing.T) {
|
||||
// Should not be able to upload because account is frozen.
|
||||
err = uplink1.Upload(ctx, sat, bucketName, path, expectedData)
|
||||
require.Error(t, err)
|
||||
require.Error(testT, err)
|
||||
|
||||
// Should not be able to download because account is frozen.
|
||||
_, err = uplink1.Download(ctx, sat, bucketName, path)
|
||||
require.Error(t, err)
|
||||
require.Error(testT, err)
|
||||
|
||||
// Should not be able to create bucket because account is frozen.
|
||||
err = uplink1.CreateBucket(ctx, sat, "anotherBucket")
|
||||
require.Error(t, err)
|
||||
require.Error(testT, err)
|
||||
}
|
||||
|
||||
shouldListAndDelete := func(testT *testing.T) {
|
||||
// Should be able to list even if frozen.
|
||||
objects, err := uplink1.ListObjects(ctx, sat, bucketName)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, objects, 1)
|
||||
_, err := uplink1.ListObjects(ctx, sat, bucketName)
|
||||
require.NoError(testT, err)
|
||||
|
||||
// Should be able to delete even if frozen.
|
||||
err = uplink1.DeleteObject(ctx, sat, bucketName, path)
|
||||
require.NoError(t, err)
|
||||
require.NoError(testT, err)
|
||||
}
|
||||
|
||||
shouldNotListAndDelete := func(testT *testing.T) {
|
||||
// Should not be able to list.
|
||||
_, err := uplink1.ListObjects(ctx, sat, bucketName)
|
||||
require.Error(testT, err)
|
||||
require.ErrorIs(testT, err, uplink.ErrTooManyRequests)
|
||||
|
||||
// Should not be able to delete.
|
||||
err = uplink1.DeleteObject(ctx, sat, bucketName, path)
|
||||
require.Error(testT, err)
|
||||
require.ErrorIs(testT, err, uplink.ErrTooManyRequests)
|
||||
}
|
||||
|
||||
t.Run("BillingFreeze effect on project owner", func(t *testing.T) {
|
||||
shouldUploadAndDownload(t)
|
||||
shouldListAndDelete(t)
|
||||
|
||||
require.NoError(t, freezeService.BillingWarnUser(ctx, user1.ID))
|
||||
|
||||
// Should be able to download because account is not frozen.
|
||||
// Should be able to download and list because account is not frozen.
|
||||
shouldUploadAndDownload(t)
|
||||
shouldListAndDelete(t)
|
||||
|
||||
require.NoError(t, freezeService.BillingFreezeUser(ctx, user1.ID))
|
||||
|
||||
shouldNotUploadAndDownload(t)
|
||||
|
||||
shouldListAndDelete(t)
|
||||
|
||||
require.NoError(t, freezeService.BillingUnfreezeUser(ctx, user1.ID))
|
||||
|
||||
shouldUploadAndDownload(t)
|
||||
})
|
||||
|
||||
t.Run("ViolationFreeze effect on project owner", func(t *testing.T) {
|
||||
shouldUploadAndDownload(t)
|
||||
shouldListAndDelete(t)
|
||||
|
||||
require.NoError(t, freezeService.ViolationFreezeUser(ctx, user1.ID))
|
||||
|
||||
shouldNotUploadAndDownload(t)
|
||||
|
||||
shouldListAndDelete(t)
|
||||
|
||||
require.NoError(t, freezeService.ViolationUnfreezeUser(ctx, user1.ID))
|
||||
|
||||
shouldUploadAndDownload(t)
|
||||
})
|
||||
|
||||
t.Run("LegalFreeze effect on project owner", func(t *testing.T) {
|
||||
shouldUploadAndDownload(t)
|
||||
shouldListAndDelete(t)
|
||||
|
||||
require.NoError(t, freezeService.LegalFreezeUser(ctx, user1.ID))
|
||||
|
||||
shouldNotUploadAndDownload(t)
|
||||
|
||||
shouldListAndDelete(t)
|
||||
shouldNotListAndDelete(t)
|
||||
|
||||
require.NoError(t, freezeService.LegalUnfreezeUser(ctx, user1.ID))
|
||||
|
||||
shouldListAndDelete(t)
|
||||
shouldUploadAndDownload(t)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -18,15 +18,17 @@ type UpgradeUserObserver struct {
|
||||
transactionsDB billing.TransactionsDB
|
||||
usageLimitsConfig UsageLimitsConfig
|
||||
userBalanceForUpgrade int64
|
||||
freezeService *AccountFreezeService
|
||||
}
|
||||
|
||||
// NewUpgradeUserObserver creates new observer instance.
|
||||
func NewUpgradeUserObserver(consoleDB DB, transactionsDB billing.TransactionsDB, usageLimitsConfig UsageLimitsConfig, userBalanceForUpgrade int64) *UpgradeUserObserver {
|
||||
func NewUpgradeUserObserver(consoleDB DB, transactionsDB billing.TransactionsDB, usageLimitsConfig UsageLimitsConfig, userBalanceForUpgrade int64, freezeService *AccountFreezeService) *UpgradeUserObserver {
|
||||
return &UpgradeUserObserver{
|
||||
consoleDB: consoleDB,
|
||||
transactionsDB: transactionsDB,
|
||||
usageLimitsConfig: usageLimitsConfig,
|
||||
userBalanceForUpgrade: userBalanceForUpgrade,
|
||||
freezeService: freezeService,
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +36,16 @@ func NewUpgradeUserObserver(consoleDB DB, transactionsDB billing.TransactionsDB,
|
||||
func (o *UpgradeUserObserver) Process(ctx context.Context, transaction billing.Transaction) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
freezes, err := o.freezeService.GetAll(ctx, transaction.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if freezes.LegalFreeze != nil || freezes.ViolationFreeze != nil {
|
||||
// user can not exit these freezes by paying with tokens
|
||||
return nil
|
||||
}
|
||||
|
||||
user, err := o.consoleDB.Users().Get(ctx, transaction.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -43,7 +43,7 @@ type Projects interface {
|
||||
ListByOwnerID(ctx context.Context, userID uuid.UUID, cursor ProjectsCursor) (ProjectsPage, error)
|
||||
|
||||
// UpdateRateLimit is a method for updating projects rate limit.
|
||||
UpdateRateLimit(ctx context.Context, id uuid.UUID, newLimit int) error
|
||||
UpdateRateLimit(ctx context.Context, id uuid.UUID, newLimit *int) error
|
||||
|
||||
// UpdateBurstLimit is a method for updating projects burst limit.
|
||||
UpdateBurstLimit(ctx context.Context, id uuid.UUID, newLimit int) error
|
||||
|
@ -442,7 +442,7 @@ func TestRateLimit_ProjectRateLimitZero(t *testing.T) {
|
||||
require.Len(t, projects, 1)
|
||||
|
||||
zeroRateLimit := 0
|
||||
err = satellite.DB.Console().Projects().UpdateRateLimit(ctx, projects[0].ID, zeroRateLimit)
|
||||
err = satellite.DB.Console().Projects().UpdateRateLimit(ctx, projects[0].ID, &zeroRateLimit)
|
||||
require.NoError(t, err)
|
||||
|
||||
var group errs2.Group
|
||||
|
@ -24,4 +24,5 @@ type UsageLimits struct {
|
||||
Storage int64 `json:"storage"`
|
||||
Bandwidth int64 `json:"bandwidth"`
|
||||
Segment int64 `json:"segment"`
|
||||
RateLimit *int `json:"rateLimit"`
|
||||
}
|
||||
|
@ -525,15 +525,12 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB,
|
||||
debug.Cycle("Payments Storjscan", peer.Payments.StorjscanChore.TransactionCycle),
|
||||
)
|
||||
|
||||
freezeService := console.NewAccountFreezeService(peer.DB.Console(), peer.Analytics.Service, config.Console.AccountFreeze)
|
||||
choreObservers := billing.ChoreObservers{
|
||||
UpgradeUser: console.NewUpgradeUserObserver(peer.DB.Console(), peer.DB.Billing(), config.Console.UsageLimits, config.Console.UserBalanceForUpgrade),
|
||||
UpgradeUser: console.NewUpgradeUserObserver(peer.DB.Console(), peer.DB.Billing(), config.Console.UsageLimits, config.Console.UserBalanceForUpgrade, freezeService),
|
||||
PayInvoices: console.NewInvoiceTokenPaymentObserver(
|
||||
peer.DB.Console(), peer.Payments.Accounts.Invoices(),
|
||||
console.NewAccountFreezeService(
|
||||
peer.DB.Console(),
|
||||
peer.Analytics.Service,
|
||||
config.Console.AccountFreeze,
|
||||
),
|
||||
freezeService,
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ func TestChore(t *testing.T) {
|
||||
assert.Equal(t, expected, actual, "unexpected balance for user %s (%q)", userID, names[userID])
|
||||
}
|
||||
|
||||
runTest := func(ctx *testcontext.Context, t *testing.T, consoleDB console.DB, db billing.TransactionsDB, bonusRate int64, mikeTXs, joeTXs, robertTXs []billing.Transaction, mikeBalance, joeBalance, robertBalance currency.Amount, usageLimitsConfig console.UsageLimitsConfig, userBalanceForUpgrade int64) {
|
||||
runTest := func(ctx *testcontext.Context, t *testing.T, consoleDB console.DB, db billing.TransactionsDB, bonusRate int64, mikeTXs, joeTXs, robertTXs []billing.Transaction, mikeBalance, joeBalance, robertBalance currency.Amount, usageLimitsConfig console.UsageLimitsConfig, userBalanceForUpgrade int64, freezeService *console.AccountFreezeService) {
|
||||
paymentTypes := []billing.PaymentType{
|
||||
newFakePaymentType(billing.StorjScanSource,
|
||||
[]billing.Transaction{mike1, joe1, joe2},
|
||||
@ -88,7 +88,7 @@ func TestChore(t *testing.T) {
|
||||
}
|
||||
|
||||
choreObservers := billing.ChoreObservers{
|
||||
UpgradeUser: console.NewUpgradeUserObserver(consoleDB, db, usageLimitsConfig, userBalanceForUpgrade),
|
||||
UpgradeUser: console.NewUpgradeUserObserver(consoleDB, db, usageLimitsConfig, userBalanceForUpgrade, freezeService),
|
||||
}
|
||||
|
||||
chore := billing.NewChore(zaptest.NewLogger(t), paymentTypes, db, time.Hour, false, bonusRate, choreObservers)
|
||||
@ -118,6 +118,8 @@ func TestChore(t *testing.T) {
|
||||
sat := planet.Satellites[0]
|
||||
db := sat.DB
|
||||
|
||||
freezeService := console.NewAccountFreezeService(db.Console(), sat.Core.Analytics.Service, sat.Config.Console.AccountFreeze)
|
||||
|
||||
runTest(ctx, t, db.Console(), db.Billing(), 0,
|
||||
[]billing.Transaction{mike2, mike1},
|
||||
[]billing.Transaction{joe1, joe2},
|
||||
@ -127,6 +129,7 @@ func TestChore(t *testing.T) {
|
||||
currency.AmountFromBaseUnits(30000000, currency.USDollarsMicro),
|
||||
sat.Config.Console.UsageLimits,
|
||||
sat.Config.Console.UserBalanceForUpgrade,
|
||||
freezeService,
|
||||
)
|
||||
})
|
||||
})
|
||||
@ -138,6 +141,8 @@ func TestChore(t *testing.T) {
|
||||
sat := planet.Satellites[0]
|
||||
db := sat.DB
|
||||
|
||||
freezeService := console.NewAccountFreezeService(db.Console(), sat.Core.Analytics.Service, sat.Config.Console.AccountFreeze)
|
||||
|
||||
runTest(ctx, t, db.Console(), db.Billing(), 10,
|
||||
[]billing.Transaction{mike2, mike2Bonus, mike1, mike1Bonus},
|
||||
[]billing.Transaction{joe1, joe1Bonus, joe2},
|
||||
@ -147,6 +152,7 @@ func TestChore(t *testing.T) {
|
||||
currency.AmountFromBaseUnits(30000000, currency.USDollarsMicro),
|
||||
sat.Config.Console.UsageLimits,
|
||||
sat.Config.Console.UserBalanceForUpgrade,
|
||||
freezeService,
|
||||
)
|
||||
})
|
||||
})
|
||||
@ -161,29 +167,48 @@ func TestChore_UpgradeUserObserver(t *testing.T) {
|
||||
usageLimitsConfig := sat.Config.Console.UsageLimits
|
||||
ts := makeTimestamp()
|
||||
|
||||
freezeService := console.NewAccountFreezeService(db.Console(), sat.Core.Analytics.Service, sat.Config.Console.AccountFreeze)
|
||||
|
||||
user, err := sat.AddUser(ctx, console.CreateUser{
|
||||
FullName: "Test User",
|
||||
Email: "choreobserver@mail.test",
|
||||
}, 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
user2, err := sat.AddUser(ctx, console.CreateUser{
|
||||
FullName: "Test User",
|
||||
Email: "choreobserver2@mail.test",
|
||||
}, 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
user3, err := sat.AddUser(ctx, console.CreateUser{
|
||||
FullName: "Test User",
|
||||
Email: "choreobserver3@mail.test",
|
||||
}, 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = sat.AddProject(ctx, user.ID, "Test Project")
|
||||
require.NoError(t, err)
|
||||
|
||||
choreObservers := billing.ChoreObservers{
|
||||
UpgradeUser: console.NewUpgradeUserObserver(db.Console(), db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade),
|
||||
UpgradeUser: console.NewUpgradeUserObserver(db.Console(), db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade, freezeService),
|
||||
}
|
||||
|
||||
amount1 := int64(200) // $2
|
||||
amount2 := int64(800) // $8
|
||||
transaction1 := makeFakeTransaction(user.ID, billing.StorjScanSource, billing.TransactionTypeCredit, amount1, ts, `{"fake": "transaction1"}`)
|
||||
transaction2 := makeFakeTransaction(user.ID, billing.StorjScanSource, billing.TransactionTypeCredit, amount2, ts.Add(time.Second*2), `{"fake": "transaction2"}`)
|
||||
transaction3 := makeFakeTransaction(user2.ID, billing.StorjScanSource, billing.TransactionTypeCredit, amount1+amount2, ts, `{"fake": "transaction3"}`)
|
||||
transaction4 := makeFakeTransaction(user3.ID, billing.StorjScanSource, billing.TransactionTypeCredit, amount1+amount2, ts.Add(time.Second*2), `{"fake": "transaction4"}`)
|
||||
paymentTypes := []billing.PaymentType{
|
||||
newFakePaymentType(billing.StorjScanSource,
|
||||
[]billing.Transaction{transaction1},
|
||||
[]billing.Transaction{},
|
||||
[]billing.Transaction{transaction2},
|
||||
[]billing.Transaction{},
|
||||
[]billing.Transaction{transaction3},
|
||||
[]billing.Transaction{transaction4},
|
||||
[]billing.Transaction{},
|
||||
),
|
||||
}
|
||||
|
||||
@ -241,6 +266,39 @@ func TestChore_UpgradeUserObserver(t *testing.T) {
|
||||
require.Equal(t, usageLimitsConfig.Segment.Paid, *p.SegmentLimit)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("no upgrade for legal/violation freeze", func(t *testing.T) {
|
||||
require.NoError(t, freezeService.LegalFreezeUser(ctx, user2.ID))
|
||||
require.NoError(t, freezeService.ViolationFreezeUser(ctx, user3.ID))
|
||||
|
||||
chore.TransactionCycle.TriggerWait()
|
||||
chore.TransactionCycle.Pause()
|
||||
|
||||
expected := currency.AmountFromBaseUnits((amount1+amount2)*int64(10000), currency.USDollarsMicro)
|
||||
|
||||
chore.TransactionCycle.TriggerWait()
|
||||
chore.TransactionCycle.Pause()
|
||||
|
||||
balance, err := db.Billing().GetBalance(ctx, user2.ID)
|
||||
require.NoError(t, err)
|
||||
require.True(t, expected.Equal(balance))
|
||||
|
||||
chore.TransactionCycle.TriggerWait()
|
||||
|
||||
balance, err = db.Billing().GetBalance(ctx, user3.ID)
|
||||
require.NoError(t, err)
|
||||
require.True(t, expected.Equal(balance))
|
||||
|
||||
// users should not be upgraded though they have enough balance
|
||||
// since they are in legal/violation freeze.
|
||||
user, err = db.Console().Users().Get(ctx, user2.ID)
|
||||
require.NoError(t, err)
|
||||
require.False(t, user.PaidTier)
|
||||
|
||||
user, err = db.Console().Users().Get(ctx, user3.ID)
|
||||
require.NoError(t, err)
|
||||
require.False(t, user.PaidTier)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -275,7 +333,7 @@ func TestChore_PayInvoiceObserver(t *testing.T) {
|
||||
freezeService := console.NewAccountFreezeService(consoleDB, sat.Core.Analytics.Service, sat.Config.Console.AccountFreeze)
|
||||
|
||||
choreObservers := billing.ChoreObservers{
|
||||
UpgradeUser: console.NewUpgradeUserObserver(consoleDB, db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade),
|
||||
UpgradeUser: console.NewUpgradeUserObserver(consoleDB, db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade, freezeService),
|
||||
PayInvoices: console.NewInvoiceTokenPaymentObserver(consoleDB, sat.Core.Payments.Accounts.Invoices(), freezeService),
|
||||
}
|
||||
|
||||
|
@ -265,17 +265,22 @@ func (projects *projects) Update(ctx context.Context, project *console.Project)
|
||||
}
|
||||
|
||||
// UpdateRateLimit is a method for updating projects rate limit.
|
||||
func (projects *projects) UpdateRateLimit(ctx context.Context, id uuid.UUID, newLimit int) (err error) {
|
||||
func (projects *projects) UpdateRateLimit(ctx context.Context, id uuid.UUID, newLimit *int) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
if newLimit < 0 {
|
||||
if newLimit != nil && *newLimit < 0 {
|
||||
return Error.New("limit can't be set to negative value")
|
||||
}
|
||||
|
||||
rateLimit := dbx.Project_RateLimit_Null()
|
||||
if newLimit != nil {
|
||||
rateLimit = dbx.Project_RateLimit(*newLimit)
|
||||
}
|
||||
|
||||
_, err = projects.db.Update_Project_By_Id(ctx,
|
||||
dbx.Project_Id(id[:]),
|
||||
dbx.Project_Update_Fields{
|
||||
RateLimit: dbx.Project_RateLimit(newLimit),
|
||||
RateLimit: rateLimit,
|
||||
})
|
||||
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user