satellite/console: Prevent duplicate project names for the same user.
issue: https://github.com/storj/storj/issues/5247 Change-Id: Ie51f24dca5b9e5064cb06ae238055177bec5975a
This commit is contained in:
parent
0185bba90a
commit
583ea51fb1
@ -133,7 +133,7 @@ func TestAccountFreezeAlreadyFrozen(t *testing.T) {
|
||||
require.NoError(t, usersDB.UpdateUserProjectLimits(ctx, user.ID, userLimits))
|
||||
|
||||
proj1Limits := randUsageLimits()
|
||||
proj1, err := sat.AddProject(ctx, user.ID, "")
|
||||
proj1, err := sat.AddProject(ctx, user.ID, "project1")
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, projectsDB.UpdateUsageLimits(ctx, proj1.ID, proj1Limits))
|
||||
|
||||
@ -143,7 +143,7 @@ func TestAccountFreezeAlreadyFrozen(t *testing.T) {
|
||||
require.NoError(t, service.FreezeUser(ctx, user.ID))
|
||||
|
||||
proj2Limits := randUsageLimits()
|
||||
proj2, err := sat.AddProject(ctx, user.ID, "")
|
||||
proj2, err := sat.AddProject(ctx, user.ID, "project2")
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, projectsDB.UpdateUsageLimits(ctx, proj2.ID, proj2Limits))
|
||||
|
||||
|
@ -69,6 +69,7 @@ const (
|
||||
activationTokenExpiredErrMsg = "This activation token has expired, please request another one"
|
||||
usedRegTokenErrMsg = "This registration token has already been used"
|
||||
projLimitErrMsg = "Sorry, project creation is limited for your account. Please contact support!"
|
||||
projNameErrMsg = "The new project must have a name you haven't used before!"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -119,6 +120,9 @@ var (
|
||||
|
||||
// ErrRecoveryToken describes account recovery token errors.
|
||||
ErrRecoveryToken = errs.Class("recovery token")
|
||||
|
||||
// ErrProjName is error that occurs with reused project names.
|
||||
ErrProjName = errs.Class("project name")
|
||||
)
|
||||
|
||||
// Service is handling accounts related logic.
|
||||
@ -1489,6 +1493,11 @@ func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p
|
||||
return nil, ErrProjLimit.Wrap(err)
|
||||
}
|
||||
|
||||
passesNameCheck, err := s.checkProjectName(ctx, projectInfo, user.ID)
|
||||
if err != nil || !passesNameCheck {
|
||||
return nil, ErrProjName.Wrap(err)
|
||||
}
|
||||
|
||||
newProjectLimits, err := s.getUserProjectLimits(ctx, user.ID)
|
||||
if err != nil {
|
||||
return nil, ErrProjLimit.Wrap(err)
|
||||
@ -1695,7 +1704,14 @@ func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, update
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
project := isMember.project
|
||||
if updatedProject.Name != project.Name {
|
||||
passesNameCheck, err := s.checkProjectName(ctx, updatedProject, user.ID)
|
||||
if err != nil || !passesNameCheck {
|
||||
return nil, ErrProjName.Wrap(err)
|
||||
}
|
||||
}
|
||||
project.Name = updatedProject.Name
|
||||
project.Description = updatedProject.Description
|
||||
|
||||
@ -2776,6 +2792,25 @@ func (s *Service) checkProjectLimit(ctx context.Context, userID uuid.UUID) (curr
|
||||
return len(projects), nil
|
||||
}
|
||||
|
||||
// checkProjectName is used to check if user has used project name before.
|
||||
func (s *Service) checkProjectName(ctx context.Context, projectInfo ProjectInfo, userID uuid.UUID) (passesNameCheck bool, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
passesCheck := true
|
||||
|
||||
projects, err := s.store.Projects().GetOwn(ctx, userID)
|
||||
if err != nil {
|
||||
return false, Error.Wrap(err)
|
||||
}
|
||||
|
||||
for _, project := range projects {
|
||||
if project.Name == projectInfo.Name {
|
||||
return false, ErrProjName.New(projNameErrMsg)
|
||||
}
|
||||
}
|
||||
|
||||
return passesCheck, nil
|
||||
}
|
||||
|
||||
// getUserProjectLimits is a method to get the users storage and bandwidth limits for new projects.
|
||||
func (s *Service) getUserProjectLimits(ctx context.Context, userID uuid.UUID) (_ *UsageLimits, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
@ -91,6 +91,15 @@ func TestService(t *testing.T) {
|
||||
require.Nil(t, salt)
|
||||
})
|
||||
|
||||
t.Run("CreateProject", func(t *testing.T) {
|
||||
// Creating a project with a previously used name should fail
|
||||
createdProject, err := service.CreateProject(userCtx1, console.ProjectInfo{
|
||||
Name: up1Pro1.Name,
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.Nil(t, createdProject)
|
||||
})
|
||||
|
||||
t.Run("UpdateProject", func(t *testing.T) {
|
||||
updatedName := "newName"
|
||||
updatedDescription := "newDescription"
|
||||
@ -188,6 +197,13 @@ func TestService(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, updateInfo.StorageLimit, *project.StorageLimit)
|
||||
require.Equal(t, updateInfo.BandwidthLimit, *project.BandwidthLimit)
|
||||
|
||||
// attempting to update a project with a previously used name should fail
|
||||
updatedProject, err = service.UpdateProject(userCtx1, up2Pro1.ID, console.ProjectInfo{
|
||||
Name: up1Pro1.Name,
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.Nil(t, updatedProject)
|
||||
})
|
||||
|
||||
t.Run("AddProjectMembers", func(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user