Browse Source

shares: respect password strength

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
Nicola Murino 2 years ago
parent
commit
d6b584e064

+ 10 - 0
internal/dataprovider/share.go

@@ -22,6 +22,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/alexedwards/argon2id"
 	"github.com/alexedwards/argon2id"
+	passwordvalidator "github.com/wagslane/go-password-validator"
 	"golang.org/x/crypto/bcrypt"
 	"golang.org/x/crypto/bcrypt"
 
 
 	"github.com/drakkan/sftpgo/v2/internal/logger"
 	"github.com/drakkan/sftpgo/v2/internal/logger"
@@ -178,6 +179,15 @@ func (s *Share) HasRedactedPassword() bool {
 
 
 func (s *Share) hashPassword() error {
 func (s *Share) hashPassword() error {
 	if s.Password != "" && !util.IsStringPrefixInSlice(s.Password, internalHashPwdPrefixes) {
 	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 {
 		if config.PasswordHashing.Algo == HashingAlgoBcrypt {
 			hashed, err := bcrypt.GenerateFromPassword([]byte(s.Password), config.PasswordHashing.BcryptOptions.Cost)
 			hashed, err := bcrypt.GenerateFromPassword([]byte(s.Password), config.PasswordHashing.BcryptOptions.Cost)
 			if err != nil {
 			if err != nil {

+ 12 - 1
internal/httpd/httpd_test.go

@@ -14889,9 +14889,11 @@ func TestUserAPIShares(t *testing.T) {
 func TestUsersAPISharesNoPasswordDisabled(t *testing.T) {
 func TestUsersAPISharesNoPasswordDisabled(t *testing.T) {
 	u := getTestUser()
 	u := getTestUser()
 	u.Filters.WebClient = []string{sdk.WebClientShareNoPasswordDisabled}
 	u.Filters.WebClient = []string{sdk.WebClientShareNoPasswordDisabled}
+	u.Filters.PasswordStrength = 70
+	u.Password = "ahpoo8baa6EeZieshies"
 	user, _, err := httpdtest.AddUser(u, http.StatusCreated)
 	user, _, err := httpdtest.AddUser(u, http.StatusCreated)
 	assert.NoError(t, err)
 	assert.NoError(t, err)
-	token, err := getJWTAPIUserTokenFromTestServer(defaultUsername, defaultPassword)
+	token, err := getJWTAPIUserTokenFromTestServer(defaultUsername, u.Password)
 	assert.NoError(t, err)
 	assert.NoError(t, err)
 
 
 	share := dataprovider.Share{
 	share := dataprovider.Share{
@@ -14915,6 +14917,15 @@ func TestUsersAPISharesNoPasswordDisabled(t *testing.T) {
 	assert.NoError(t, err)
 	assert.NoError(t, err)
 	setBearerForReq(req, token)
 	setBearerForReq(req, token)
 	rr = executeRequest(req)
 	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)
 	checkResponseCode(t, http.StatusCreated, rr)
 	location := rr.Header().Get("Location")
 	location := rr.Header().Get("Location")
 	assert.NotEmpty(t, location)
 	assert.NotEmpty(t, location)

+ 1 - 1
internal/version/version.go

@@ -17,7 +17,7 @@ package version
 
 
 import "strings"
 import "strings"
 
 
-const version = "2.5.4"
+const version = "2.5.4-dev"
 
 
 var (
 var (
 	commit = ""
 	commit = ""

+ 1 - 1
openapi/openapi.yaml

@@ -29,7 +29,7 @@ info:
     SFTPGo supports groups to simplify the administration of multiple accounts by letting you assign settings once to a group, instead of multiple times to each individual user.
     SFTPGo supports groups to simplify the administration of multiple accounts by letting you assign settings once to a group, instead of multiple times to each individual user.
     The SFTPGo WebClient allows end users to change their credentials, browse and manage their files in the browser and setup two-factor authentication which works with Authy, Google Authenticator and other compatible apps.
     The SFTPGo WebClient allows end users to change their credentials, browse and manage their files in the browser and setup two-factor authentication which works with Authy, Google Authenticator and other compatible apps.
     From the WebClient each authorized user can also create HTTP/S links to externally share files and folders securely, by setting limits to the number of downloads/uploads, protecting the share with a password, limiting access by source IP address, setting an automatic expiration date.
     From the WebClient each authorized user can also create HTTP/S links to externally share files and folders securely, by setting limits to the number of downloads/uploads, protecting the share with a password, limiting access by source IP address, setting an automatic expiration date.
-  version: 2.5.4
+  version: 2.5.4-dev
   contact:
   contact:
     name: API support
     name: API support
     url: 'https://github.com/drakkan/sftpgo'
     url: 'https://github.com/drakkan/sftpgo'