From 2ea6ca9c1833ee37d5d2afab45621ca913785853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Elek?= Date: Wed, 7 Jun 2023 11:25:57 +0200 Subject: [PATCH] satellite/console: fill default placement of project based on user info https://github.com/storj/storj/issues/5879 Change-Id: I5aacbe57a7aab65e11915dd8bf0c68f89da32fb4 --- satellite/admin/project_test.go | 2 +- satellite/console/projects.go | 30 ++++++++++++++------------- satellite/console/service.go | 30 ++++++++++++++------------- satellite/console/service_test.go | 26 ++++++++++++++++++++++- satellite/console/users.go | 5 +++++ satellite/satellitedb/projects.go | 34 +++++++++++++++++++------------ satellite/satellitedb/users.go | 6 ++++++ 7 files changed, 90 insertions(+), 43 deletions(-) diff --git a/satellite/admin/project_test.go b/satellite/admin/project_test.go index d771993ed..3b209a523 100644 --- a/satellite/admin/project_test.go +++ b/satellite/admin/project_test.go @@ -47,7 +47,7 @@ func TestProjectGet(t *testing.T) { t.Run("OK", func(t *testing.T) { link := "http://" + address.String() + "/api/projects/" + project.ID.String() expected := fmt.Sprintf( - `{"id":"%s","publicId":"%s","name":"%s","description":"%s","userAgent":null,"ownerId":"%s","rateLimit":null,"burstLimit":null,"maxBuckets":null,"createdAt":"%s","memberCount":0,"storageLimit":"25.00 GB","bandwidthLimit":"25.00 GB","userSpecifiedStorageLimit":null,"userSpecifiedBandwidthLimit":null,"segmentLimit":10000}`, + `{"id":"%s","publicId":"%s","name":"%s","description":"%s","userAgent":null,"ownerId":"%s","rateLimit":null,"burstLimit":null,"maxBuckets":null,"createdAt":"%s","memberCount":0,"storageLimit":"25.00 GB","bandwidthLimit":"25.00 GB","userSpecifiedStorageLimit":null,"userSpecifiedBandwidthLimit":null,"segmentLimit":10000,"defaultPlacement":0}`, project.ID.String(), project.PublicID.String(), project.Name, diff --git a/satellite/console/projects.go b/satellite/console/projects.go index a8fecbe89..6cce09050 100644 --- a/satellite/console/projects.go +++ b/satellite/console/projects.go @@ -9,6 +9,7 @@ import ( "time" "storj.io/common/memory" + "storj.io/common/storj" "storj.io/common/uuid" ) @@ -93,20 +94,21 @@ type Project struct { ID uuid.UUID `json:"id"` PublicID uuid.UUID `json:"publicId"` - Name string `json:"name"` - Description string `json:"description"` - UserAgent []byte `json:"userAgent"` - OwnerID uuid.UUID `json:"ownerId"` - RateLimit *int `json:"rateLimit"` - BurstLimit *int `json:"burstLimit"` - MaxBuckets *int `json:"maxBuckets"` - CreatedAt time.Time `json:"createdAt"` - MemberCount int `json:"memberCount"` - StorageLimit *memory.Size `json:"storageLimit"` - BandwidthLimit *memory.Size `json:"bandwidthLimit"` - UserSpecifiedStorageLimit *memory.Size `json:"userSpecifiedStorageLimit"` - UserSpecifiedBandwidthLimit *memory.Size `json:"userSpecifiedBandwidthLimit"` - SegmentLimit *int64 `json:"segmentLimit"` + Name string `json:"name"` + Description string `json:"description"` + UserAgent []byte `json:"userAgent"` + OwnerID uuid.UUID `json:"ownerId"` + RateLimit *int `json:"rateLimit"` + BurstLimit *int `json:"burstLimit"` + MaxBuckets *int `json:"maxBuckets"` + CreatedAt time.Time `json:"createdAt"` + MemberCount int `json:"memberCount"` + StorageLimit *memory.Size `json:"storageLimit"` + BandwidthLimit *memory.Size `json:"bandwidthLimit"` + UserSpecifiedStorageLimit *memory.Size `json:"userSpecifiedStorageLimit"` + UserSpecifiedBandwidthLimit *memory.Size `json:"userSpecifiedBandwidthLimit"` + SegmentLimit *int64 `json:"segmentLimit"` + DefaultPlacement storj.PlacementConstraint `json:"defaultPlacement"` } // ProjectInfo holds data needed to create/update Project. diff --git a/satellite/console/service.go b/satellite/console/service.go index e009e2c88..3b6f7419c 100644 --- a/satellite/console/service.go +++ b/satellite/console/service.go @@ -1616,13 +1616,14 @@ func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p bandwidthLimit := memory.Size(newProjectLimits.Bandwidth) p, err = tx.Projects().Insert(ctx, &Project{ - Description: projectInfo.Description, - Name: projectInfo.Name, - OwnerID: user.ID, - UserAgent: user.UserAgent, - StorageLimit: &storageLimit, - BandwidthLimit: &bandwidthLimit, - SegmentLimit: &newProjectLimits.Segment, + Description: projectInfo.Description, + Name: projectInfo.Name, + OwnerID: user.ID, + UserAgent: user.UserAgent, + StorageLimit: &storageLimit, + BandwidthLimit: &bandwidthLimit, + SegmentLimit: &newProjectLimits.Segment, + DefaultPlacement: user.DefaultPlacement, }, ) if err != nil { @@ -1683,13 +1684,14 @@ func (s *Service) GenCreateProject(ctx context.Context, projectInfo ProjectInfo) bandwidthLimit := memory.Size(newProjectLimits.Bandwidth) p, err = tx.Projects().Insert(ctx, &Project{ - Description: projectInfo.Description, - Name: projectInfo.Name, - OwnerID: user.ID, - UserAgent: user.UserAgent, - StorageLimit: &storageLimit, - BandwidthLimit: &bandwidthLimit, - SegmentLimit: &newProjectLimits.Segment, + Description: projectInfo.Description, + Name: projectInfo.Name, + OwnerID: user.ID, + UserAgent: user.UserAgent, + StorageLimit: &storageLimit, + BandwidthLimit: &bandwidthLimit, + SegmentLimit: &newProjectLimits.Segment, + DefaultPlacement: user.DefaultPlacement, }, ) if err != nil { diff --git a/satellite/console/service_test.go b/satellite/console/service_test.go index 537eb7de9..f5f183558 100644 --- a/satellite/console/service_test.go +++ b/satellite/console/service_test.go @@ -23,6 +23,7 @@ import ( "storj.io/common/currency" "storj.io/common/macaroon" "storj.io/common/memory" + "storj.io/common/storj" "storj.io/common/testcontext" "storj.io/common/testrand" "storj.io/common/uuid" @@ -41,7 +42,7 @@ import ( func TestService(t *testing.T) { testplanet.Run(t, testplanet.Config{ - SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 2, + SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 3, Reconfigure: testplanet.Reconfigure{ Satellite: func(log *zap.Logger, index int, config *satellite.Config) { config.Payments.StripeCoinPayments.StripeFreeTierCouponID = stripe.MockCouponID1 @@ -156,6 +157,29 @@ func TestService(t *testing.T) { require.Nil(t, createdProject) }) + t.Run("CreateProject with placement", func(t *testing.T) { + uid := planet.Uplinks[2].Projects[0].Owner.ID + err := sat.API.DB.Console().Users().Update(ctx, uid, console.UpdateUserRequest{ + DefaultPlacement: storj.EU, + }) + require.NoError(t, err) + + user, err := service.GetUser(ctx, uid) + require.NoError(t, err) + + userCtx, err := sat.UserContext(ctx, user.ID) + require.NoError(t, err) + + p, err := service.CreateProject(userCtx, console.ProjectInfo{ + Name: "eu-project", + Description: "project with eu1 default placement", + CreatedAt: time.Now(), + }) + require.NoError(t, err) + require.Equal(t, storj.EU, p.DefaultPlacement) + + }) + t.Run("UpdateProject", func(t *testing.T) { updatedName := "newName" updatedDescription := "newDescription" diff --git a/satellite/console/users.go b/satellite/console/users.go index 8ad6ecf16..1422fd4d5 100644 --- a/satellite/console/users.go +++ b/satellite/console/users.go @@ -11,6 +11,7 @@ import ( "github.com/zeebo/errs" "storj.io/common/memory" + "storj.io/common/storj" "storj.io/common/uuid" "storj.io/storj/satellite/console/consoleauth" ) @@ -184,6 +185,8 @@ type User struct { FailedLoginCount int `json:"failedLoginCount"` LoginLockoutExpiration time.Time `json:"loginLockoutExpiration"` SignupCaptcha *float64 `json:"-"` + + DefaultPlacement storj.PlacementConstraint `json:"defaultPlacement"` } // ResponseUser is an entity which describes db User and can be sent in response. @@ -249,6 +252,8 @@ type UpdateUserRequest struct { FailedLoginCount *int LoginLockoutExpiration **time.Time + + DefaultPlacement storj.PlacementConstraint } // UserSettings contains configurations for a user. diff --git a/satellite/satellitedb/projects.go b/satellite/satellitedb/projects.go index 36a3d0477..81c5b4e73 100644 --- a/satellite/satellitedb/projects.go +++ b/satellite/satellitedb/projects.go @@ -12,6 +12,7 @@ import ( "github.com/zeebo/errs" "storj.io/common/memory" + "storj.io/common/storj" "storj.io/common/uuid" "storj.io/storj/satellite/console" "storj.io/storj/satellite/satellitedb/dbx" @@ -153,6 +154,7 @@ func (projects *projects) Insert(ctx context.Context, project *console.Project) createFields.MaxBuckets = dbx.Project_MaxBuckets_Raw(project.MaxBuckets) createFields.PublicId = dbx.Project_PublicId(publicID[:]) createFields.Salt = dbx.Project_Salt(salt[:]) + createFields.DefaultPlacement = dbx.Project_DefaultPlacement(int(project.DefaultPlacement)) createdProject, err := projects.db.Create_Project(ctx, dbx.Project_Id(projectID[:]), @@ -395,20 +397,26 @@ func projectFromDBX(ctx context.Context, project *dbx.Project) (_ *console.Proje return nil, err } + var placement storj.PlacementConstraint + if project.DefaultPlacement != nil { + placement = storj.PlacementConstraint(*project.DefaultPlacement) + } + return &console.Project{ - ID: id, - PublicID: publicID, - Name: project.Name, - Description: project.Description, - UserAgent: userAgent, - OwnerID: ownerID, - RateLimit: project.RateLimit, - BurstLimit: project.BurstLimit, - MaxBuckets: project.MaxBuckets, - CreatedAt: project.CreatedAt, - StorageLimit: (*memory.Size)(project.UsageLimit), - BandwidthLimit: (*memory.Size)(project.BandwidthLimit), - SegmentLimit: project.SegmentLimit, + ID: id, + PublicID: publicID, + Name: project.Name, + Description: project.Description, + UserAgent: userAgent, + OwnerID: ownerID, + RateLimit: project.RateLimit, + BurstLimit: project.BurstLimit, + MaxBuckets: project.MaxBuckets, + CreatedAt: project.CreatedAt, + StorageLimit: (*memory.Size)(project.UsageLimit), + BandwidthLimit: (*memory.Size)(project.BandwidthLimit), + SegmentLimit: project.SegmentLimit, + DefaultPlacement: placement, }, nil } diff --git a/satellite/satellitedb/users.go b/satellite/satellitedb/users.go index 10cc7888e..8c1859867 100644 --- a/satellite/satellitedb/users.go +++ b/satellite/satellitedb/users.go @@ -14,6 +14,7 @@ import ( "github.com/zeebo/errs" "storj.io/common/memory" + "storj.io/common/storj" "storj.io/common/uuid" "storj.io/storj/satellite/console" "storj.io/storj/satellite/satellitedb/dbx" @@ -507,6 +508,7 @@ func toUpdateUser(request console.UpdateUserRequest) (*dbx.User_Update_Fields, e update.LoginLockoutExpiration = dbx.User_LoginLockoutExpiration(**request.LoginLockoutExpiration) } } + update.DefaultPlacement = dbx.User_DefaultPlacement(int(request.DefaultPlacement)) return &update, nil } @@ -550,6 +552,10 @@ func userFromDBX(ctx context.Context, user *dbx.User) (_ *console.User, err erro SignupCaptcha: user.SignupCaptcha, } + if user.DefaultPlacement != nil { + result.DefaultPlacement = storj.PlacementConstraint(*user.DefaultPlacement) + } + if user.UserAgent != nil { result.UserAgent = user.UserAgent }