satellite/{console,satellitedb}: add account freeze service
This change adds an account freeze service with methods for checking if a user is frozen, freezing a user, and unfreezing a user. Furthermore, methods for altering the usage limits of a user or project have been implemented for use by the account freeze service. Change-Id: I77fecfac5c152f134bec90165acfe4f1dea957e7
This commit is contained in:
parent
7b851b42f7
commit
471f9e4e10
@ -5,21 +5,26 @@ package console
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeebo/errs"
|
||||||
|
|
||||||
"storj.io/common/uuid"
|
"storj.io/common/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrAccountFreeze is the class for errors that occur during operation of the account freeze service.
|
||||||
|
var ErrAccountFreeze = errs.Class("account freeze service")
|
||||||
|
|
||||||
// AccountFreezeEvents exposes methods to manage the account freeze events table in database.
|
// AccountFreezeEvents exposes methods to manage the account freeze events table in database.
|
||||||
//
|
//
|
||||||
// architecture: Database
|
// architecture: Database
|
||||||
type AccountFreezeEvents interface {
|
type AccountFreezeEvents interface {
|
||||||
// Insert is a method for inserting account freeze event into the database.
|
// Upsert is a method for updating an account freeze event if it exists and inserting it otherwise.
|
||||||
Insert(ctx context.Context, event *AccountFreezeEvent) (*AccountFreezeEvent, error)
|
Upsert(ctx context.Context, event *AccountFreezeEvent) (*AccountFreezeEvent, error)
|
||||||
// Get is a method for querying account freeze event from the database by user ID and event type.
|
// Get is a method for querying account freeze event from the database by user ID and event type.
|
||||||
Get(ctx context.Context, userID uuid.UUID, eventType AccountFreezeEventType) (*AccountFreezeEvent, error)
|
Get(ctx context.Context, userID uuid.UUID, eventType AccountFreezeEventType) (*AccountFreezeEvent, error)
|
||||||
// UpdateLimits is a method for updating the limits of an account freeze event by user ID and event type.
|
|
||||||
UpdateLimits(ctx context.Context, userID uuid.UUID, eventType AccountFreezeEventType, limits *AccountFreezeEventLimits) error
|
|
||||||
// DeleteAllByUserID is a method for deleting all account freeze events from the database by user ID.
|
// DeleteAllByUserID is a method for deleting all account freeze events from the database by user ID.
|
||||||
DeleteAllByUserID(ctx context.Context, userID uuid.UUID) error
|
DeleteAllByUserID(ctx context.Context, userID uuid.UUID) error
|
||||||
}
|
}
|
||||||
@ -47,3 +52,140 @@ const (
|
|||||||
// Warning signifies that the user has been warned that they may be frozen soon.
|
// Warning signifies that the user has been warned that they may be frozen soon.
|
||||||
Warning AccountFreezeEventType = 1
|
Warning AccountFreezeEventType = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AccountFreezeService encapsulates operations concerning account freezes.
|
||||||
|
type AccountFreezeService struct {
|
||||||
|
freezeEventsDB AccountFreezeEvents
|
||||||
|
usersDB Users
|
||||||
|
projectsDB Projects
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAccountFreezeService creates a new account freeze service.
|
||||||
|
func NewAccountFreezeService(freezeEventsDB AccountFreezeEvents, usersDB Users, projectsDB Projects) *AccountFreezeService {
|
||||||
|
return &AccountFreezeService{
|
||||||
|
freezeEventsDB: freezeEventsDB,
|
||||||
|
usersDB: usersDB,
|
||||||
|
projectsDB: projectsDB,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsUserFrozen returns whether the user specified by the given ID is frozen.
|
||||||
|
func (s *AccountFreezeService) IsUserFrozen(ctx context.Context, userID uuid.UUID) (_ bool, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
_, err = s.freezeEventsDB.Get(ctx, userID, Freeze)
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, sql.ErrNoRows):
|
||||||
|
return false, nil
|
||||||
|
case err != nil:
|
||||||
|
return false, ErrAccountFreeze.Wrap(err)
|
||||||
|
default:
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FreezeUser freezes the user specified by the given ID.
|
||||||
|
func (s *AccountFreezeService) FreezeUser(ctx context.Context, userID uuid.UUID) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
user, err := s.usersDB.Get(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
event, err := s.freezeEventsDB.Get(ctx, userID, Freeze)
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
event = &AccountFreezeEvent{
|
||||||
|
UserID: userID,
|
||||||
|
Type: Freeze,
|
||||||
|
Limits: &AccountFreezeEventLimits{
|
||||||
|
User: UsageLimits{
|
||||||
|
Storage: user.ProjectStorageLimit,
|
||||||
|
Bandwidth: user.ProjectBandwidthLimit,
|
||||||
|
Segment: user.ProjectSegmentLimit,
|
||||||
|
},
|
||||||
|
Projects: make(map[uuid.UUID]UsageLimits),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
userLimits := UsageLimits{
|
||||||
|
Storage: user.ProjectStorageLimit,
|
||||||
|
Bandwidth: user.ProjectBandwidthLimit,
|
||||||
|
Segment: user.ProjectSegmentLimit,
|
||||||
|
}
|
||||||
|
// If user limits have been zeroed already, we should not override what is in the freeze table.
|
||||||
|
if userLimits != (UsageLimits{}) {
|
||||||
|
event.Limits.User = userLimits
|
||||||
|
}
|
||||||
|
|
||||||
|
projects, err := s.projectsDB.GetOwn(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
for _, p := range projects {
|
||||||
|
projLimits := UsageLimits{}
|
||||||
|
if p.StorageLimit != nil {
|
||||||
|
projLimits.Storage = p.StorageLimit.Int64()
|
||||||
|
}
|
||||||
|
if p.BandwidthLimit != nil {
|
||||||
|
projLimits.Bandwidth = p.BandwidthLimit.Int64()
|
||||||
|
}
|
||||||
|
if p.SegmentLimit != nil {
|
||||||
|
projLimits.Segment = *p.SegmentLimit
|
||||||
|
}
|
||||||
|
// If project limits have been zeroed already, we should not override what is in the freeze table.
|
||||||
|
if projLimits != (UsageLimits{}) {
|
||||||
|
event.Limits.Projects[p.ID] = projLimits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.freezeEventsDB.Upsert(ctx, event)
|
||||||
|
if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.usersDB.UpdateUserProjectLimits(ctx, userID, UsageLimits{})
|
||||||
|
if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, proj := range projects {
|
||||||
|
err := s.projectsDB.UpdateUsageLimits(ctx, proj.ID, UsageLimits{})
|
||||||
|
if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnfreezeUser reverses the freeze placed on the user specified by the given ID.
|
||||||
|
func (s *AccountFreezeService) UnfreezeUser(ctx context.Context, userID uuid.UUID) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
event, err := s.freezeEventsDB.Get(ctx, userID, Freeze)
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
return ErrAccountFreeze.New("user is not frozen")
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Limits == nil {
|
||||||
|
return ErrAccountFreeze.New("freeze event limits are nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
for id, limits := range event.Limits.Projects {
|
||||||
|
err := s.projectsDB.UpdateUsageLimits(ctx, id, limits)
|
||||||
|
if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.usersDB.UpdateUserProjectLimits(ctx, userID, event.Limits.User)
|
||||||
|
if err != nil {
|
||||||
|
return ErrAccountFreeze.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrAccountFreeze.Wrap(s.freezeEventsDB.DeleteAllByUserID(ctx, userID))
|
||||||
|
}
|
||||||
|
210
satellite/console/accountfreezes_test.go
Normal file
210
satellite/console/accountfreezes_test.go
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
// Copyright (C) 2022 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package console_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"storj.io/common/testcontext"
|
||||||
|
"storj.io/storj/private/testplanet"
|
||||||
|
"storj.io/storj/satellite/console"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getUserLimits(u *console.User) console.UsageLimits {
|
||||||
|
return console.UsageLimits{
|
||||||
|
Storage: u.ProjectStorageLimit,
|
||||||
|
Bandwidth: u.ProjectBandwidthLimit,
|
||||||
|
Segment: u.ProjectSegmentLimit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProjectLimits(p *console.Project) console.UsageLimits {
|
||||||
|
return console.UsageLimits{
|
||||||
|
Storage: p.StorageLimit.Int64(),
|
||||||
|
Bandwidth: p.BandwidthLimit.Int64(),
|
||||||
|
Segment: *p.SegmentLimit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func randUsageLimits() console.UsageLimits {
|
||||||
|
return console.UsageLimits{Storage: rand.Int63(), Bandwidth: rand.Int63(), Segment: rand.Int63()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccountFreeze(t *testing.T) {
|
||||||
|
testplanet.Run(t, testplanet.Config{
|
||||||
|
SatelliteCount: 1,
|
||||||
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||||
|
sat := planet.Satellites[0]
|
||||||
|
usersDB := sat.DB.Console().Users()
|
||||||
|
projectsDB := sat.DB.Console().Projects()
|
||||||
|
service := console.NewAccountFreezeService(sat.DB.Console().AccountFreezeEvents(), usersDB, projectsDB)
|
||||||
|
|
||||||
|
userLimits := randUsageLimits()
|
||||||
|
user, err := sat.AddUser(ctx, console.CreateUser{
|
||||||
|
FullName: "Test User",
|
||||||
|
Email: "user@mail.test",
|
||||||
|
}, 2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, usersDB.UpdateUserProjectLimits(ctx, user.ID, userLimits))
|
||||||
|
|
||||||
|
projLimits := randUsageLimits()
|
||||||
|
proj, err := sat.AddProject(ctx, user.ID, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, projectsDB.UpdateUsageLimits(ctx, proj.ID, projLimits))
|
||||||
|
|
||||||
|
frozen, err := service.IsUserFrozen(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.False(t, frozen)
|
||||||
|
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
frozen, err = service.IsUserFrozen(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, frozen)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccountUnfreeze(t *testing.T) {
|
||||||
|
testplanet.Run(t, testplanet.Config{
|
||||||
|
SatelliteCount: 1,
|
||||||
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||||
|
sat := planet.Satellites[0]
|
||||||
|
usersDB := sat.DB.Console().Users()
|
||||||
|
projectsDB := sat.DB.Console().Projects()
|
||||||
|
service := console.NewAccountFreezeService(sat.DB.Console().AccountFreezeEvents(), usersDB, projectsDB)
|
||||||
|
|
||||||
|
userLimits := randUsageLimits()
|
||||||
|
user, err := sat.AddUser(ctx, console.CreateUser{
|
||||||
|
FullName: "Test User",
|
||||||
|
Email: "user@mail.test",
|
||||||
|
}, 2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, usersDB.UpdateUserProjectLimits(ctx, user.ID, userLimits))
|
||||||
|
|
||||||
|
projLimits := randUsageLimits()
|
||||||
|
proj, err := sat.AddProject(ctx, user.ID, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, projectsDB.UpdateUsageLimits(ctx, proj.ID, projLimits))
|
||||||
|
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
require.NoError(t, service.UnfreezeUser(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))
|
||||||
|
|
||||||
|
frozen, err := service.IsUserFrozen(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.False(t, frozen)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccountFreezeAlreadyFrozen(t *testing.T) {
|
||||||
|
testplanet.Run(t, testplanet.Config{
|
||||||
|
SatelliteCount: 1,
|
||||||
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||||
|
sat := planet.Satellites[0]
|
||||||
|
usersDB := sat.DB.Console().Users()
|
||||||
|
projectsDB := sat.DB.Console().Projects()
|
||||||
|
service := console.NewAccountFreezeService(sat.DB.Console().AccountFreezeEvents(), usersDB, projectsDB)
|
||||||
|
|
||||||
|
userLimits := randUsageLimits()
|
||||||
|
user, err := sat.AddUser(ctx, console.CreateUser{
|
||||||
|
FullName: "Test User",
|
||||||
|
Email: "user@mail.test",
|
||||||
|
}, 2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, usersDB.UpdateUserProjectLimits(ctx, user.ID, userLimits))
|
||||||
|
|
||||||
|
proj1Limits := randUsageLimits()
|
||||||
|
proj1, err := sat.AddProject(ctx, user.ID, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, projectsDB.UpdateUsageLimits(ctx, proj1.ID, proj1Limits))
|
||||||
|
|
||||||
|
// Freezing a frozen user should freeze any projects that were unable to be frozen prior.
|
||||||
|
// The limits stored for projects frozen by the prior freeze should not be modified.
|
||||||
|
t.Run("Project limits", func(t *testing.T) {
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
|
||||||
|
proj2Limits := randUsageLimits()
|
||||||
|
proj2, err := sat.AddProject(ctx, user.ID, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, projectsDB.UpdateUsageLimits(ctx, proj2.ID, proj2Limits))
|
||||||
|
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
|
||||||
|
user, err := usersDB.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Zero(t, getUserLimits(user))
|
||||||
|
|
||||||
|
proj2, err = projectsDB.Get(ctx, proj2.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Zero(t, getProjectLimits(proj2))
|
||||||
|
|
||||||
|
require.NoError(t, service.UnfreezeUser(ctx, user.ID))
|
||||||
|
|
||||||
|
user, err = usersDB.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, userLimits, getUserLimits(user))
|
||||||
|
|
||||||
|
proj1, err = projectsDB.Get(ctx, proj1.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, proj1Limits, getProjectLimits(proj1))
|
||||||
|
|
||||||
|
proj2, err = projectsDB.Get(ctx, proj2.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, proj2Limits, getProjectLimits(proj2))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Freezing a frozen user should freeze the user's limits if they were unable to be frozen prior.
|
||||||
|
t.Run("Unfrozen user limits", func(t *testing.T) {
|
||||||
|
user, err := usersDB.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
require.NoError(t, usersDB.UpdateUserProjectLimits(ctx, user.ID, userLimits))
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
|
||||||
|
user, err = usersDB.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Zero(t, getUserLimits(user))
|
||||||
|
|
||||||
|
require.NoError(t, service.UnfreezeUser(ctx, user.ID))
|
||||||
|
|
||||||
|
user, err = usersDB.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, userLimits, getUserLimits(user))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Freezing a frozen user should not modify user limits stored by the prior freeze.
|
||||||
|
t.Run("Frozen user limits", func(t *testing.T) {
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||||
|
|
||||||
|
user, err = usersDB.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Zero(t, getUserLimits(user))
|
||||||
|
|
||||||
|
require.NoError(t, service.UnfreezeUser(ctx, user.ID))
|
||||||
|
user, err = usersDB.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, userLimits, getUserLimits(user))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
@ -51,6 +51,9 @@ type Projects interface {
|
|||||||
GetMaxBuckets(ctx context.Context, id uuid.UUID) (*int, error)
|
GetMaxBuckets(ctx context.Context, id uuid.UUID) (*int, error)
|
||||||
// UpdateBucketLimit is a method for updating projects bucket limit.
|
// UpdateBucketLimit is a method for updating projects bucket limit.
|
||||||
UpdateBucketLimit(ctx context.Context, id uuid.UUID, newLimit int) error
|
UpdateBucketLimit(ctx context.Context, id uuid.UUID, newLimit int) error
|
||||||
|
|
||||||
|
// UpdateUsageLimits is a method for updating project's usage limits.
|
||||||
|
UpdateUsageLimits(ctx context.Context, id uuid.UUID, limits UsageLimits) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// UsageLimitsConfig is a configuration struct for default per-project usage limits.
|
// UsageLimitsConfig is a configuration struct for default per-project usage limits.
|
||||||
|
@ -39,6 +39,8 @@ type Users interface {
|
|||||||
Update(ctx context.Context, userID uuid.UUID, request UpdateUserRequest) error
|
Update(ctx context.Context, userID uuid.UUID, request UpdateUserRequest) error
|
||||||
// UpdatePaidTier sets whether the user is in the paid tier.
|
// UpdatePaidTier sets whether the user is in the paid tier.
|
||||||
UpdatePaidTier(ctx context.Context, id uuid.UUID, paidTier bool, projectBandwidthLimit, projectStorageLimit memory.Size, projectSegmentLimit int64, projectLimit int) error
|
UpdatePaidTier(ctx context.Context, id uuid.UUID, paidTier bool, projectBandwidthLimit, projectStorageLimit memory.Size, projectSegmentLimit int64, projectLimit int) error
|
||||||
|
// UpdateUserProjectLimits is a method to update the user's usage limits for new projects.
|
||||||
|
UpdateUserProjectLimits(ctx context.Context, id uuid.UUID, limits UsageLimits) error
|
||||||
// GetProjectLimit is a method to get the users project limit
|
// GetProjectLimit is a method to get the users project limit
|
||||||
GetProjectLimit(ctx context.Context, id uuid.UUID) (limit int, err error)
|
GetProjectLimit(ctx context.Context, id uuid.UUID) (limit int, err error)
|
||||||
// GetUserProjectLimits is a method to get the users storage and bandwidth limits for new projects.
|
// GetUserProjectLimits is a method to get the users storage and bandwidth limits for new projects.
|
||||||
|
@ -20,8 +20,8 @@ type accountFreezeEvents struct {
|
|||||||
db dbx.Methods
|
db dbx.Methods
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert is a method for inserting account freeze event into the database.
|
// Upsert is a method for updating an account freeze event if it exists and inserting it otherwise.
|
||||||
func (events *accountFreezeEvents) Insert(ctx context.Context, event *console.AccountFreezeEvent) (_ *console.AccountFreezeEvent, err error) {
|
func (events *accountFreezeEvents) Upsert(ctx context.Context, event *console.AccountFreezeEvent) (_ *console.AccountFreezeEvent, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
if event == nil {
|
if event == nil {
|
||||||
@ -37,7 +37,7 @@ func (events *accountFreezeEvents) Insert(ctx context.Context, event *console.Ac
|
|||||||
createFields.Limits = dbx.AccountFreezeEvent_Limits(limitBytes)
|
createFields.Limits = dbx.AccountFreezeEvent_Limits(limitBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbxEvent, err := events.db.Create_AccountFreezeEvent(ctx,
|
dbxEvent, err := events.db.Replace_AccountFreezeEvent(ctx,
|
||||||
dbx.AccountFreezeEvent_UserId(event.UserID.Bytes()),
|
dbx.AccountFreezeEvent_UserId(event.UserID.Bytes()),
|
||||||
dbx.AccountFreezeEvent_Event(int(event.Type)),
|
dbx.AccountFreezeEvent_Event(int(event.Type)),
|
||||||
createFields,
|
createFields,
|
||||||
@ -64,26 +64,6 @@ func (events *accountFreezeEvents) Get(ctx context.Context, userID uuid.UUID, ev
|
|||||||
return fromDBXAccountFreezeEvent(dbxEvent)
|
return fromDBXAccountFreezeEvent(dbxEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateLimits is a method for updating the limits of an account freeze event by user ID and event type.
|
|
||||||
func (events *accountFreezeEvents) UpdateLimits(ctx context.Context, userID uuid.UUID, eventType console.AccountFreezeEventType, limits *console.AccountFreezeEventLimits) (err error) {
|
|
||||||
defer mon.Task()(&ctx)(&err)
|
|
||||||
|
|
||||||
limitBytes, err := json.Marshal(limits)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = events.db.Update_AccountFreezeEvent_By_UserId_And_Event(ctx,
|
|
||||||
dbx.AccountFreezeEvent_UserId(userID.Bytes()),
|
|
||||||
dbx.AccountFreezeEvent_Event(int(eventType)),
|
|
||||||
dbx.AccountFreezeEvent_Update_Fields{
|
|
||||||
Limits: dbx.AccountFreezeEvent_Limits(limitBytes),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteAllByUserID is a method for deleting all account freeze events from the database by user ID.
|
// DeleteAllByUserID is a method for deleting all account freeze events from the database by user ID.
|
||||||
func (events *accountFreezeEvents) DeleteAllByUserID(ctx context.Context, userID uuid.UUID) (err error) {
|
func (events *accountFreezeEvents) DeleteAllByUserID(ctx context.Context, userID uuid.UUID) (err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
@ -22,11 +22,7 @@ import (
|
|||||||
func TestAccountFreezeEvents(t *testing.T) {
|
func TestAccountFreezeEvents(t *testing.T) {
|
||||||
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
||||||
randUsageLimits := func() console.UsageLimits {
|
randUsageLimits := func() console.UsageLimits {
|
||||||
return console.UsageLimits{
|
return console.UsageLimits{Storage: rand.Int63(), Bandwidth: rand.Int63(), Segment: rand.Int63()}
|
||||||
Storage: rand.Int63(),
|
|
||||||
Bandwidth: rand.Int63(),
|
|
||||||
Segment: rand.Int63(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &console.AccountFreezeEvent{
|
event := &console.AccountFreezeEvent{
|
||||||
@ -44,12 +40,12 @@ func TestAccountFreezeEvents(t *testing.T) {
|
|||||||
eventsDB := db.Console().AccountFreezeEvents()
|
eventsDB := db.Console().AccountFreezeEvents()
|
||||||
|
|
||||||
t.Run("Can't insert nil event", func(t *testing.T) {
|
t.Run("Can't insert nil event", func(t *testing.T) {
|
||||||
_, err := eventsDB.Insert(ctx, nil)
|
_, err := eventsDB.Upsert(ctx, nil)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Insert event", func(t *testing.T) {
|
t.Run("Insert event", func(t *testing.T) {
|
||||||
dbEvent, err := eventsDB.Insert(ctx, event)
|
dbEvent, err := eventsDB.Upsert(ctx, event)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, dbEvent)
|
require.NotNil(t, dbEvent)
|
||||||
require.WithinDuration(t, time.Now(), dbEvent.CreatedAt, time.Minute)
|
require.WithinDuration(t, time.Now(), dbEvent.CreatedAt, time.Minute)
|
||||||
@ -57,11 +53,6 @@ func TestAccountFreezeEvents(t *testing.T) {
|
|||||||
require.Equal(t, event, dbEvent)
|
require.Equal(t, event, dbEvent)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Can't insert duplicate event", func(t *testing.T) {
|
|
||||||
_, err := eventsDB.Insert(ctx, event)
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Get event", func(t *testing.T) {
|
t.Run("Get event", func(t *testing.T) {
|
||||||
dbEvent, err := eventsDB.Get(ctx, event.UserID, event.Type)
|
dbEvent, err := eventsDB.Get(ctx, event.UserID, event.Type)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -71,18 +62,22 @@ func TestAccountFreezeEvents(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Update event limits", func(t *testing.T) {
|
t.Run("Update event limits", func(t *testing.T) {
|
||||||
limits := &console.AccountFreezeEventLimits{
|
event.Limits = &console.AccountFreezeEventLimits{
|
||||||
User: randUsageLimits(),
|
User: randUsageLimits(),
|
||||||
Projects: map[uuid.UUID]console.UsageLimits{
|
Projects: map[uuid.UUID]console.UsageLimits{
|
||||||
testrand.UUID(): randUsageLimits(),
|
testrand.UUID(): randUsageLimits(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
require.NoError(t, eventsDB.UpdateLimits(ctx, event.UserID, event.Type, limits))
|
|
||||||
|
_, err := eventsDB.Upsert(ctx, event)
|
||||||
|
require.NoError(t, err)
|
||||||
dbEvent, err := eventsDB.Get(ctx, event.UserID, event.Type)
|
dbEvent, err := eventsDB.Get(ctx, event.UserID, event.Type)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, limits, dbEvent.Limits)
|
require.Equal(t, event.Limits, dbEvent.Limits)
|
||||||
|
|
||||||
require.NoError(t, eventsDB.UpdateLimits(ctx, event.UserID, event.Type, nil))
|
event.Limits = nil
|
||||||
|
_, err = eventsDB.Upsert(ctx, event)
|
||||||
|
require.NoError(t, err)
|
||||||
dbEvent, err = eventsDB.Get(ctx, event.UserID, event.Type)
|
dbEvent, err = eventsDB.Get(ctx, event.UserID, event.Type)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, dbEvent.Limits)
|
require.Nil(t, dbEvent.Limits)
|
||||||
|
@ -10,7 +10,7 @@ model account_freeze_event (
|
|||||||
field created_at timestamp ( default current_timestamp )
|
field created_at timestamp ( default current_timestamp )
|
||||||
)
|
)
|
||||||
|
|
||||||
create account_freeze_event()
|
create account_freeze_event( replace )
|
||||||
|
|
||||||
read one (
|
read one (
|
||||||
select account_freeze_event
|
select account_freeze_event
|
||||||
|
@ -12830,7 +12830,7 @@ type WalletAddress_Row struct {
|
|||||||
WalletAddress []byte
|
WalletAddress []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *pgxImpl) Create_AccountFreezeEvent(ctx context.Context,
|
func (obj *pgxImpl) Replace_AccountFreezeEvent(ctx context.Context,
|
||||||
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
||||||
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
||||||
optional AccountFreezeEvent_Create_Fields) (
|
optional AccountFreezeEvent_Create_Fields) (
|
||||||
@ -12844,7 +12844,7 @@ func (obj *pgxImpl) Create_AccountFreezeEvent(ctx context.Context,
|
|||||||
var __placeholders = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("?, ?, ?")}
|
var __placeholders = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("?, ?, ?")}
|
||||||
var __clause = &__sqlbundle_Hole{SQL: __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("("), __columns, __sqlbundle_Literal(") VALUES ("), __placeholders, __sqlbundle_Literal(")")}}}
|
var __clause = &__sqlbundle_Hole{SQL: __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("("), __columns, __sqlbundle_Literal(") VALUES ("), __placeholders, __sqlbundle_Literal(")")}}}
|
||||||
|
|
||||||
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("INSERT INTO account_freeze_events "), __clause, __sqlbundle_Literal(" RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}}
|
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("INSERT INTO account_freeze_events "), __clause, __sqlbundle_Literal(" ON CONFLICT ( user_id, event ) DO UPDATE SET user_id = EXCLUDED.user_id, event = EXCLUDED.event, limits = EXCLUDED.limits, created_at = EXCLUDED.created_at RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}}
|
||||||
|
|
||||||
var __values []interface{}
|
var __values []interface{}
|
||||||
__values = append(__values, __user_id_val, __event_val, __limits_val)
|
__values = append(__values, __user_id_val, __event_val, __limits_val)
|
||||||
@ -20781,7 +20781,7 @@ func (obj *pgxImpl) deleteAll(ctx context.Context) (count int64, err error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *pgxcockroachImpl) Create_AccountFreezeEvent(ctx context.Context,
|
func (obj *pgxcockroachImpl) Replace_AccountFreezeEvent(ctx context.Context,
|
||||||
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
||||||
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
||||||
optional AccountFreezeEvent_Create_Fields) (
|
optional AccountFreezeEvent_Create_Fields) (
|
||||||
@ -20795,7 +20795,7 @@ func (obj *pgxcockroachImpl) Create_AccountFreezeEvent(ctx context.Context,
|
|||||||
var __placeholders = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("?, ?, ?")}
|
var __placeholders = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("?, ?, ?")}
|
||||||
var __clause = &__sqlbundle_Hole{SQL: __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("("), __columns, __sqlbundle_Literal(") VALUES ("), __placeholders, __sqlbundle_Literal(")")}}}
|
var __clause = &__sqlbundle_Hole{SQL: __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("("), __columns, __sqlbundle_Literal(") VALUES ("), __placeholders, __sqlbundle_Literal(")")}}}
|
||||||
|
|
||||||
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("INSERT INTO account_freeze_events "), __clause, __sqlbundle_Literal(" RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}}
|
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("UPSERT INTO account_freeze_events "), __clause, __sqlbundle_Literal(" RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}}
|
||||||
|
|
||||||
var __values []interface{}
|
var __values []interface{}
|
||||||
__values = append(__values, __user_id_val, __event_val, __limits_val)
|
__values = append(__values, __user_id_val, __event_val, __limits_val)
|
||||||
@ -29171,19 +29171,6 @@ func (rx *Rx) CreateNoReturn_StorjscanWallet(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rx *Rx) Create_AccountFreezeEvent(ctx context.Context,
|
|
||||||
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
|
||||||
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
|
||||||
optional AccountFreezeEvent_Create_Fields) (
|
|
||||||
account_freeze_event *AccountFreezeEvent, err error) {
|
|
||||||
var tx *Tx
|
|
||||||
if tx, err = rx.getTx(ctx); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return tx.Create_AccountFreezeEvent(ctx, account_freeze_event_user_id, account_freeze_event_event, optional)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rx *Rx) Create_ApiKey(ctx context.Context,
|
func (rx *Rx) Create_ApiKey(ctx context.Context,
|
||||||
api_key_id ApiKey_Id_Field,
|
api_key_id ApiKey_Id_Field,
|
||||||
api_key_project_id ApiKey_ProjectId_Field,
|
api_key_project_id ApiKey_ProjectId_Field,
|
||||||
@ -30515,6 +30502,19 @@ func (rx *Rx) ReplaceNoReturn_StoragenodePaystub(ctx context.Context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rx *Rx) Replace_AccountFreezeEvent(ctx context.Context,
|
||||||
|
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
||||||
|
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
||||||
|
optional AccountFreezeEvent_Create_Fields) (
|
||||||
|
account_freeze_event *AccountFreezeEvent, err error) {
|
||||||
|
var tx *Tx
|
||||||
|
if tx, err = rx.getTx(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return tx.Replace_AccountFreezeEvent(ctx, account_freeze_event_user_id, account_freeze_event_event, optional)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (rx *Rx) UpdateNoReturn_AccountingTimestamps_By_Name(ctx context.Context,
|
func (rx *Rx) UpdateNoReturn_AccountingTimestamps_By_Name(ctx context.Context,
|
||||||
accounting_timestamps_name AccountingTimestamps_Name_Field,
|
accounting_timestamps_name AccountingTimestamps_Name_Field,
|
||||||
update AccountingTimestamps_Update_Fields) (
|
update AccountingTimestamps_Update_Fields) (
|
||||||
@ -30989,12 +30989,6 @@ type Methods interface {
|
|||||||
storjscan_wallet_wallet_address StorjscanWallet_WalletAddress_Field) (
|
storjscan_wallet_wallet_address StorjscanWallet_WalletAddress_Field) (
|
||||||
err error)
|
err error)
|
||||||
|
|
||||||
Create_AccountFreezeEvent(ctx context.Context,
|
|
||||||
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
|
||||||
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
|
||||||
optional AccountFreezeEvent_Create_Fields) (
|
|
||||||
account_freeze_event *AccountFreezeEvent, err error)
|
|
||||||
|
|
||||||
Create_ApiKey(ctx context.Context,
|
Create_ApiKey(ctx context.Context,
|
||||||
api_key_id ApiKey_Id_Field,
|
api_key_id ApiKey_Id_Field,
|
||||||
api_key_project_id ApiKey_ProjectId_Field,
|
api_key_project_id ApiKey_ProjectId_Field,
|
||||||
@ -31612,6 +31606,12 @@ type Methods interface {
|
|||||||
storagenode_paystub_distributed StoragenodePaystub_Distributed_Field) (
|
storagenode_paystub_distributed StoragenodePaystub_Distributed_Field) (
|
||||||
err error)
|
err error)
|
||||||
|
|
||||||
|
Replace_AccountFreezeEvent(ctx context.Context,
|
||||||
|
account_freeze_event_user_id AccountFreezeEvent_UserId_Field,
|
||||||
|
account_freeze_event_event AccountFreezeEvent_Event_Field,
|
||||||
|
optional AccountFreezeEvent_Create_Fields) (
|
||||||
|
account_freeze_event *AccountFreezeEvent, err error)
|
||||||
|
|
||||||
UpdateNoReturn_AccountingTimestamps_By_Name(ctx context.Context,
|
UpdateNoReturn_AccountingTimestamps_By_Name(ctx context.Context,
|
||||||
accounting_timestamps_name AccountingTimestamps_Name_Field,
|
accounting_timestamps_name AccountingTimestamps_Name_Field,
|
||||||
update AccountingTimestamps_Update_Fields) (
|
update AccountingTimestamps_Update_Fields) (
|
||||||
|
@ -455,3 +455,18 @@ func (projects *projects) GetMaxBuckets(ctx context.Context, id uuid.UUID) (maxB
|
|||||||
}
|
}
|
||||||
return dbxRow.MaxBuckets, nil
|
return dbxRow.MaxBuckets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateUsageLimits is a method for updating project's bandwidth, storage, and segment limits.
|
||||||
|
func (projects *projects) UpdateUsageLimits(ctx context.Context, id uuid.UUID, limits console.UsageLimits) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
_, err = projects.db.Update_Project_By_Id(ctx,
|
||||||
|
dbx.Project_Id(id[:]),
|
||||||
|
dbx.Project_Update_Fields{
|
||||||
|
BandwidthLimit: dbx.Project_BandwidthLimit(limits.Bandwidth),
|
||||||
|
UsageLimit: dbx.Project_UsageLimit(limits.Storage),
|
||||||
|
SegmentLimit: dbx.Project_SegmentLimit(limits.Segment),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
package satellitedb_test
|
package satellitedb_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -54,3 +55,23 @@ func TestProjectsGetSalt(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateProjectUsageLimits(t *testing.T) {
|
||||||
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
||||||
|
limits := console.UsageLimits{Storage: rand.Int63(), Bandwidth: rand.Int63(), Segment: rand.Int63()}
|
||||||
|
projectsRepo := db.Console().Projects()
|
||||||
|
|
||||||
|
proj, err := projectsRepo.Insert(ctx, &console.Project{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, proj)
|
||||||
|
|
||||||
|
err = projectsRepo.UpdateUsageLimits(ctx, proj.ID, limits)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
proj, err = projectsRepo.Get(ctx, proj.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, limits.Bandwidth, proj.BandwidthLimit.Int64())
|
||||||
|
require.Equal(t, limits.Storage, proj.StorageLimit.Int64())
|
||||||
|
require.Equal(t, limits.Segment, *proj.SegmentLimit)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -240,6 +240,23 @@ func (users *users) UpdatePaidTier(ctx context.Context, id uuid.UUID, paidTier b
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateUserProjectLimits is a method to update the user's usage limits for new projects.
|
||||||
|
func (users *users) UpdateUserProjectLimits(ctx context.Context, id uuid.UUID, limits console.UsageLimits) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
_, err = users.db.Update_User_By_Id(
|
||||||
|
ctx,
|
||||||
|
dbx.User_Id(id[:]),
|
||||||
|
dbx.User_Update_Fields{
|
||||||
|
ProjectBandwidthLimit: dbx.User_ProjectBandwidthLimit(limits.Bandwidth),
|
||||||
|
ProjectStorageLimit: dbx.User_ProjectStorageLimit(limits.Storage),
|
||||||
|
ProjectSegmentLimit: dbx.User_ProjectSegmentLimit(limits.Segment),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// GetProjectLimit is a method to get the users project limit.
|
// GetProjectLimit is a method to get the users project limit.
|
||||||
func (users *users) GetProjectLimit(ctx context.Context, id uuid.UUID) (limit int, err error) {
|
func (users *users) GetProjectLimit(ctx context.Context, id uuid.UUID) (limit int, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
package satellitedb_test
|
package satellitedb_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -301,3 +302,27 @@ func TestUpdateUser(t *testing.T) {
|
|||||||
require.Equal(t, u, updatedUser)
|
require.Equal(t, u, updatedUser)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateUserProjectLimits(t *testing.T) {
|
||||||
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
||||||
|
limits := console.UsageLimits{Storage: rand.Int63(), Bandwidth: rand.Int63(), Segment: rand.Int63()}
|
||||||
|
usersRepo := db.Console().Users()
|
||||||
|
|
||||||
|
user, err := usersRepo.Insert(ctx, &console.User{
|
||||||
|
ID: testrand.UUID(),
|
||||||
|
FullName: "User",
|
||||||
|
Email: "test@mail.test",
|
||||||
|
PasswordHash: []byte("123a123"),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = usersRepo.UpdateUserProjectLimits(ctx, user.ID, limits)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
user, err = usersRepo.Get(ctx, user.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, limits.Bandwidth, user.ProjectBandwidthLimit)
|
||||||
|
require.Equal(t, limits.Storage, user.ProjectStorageLimit)
|
||||||
|
require.Equal(t, limits.Segment, user.ProjectSegmentLimit)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user