shares: respect password strength
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
cc381443be
commit
d6b584e064
4 changed files with 24 additions and 3 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 = ""
|
||||||
|
|
|
@ -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'
|
||||||
|
|
Loading…
Reference in a new issue