add cli randomly for empty update (#17740)

give an random cli secret when client gives empty update.

Signed-off-by: Wang Yan <wangyan@vmware.com>

Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
Wang Yan 2022-11-03 21:04:29 +08:00 committed by GitHub
parent 10cb2fd2c7
commit 4fb0a19efb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 0 deletions

View File

@ -19,6 +19,7 @@ import (
"fmt"
"regexp"
"strings"
"time"
"github.com/go-openapi/runtime/middleware"
@ -35,6 +36,7 @@ import (
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/lib/retry"
"github.com/goharbor/harbor/src/pkg/permission/types"
"github.com/goharbor/harbor/src/server/v2.0/handler/model"
"github.com/goharbor/harbor/src/server/v2.0/models"
@ -61,6 +63,13 @@ func (u *usersAPI) SetCliSecret(ctx context.Context, params operation.SetCliSecr
if err := u.requireForCLISecret(ctx, uid); err != nil {
return u.SendError(ctx, err)
}
if params.Secret.Secret == "" {
rSec, err := getRandomSecret()
if err != nil {
return u.SendError(ctx, err)
}
params.Secret.Secret = rSec
}
if err := requireValidSecret(params.Secret.Secret); err != nil {
return u.SendError(ctx, err)
}
@ -444,6 +453,29 @@ func requireValidSecret(in string) error {
return errors.BadRequestError(nil).WithMessage("the password or secret must be longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number")
}
func getRandomSecret() (string, error) {
var cliSecret string
options := []retry.Option{
retry.InitialInterval(time.Millisecond * 500),
retry.MaxInterval(time.Second * 10),
retry.Timeout(time.Minute),
retry.Callback(func(err error, sleep time.Duration) {
log.Debugf("failed to generate secret for cli, retry after %s : %v", sleep, err)
}),
}
if err := retry.Retry(func() error {
cliSecret = utils.GenerateRandomStringWithLen(9)
if err := requireValidSecret(cliSecret); err != nil {
return errors.New(nil).WithMessage("invalid cli secret format")
}
return nil
}, options...); err != nil {
return "", errors.Wrap(err, "failed to generate an valid random secret for cli in one minute, please try again")
}
return cliSecret, nil
}
func validateUserProfile(user *commonmodels.User) error {
if len(user.Email) > 0 {
if m, _ := regexp.MatchString(`^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`, user.Email); !m {

View File

@ -90,6 +90,14 @@ func (uts *UserTestSuite) TestUpdateUserPassword() {
}
}
func (uts *UserTestSuite) TestGetRandomSecret() {
for i := 1; i < 5; i++ {
rSec, err := getRandomSecret()
uts.NoError(err)
uts.NoError(requireValidSecret(rSec))
}
}
func TestUserTestSuite(t *testing.T) {
suite.Run(t, &UserTestSuite{})
}