瀏覽代碼

shares: respect password strength

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
Nicola Murino 2 年之前
父節點
當前提交
00366fce07
共有 2 個文件被更改,包括 22 次插入1 次删除
  1. 10 0
      internal/dataprovider/share.go
  2. 12 1
      internal/httpd/httpd_test.go

+ 10 - 0
internal/dataprovider/share.go

@@ -22,6 +22,7 @@ import (
 	"time"
 
 	"github.com/alexedwards/argon2id"
+	passwordvalidator "github.com/wagslane/go-password-validator"
 	"golang.org/x/crypto/bcrypt"
 
 	"github.com/drakkan/sftpgo/v2/internal/logger"
@@ -178,6 +179,15 @@ func (s *Share) HasRedactedPassword() bool {
 
 func (s *Share) hashPassword() error {
 	if s.Password != "" && !util.IsStringPrefixInSlice(s.Password, internalHashPwdPrefixes) {
+		user, err := UserExists(s.Username, "")
+		if err != nil {
+			return util.NewGenericError(fmt.Sprintf("unable to validate user: %v", err))
+		}
+		if minEntropy := user.getMinPasswordEntropy(); minEntropy > 0 {
+			if err := passwordvalidator.Validate(s.Password, minEntropy); err != nil {
+				return util.NewValidationError(err.Error())
+			}
+		}
 		if config.PasswordHashing.Algo == HashingAlgoBcrypt {
 			hashed, err := bcrypt.GenerateFromPassword([]byte(s.Password), config.PasswordHashing.BcryptOptions.Cost)
 			if err != nil {

+ 12 - 1
internal/httpd/httpd_test.go

@@ -14889,9 +14889,11 @@ func TestUserAPIShares(t *testing.T) {
 func TestUsersAPISharesNoPasswordDisabled(t *testing.T) {
 	u := getTestUser()
 	u.Filters.WebClient = []string{sdk.WebClientShareNoPasswordDisabled}
+	u.Filters.PasswordStrength = 70
+	u.Password = "ahpoo8baa6EeZieshies"
 	user, _, err := httpdtest.AddUser(u, http.StatusCreated)
 	assert.NoError(t, err)
-	token, err := getJWTAPIUserTokenFromTestServer(defaultUsername, defaultPassword)
+	token, err := getJWTAPIUserTokenFromTestServer(defaultUsername, u.Password)
 	assert.NoError(t, err)
 
 	share := dataprovider.Share{
@@ -14915,6 +14917,15 @@ func TestUsersAPISharesNoPasswordDisabled(t *testing.T) {
 	assert.NoError(t, err)
 	setBearerForReq(req, token)
 	rr = executeRequest(req)
+	checkResponseCode(t, http.StatusBadRequest, rr)
+
+	share.Password = "vi5eiJoovee5ya9yahpi"
+	asJSON, err = json.Marshal(share)
+	assert.NoError(t, err)
+	req, err = http.NewRequest(http.MethodPost, userSharesPath, bytes.NewBuffer(asJSON))
+	assert.NoError(t, err)
+	setBearerForReq(req, token)
+	rr = executeRequest(req)
 	checkResponseCode(t, http.StatusCreated, rr)
 	location := rr.Header().Get("Location")
 	assert.NotEmpty(t, location)