fix a potential race condition for pre-login and ext auth

hooks

doing something like this:

err = provider.updateUser(u)
...
return provider.userExists(username)

could be racy if another update happen before

provider.userExists(username)

also pass a pointer to updateUser so if the user is modified inside
"validateUser" we can just return the modified user without do a new
query
This commit is contained in:
Nicola Murino 2021-01-05 09:50:22 +01:00
parent 72b2c83392
commit daac90c4e1
No known key found for this signature in database
GPG key ID: 2F1FB59433D5A8CB
26 changed files with 167 additions and 163 deletions

View file

@ -96,7 +96,7 @@ Command-line flags should be specified in the Subsystem declaration.
if user.HomeDir != filepath.Clean(homedir) && !preserveHomeDir {
// update the user
user.HomeDir = filepath.Clean(homedir)
err = dataprovider.UpdateUser(user)
err = dataprovider.UpdateUser(&user)
if err != nil {
logger.Error(logSender, connectionID, "unable to update user %#v: %v", username, err)
os.Exit(1)
@ -113,7 +113,7 @@ Command-line flags should be specified in the Subsystem declaration.
user.Password = connectionID
user.Permissions = make(map[string][]string)
user.Permissions["/"] = []string{dataprovider.PermAny}
err = dataprovider.AddUser(user)
err = dataprovider.AddUser(&user)
if err != nil {
logger.Error(logSender, connectionID, "unable to add user %#v: %v", username, err)
os.Exit(1)

View file

@ -364,7 +364,7 @@ func (c *Configuration) GetProxyListener(listener net.Listener) (*proxyproto.Lis
// ExecutePostConnectHook executes the post connect hook if defined
func (c *Configuration) ExecutePostConnectHook(ipAddr, protocol string) error {
if len(c.PostConnectHook) == 0 {
if c.PostConnectHook == "" {
return nil
}
if strings.HasPrefix(c.PostConnectHook, "http") {
@ -594,7 +594,7 @@ func (conns *ActiveConnections) checkIdles() {
for _, c := range conns.connections {
idleTime := time.Since(c.GetLastActivity())
isUnauthenticatedFTPUser := (c.GetProtocol() == ProtocolFTP && len(c.GetUsername()) == 0)
isUnauthenticatedFTPUser := (c.GetProtocol() == ProtocolFTP && c.GetUsername() == "")
if idleTime > Config.idleTimeoutAsDuration || (isUnauthenticatedFTPUser && idleTime > Config.idleLoginTimeout) {
defer func(conn ActiveConnection, isFTPNoAuth bool) {

View file

@ -1031,7 +1031,7 @@ func TestHasSpace(t *testing.T) {
user.VirtualFolders[0].QuotaFiles = 0
user.VirtualFolders[0].QuotaSize = 0
err = dataprovider.AddUser(user)
err = dataprovider.AddUser(&user)
assert.NoError(t, err)
user, err = dataprovider.UserExists(user.Username)
assert.NoError(t, err)
@ -1041,7 +1041,7 @@ func TestHasSpace(t *testing.T) {
user.VirtualFolders[0].QuotaFiles = 10
user.VirtualFolders[0].QuotaSize = 1048576
err = dataprovider.UpdateUser(user)
err = dataprovider.UpdateUser(&user)
assert.NoError(t, err)
c.User = user
quotaResult = c.HasSpace(true, "/vdir/file1")
@ -1057,10 +1057,10 @@ func TestHasSpace(t *testing.T) {
quotaResult = c.HasSpace(true, "/vdir/file1")
assert.False(t, quotaResult.HasSpace)
err = dataprovider.DeleteUser(user)
err = dataprovider.DeleteUser(&user)
assert.NoError(t, err)
err = dataprovider.DeleteFolder(folder)
err = dataprovider.DeleteFolder(&folder)
assert.NoError(t, err)
}
@ -1091,7 +1091,7 @@ func TestUpdateQuotaMoveVFolders(t *testing.T) {
QuotaFiles: -1,
QuotaSize: -1,
})
err := dataprovider.AddUser(user)
err := dataprovider.AddUser(&user)
assert.NoError(t, err)
user, err = dataprovider.UserExists(user.Username)
assert.NoError(t, err)
@ -1148,11 +1148,11 @@ func TestUpdateQuotaMoveVFolders(t *testing.T) {
assert.Equal(t, 1, user.UsedQuotaFiles)
assert.Equal(t, int64(100), user.UsedQuotaSize)
err = dataprovider.DeleteUser(user)
err = dataprovider.DeleteUser(&user)
assert.NoError(t, err)
err = dataprovider.DeleteFolder(folder1)
err = dataprovider.DeleteFolder(&folder1)
assert.NoError(t, err)
err = dataprovider.DeleteFolder(folder2)
err = dataprovider.DeleteFolder(&folder2)
assert.NoError(t, err)
}

View file

@ -171,19 +171,15 @@ func (m *CertManager) LoadRootCAs() error {
return nil
}
// SetCACertificates sets the root CA authorities file paths
// SetCACertificates sets the root CA authorities file paths.
// This should not be changed at runtime
func (m *CertManager) SetCACertificates(caCertificates []string) {
m.Lock()
defer m.Unlock()
m.caCertificates = caCertificates
}
// SetCARevocationLists sets the CA revocation lists file paths
// SetCARevocationLists sets the CA revocation lists file paths.
// This should not be changed at runtime
func (m *CertManager) SetCARevocationLists(caRevocationLists []string) {
m.Lock()
defer m.Unlock()
m.caRevocationLists = caRevocationLists
}

View file

@ -101,7 +101,7 @@ func (p BoltProvider) checkAvailability() error {
func (p BoltProvider) validateUserAndPass(username, password, ip, protocol string) (User, error) {
var user User
if len(password) == 0 {
if password == "" {
return user, errors.New("Credentials cannot be null or empty")
}
user, err := p.userExists(username)
@ -246,8 +246,8 @@ func (p BoltProvider) userExists(username string) (User, error) {
return user, err
}
func (p BoltProvider) addUser(user User) error {
err := validateUser(&user)
func (p BoltProvider) addUser(user *User) error {
err := validateUser(user)
if err != nil {
return err
}
@ -291,8 +291,8 @@ func (p BoltProvider) addUser(user User) error {
})
}
func (p BoltProvider) updateUser(user User) error {
err := validateUser(&user)
func (p BoltProvider) updateUser(user *User) error {
err := validateUser(user)
if err != nil {
return err
}
@ -315,7 +315,7 @@ func (p BoltProvider) updateUser(user User) error {
return err
}
for _, folder := range oldUser.VirtualFolders {
err = removeUserFromFolderMapping(folder, oldUser, folderBucket)
err = removeUserFromFolderMapping(folder, &oldUser, folderBucket)
if err != nil {
return err
}
@ -339,7 +339,7 @@ func (p BoltProvider) updateUser(user User) error {
})
}
func (p BoltProvider) deleteUser(user User) error {
func (p BoltProvider) deleteUser(user *User) error {
return p.dbHandle.Update(func(tx *bolt.Tx) error {
bucket, idxBucket, err := getBuckets(tx)
if err != nil {
@ -567,8 +567,8 @@ func (p BoltProvider) getFolderByPath(name string) (vfs.BaseVirtualFolder, error
return folder, err
}
func (p BoltProvider) addFolder(folder vfs.BaseVirtualFolder) error {
err := validateFolder(&folder)
func (p BoltProvider) addFolder(folder *vfs.BaseVirtualFolder) error {
err := validateFolder(folder)
if err != nil {
return err
}
@ -580,12 +580,12 @@ func (p BoltProvider) addFolder(folder vfs.BaseVirtualFolder) error {
if f := bucket.Get([]byte(folder.MappedPath)); f != nil {
return fmt.Errorf("folder %v already exists", folder.MappedPath)
}
_, err = addFolderInternal(folder, bucket)
_, err = addFolderInternal(*folder, bucket)
return err
})
}
func (p BoltProvider) deleteFolder(folder vfs.BaseVirtualFolder) error {
func (p BoltProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error {
return p.dbHandle.Update(func(tx *bolt.Tx) error {
bucket, err := getFolderBucket(tx)
if err != nil {
@ -816,7 +816,7 @@ func addFolderInternal(folder vfs.BaseVirtualFolder, bucket *bolt.Bucket) (vfs.B
return folder, err
}
func addUserToFolderMapping(folder vfs.VirtualFolder, user User, bucket *bolt.Bucket) error {
func addUserToFolderMapping(folder vfs.VirtualFolder, user *User, bucket *bolt.Bucket) error {
var baseFolder vfs.BaseVirtualFolder
var err error
if f := bucket.Get([]byte(folder.MappedPath)); f == nil {
@ -842,7 +842,7 @@ func addUserToFolderMapping(folder vfs.VirtualFolder, user User, bucket *bolt.Bu
return err
}
func removeUserFromFolderMapping(folder vfs.VirtualFolder, user User, bucket *bolt.Bucket) error {
func removeUserFromFolderMapping(folder vfs.VirtualFolder, user *User, bucket *bolt.Bucket) error {
var f []byte
if f = bucket.Get([]byte(folder.MappedPath)); f == nil {
// the folder does not exists so there is no associated user
@ -940,7 +940,7 @@ func updateDatabaseFrom1To2(dbHandle *bolt.DB) error {
return err
}
user.Status = 1
err = provider.updateUser(user)
err = provider.updateUser(&user)
if err != nil {
return err
}
@ -994,7 +994,8 @@ func updateDatabaseFrom2To3(dbHandle *bolt.DB) error {
}
for _, user := range users {
err = provider.updateUser(user)
user := user
err = provider.updateUser(&user)
if err != nil {
return err
}
@ -1053,7 +1054,7 @@ func updateDatabaseFrom3To4(dbHandle *bolt.DB) error {
}
}
user.VirtualFolders = folders
err = provider.updateUser(user)
err = provider.updateUser(&user)
providerLog(logger.LevelInfo, "number of virtual folders to restore %v, user %#v, error: %v", len(user.VirtualFolders),
user.Username, err)
if err != nil {

View file

@ -367,17 +367,17 @@ type Provider interface {
updateQuota(username string, filesAdd int, sizeAdd int64, reset bool) error
getUsedQuota(username string) (int, int64, error)
userExists(username string) (User, error)
addUser(user User) error
updateUser(user User) error
deleteUser(user User) error
addUser(user *User) error
updateUser(user *User) error
deleteUser(user *User) error
getUsers(limit int, offset int, order string, username string) ([]User, error)
dumpUsers() ([]User, error)
getUserByID(ID int64) (User, error)
updateLastLogin(username string) error
getFolders(limit, offset int, order, folderPath string) ([]vfs.BaseVirtualFolder, error)
getFolderByPath(mappedPath string) (vfs.BaseVirtualFolder, error)
addFolder(folder vfs.BaseVirtualFolder) error
deleteFolder(folder vfs.BaseVirtualFolder) error
addFolder(folder *vfs.BaseVirtualFolder) error
deleteFolder(folder *vfs.BaseVirtualFolder) error
updateFolderQuota(mappedPath string, filesAdd int, sizeAdd int64, reset bool) error
getUsedFolderQuota(mappedPath string) (int, int64, error)
dumpFolders() ([]vfs.BaseVirtualFolder, error)
@ -439,16 +439,16 @@ func Initialize(cnf Config, basePath string) error {
func validateHooks() error {
var hooks []string
if len(config.PreLoginHook) > 0 && !strings.HasPrefix(config.PreLoginHook, "http") {
if config.PreLoginHook != "" && !strings.HasPrefix(config.PreLoginHook, "http") {
hooks = append(hooks, config.PreLoginHook)
}
if len(config.ExternalAuthHook) > 0 && !strings.HasPrefix(config.ExternalAuthHook, "http") {
if config.ExternalAuthHook != "" && !strings.HasPrefix(config.ExternalAuthHook, "http") {
hooks = append(hooks, config.ExternalAuthHook)
}
if len(config.PostLoginHook) > 0 && !strings.HasPrefix(config.PostLoginHook, "http") {
if config.PostLoginHook != "" && !strings.HasPrefix(config.PostLoginHook, "http") {
hooks = append(hooks, config.PostLoginHook)
}
if len(config.CheckPasswordHook) > 0 && !strings.HasPrefix(config.CheckPasswordHook, "http") {
if config.CheckPasswordHook != "" && !strings.HasPrefix(config.CheckPasswordHook, "http") {
hooks = append(hooks, config.CheckPasswordHook)
}
@ -527,14 +527,14 @@ func RevertDatabase(cnf Config, basePath string, targetVersion int) error {
// CheckUserAndPass retrieves the SFTP user with the given username and password if a match is found or an error
func CheckUserAndPass(username, password, ip, protocol string) (User, error) {
if len(config.ExternalAuthHook) > 0 && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&1 != 0) {
if config.ExternalAuthHook != "" && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&1 != 0) {
user, err := doExternalAuth(username, password, nil, "", ip, protocol)
if err != nil {
return user, err
}
return checkUserAndPass(user, password, ip, protocol)
}
if len(config.PreLoginHook) > 0 {
if config.PreLoginHook != "" {
user, err := executePreLoginHook(username, LoginMethodPassword, ip, protocol)
if err != nil {
return user, err
@ -546,14 +546,14 @@ func CheckUserAndPass(username, password, ip, protocol string) (User, error) {
// CheckUserAndPubKey retrieves the SFTP user with the given username and public key if a match is found or an error
func CheckUserAndPubKey(username string, pubKey []byte, ip, protocol string) (User, string, error) {
if len(config.ExternalAuthHook) > 0 && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&2 != 0) {
if config.ExternalAuthHook != "" && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&2 != 0) {
user, err := doExternalAuth(username, "", pubKey, "", ip, protocol)
if err != nil {
return user, "", err
}
return checkUserAndPubKey(user, pubKey)
}
if len(config.PreLoginHook) > 0 {
if config.PreLoginHook != "" {
user, err := executePreLoginHook(username, SSHLoginMethodPublicKey, ip, protocol)
if err != nil {
return user, "", err
@ -568,9 +568,9 @@ func CheckUserAndPubKey(username string, pubKey []byte, ip, protocol string) (Us
func CheckKeyboardInteractiveAuth(username, authHook string, client ssh.KeyboardInteractiveChallenge, ip, protocol string) (User, error) {
var user User
var err error
if len(config.ExternalAuthHook) > 0 && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&4 != 0) {
if config.ExternalAuthHook != "" && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&4 != 0) {
user, err = doExternalAuth(username, "", nil, "1", ip, protocol)
} else if len(config.PreLoginHook) > 0 {
} else if config.PreLoginHook != "" {
user, err = executePreLoginHook(username, SSHLoginMethodKeyboardInteractive, ip, protocol)
} else {
user, err = provider.userExists(username)
@ -653,41 +653,41 @@ func UserExists(username string) (User, error) {
// AddUser adds a new SFTPGo user.
// ManageUsers configuration must be set to 1 to enable this method
func AddUser(user User) error {
func AddUser(user *User) error {
if config.ManageUsers == 0 {
return &MethodDisabledError{err: manageUsersDisabledError}
}
err := provider.addUser(user)
if err == nil {
go executeAction(operationAdd, user)
go executeAction(operationAdd, *user)
}
return err
}
// UpdateUser updates an existing SFTPGo user.
// ManageUsers configuration must be set to 1 to enable this method
func UpdateUser(user User) error {
func UpdateUser(user *User) error {
if config.ManageUsers == 0 {
return &MethodDisabledError{err: manageUsersDisabledError}
}
err := provider.updateUser(user)
if err == nil {
RemoveCachedWebDAVUser(user.Username)
go executeAction(operationUpdate, user)
go executeAction(operationUpdate, *user)
}
return err
}
// DeleteUser deletes an existing SFTPGo user.
// ManageUsers configuration must be set to 1 to enable this method
func DeleteUser(user User) error {
func DeleteUser(user *User) error {
if config.ManageUsers == 0 {
return &MethodDisabledError{err: manageUsersDisabledError}
}
err := provider.deleteUser(user)
if err == nil {
RemoveCachedWebDAVUser(user.Username)
go executeAction(operationDelete, user)
go executeAction(operationDelete, *user)
}
return err
}
@ -711,7 +711,7 @@ func GetUserByID(ID int64) (User, error) {
// AddFolder adds a new virtual folder.
// ManageUsers configuration must be set to 1 to enable this method
func AddFolder(folder vfs.BaseVirtualFolder) error {
func AddFolder(folder *vfs.BaseVirtualFolder) error {
if config.ManageUsers == 0 {
return &MethodDisabledError{err: manageUsersDisabledError}
}
@ -720,7 +720,7 @@ func AddFolder(folder vfs.BaseVirtualFolder) error {
// DeleteFolder deletes an existing folder.
// ManageUsers configuration must be set to 1 to enable this method
func DeleteFolder(folder vfs.BaseVirtualFolder) error {
func DeleteFolder(folder *vfs.BaseVirtualFolder) error {
if config.ManageUsers == 0 {
return &MethodDisabledError{err: manageUsersDisabledError}
}
@ -1303,7 +1303,7 @@ func validateUser(user *User) error {
return nil
}
func checkLoginConditions(user User) error {
func checkLoginConditions(user *User) error {
if user.Status < 1 {
return fmt.Errorf("user %#v is disabled", user.Username)
}
@ -1344,11 +1344,11 @@ func isPasswordOK(user *User, password string) (bool, error) {
}
func checkUserAndPass(user User, password, ip, protocol string) (User, error) {
err := checkLoginConditions(user)
err := checkLoginConditions(&user)
if err != nil {
return user, err
}
if len(user.Password) == 0 {
if user.Password == "" {
return user, errors.New("Credentials cannot be null or empty")
}
hookResponse, err := executeCheckPasswordHook(user.Username, password, ip, protocol)
@ -1378,7 +1378,7 @@ func checkUserAndPass(user User, password, ip, protocol string) (User, error) {
}
func checkUserAndPubKey(user User, pubKey []byte) (User, string, error) {
err := checkLoginConditions(user)
err := checkLoginConditions(&user)
if err != nil {
return user, "", err
}
@ -1731,7 +1731,7 @@ func doKeyboardInteractiveAuth(user User, authHook string, client ssh.KeyboardIn
if authResult != 1 {
return user, fmt.Errorf("keyboard interactive auth failed, result: %v", authResult)
}
err = checkLoginConditions(user)
err = checkLoginConditions(&user)
if err != nil {
return user, err
}
@ -1739,7 +1739,7 @@ func doKeyboardInteractiveAuth(user User, authHook string, client ssh.KeyboardIn
}
func isCheckPasswordHookDefined(protocol string) bool {
if len(config.CheckPasswordHook) == 0 {
if config.CheckPasswordHook == "" {
return false
}
if config.CheckPasswordScope == 0 {
@ -1900,20 +1900,23 @@ func executePreLoginHook(username, loginMethod, ip, protocol string) (User, erro
u.LastQuotaUpdate = userLastQuotaUpdate
u.LastLogin = userLastLogin
if userID == 0 {
err = provider.addUser(u)
err = provider.addUser(&u)
} else {
err = provider.updateUser(u)
err = provider.updateUser(&u)
}
if err != nil {
return u, err
}
providerLog(logger.LevelDebug, "user %#v added/updated from pre-login hook response, id: %v", username, userID)
return provider.userExists(username)
if userID == 0 {
return provider.userExists(username)
}
return u, nil
}
// ExecutePostLoginHook executes the post login hook if defined
func ExecutePostLoginHook(username, loginMethod, ip, protocol string, err error) {
if len(config.PostLoginHook) == 0 {
if config.PostLoginHook == "" {
return
}
if config.PostLoginScope == 1 && err == nil {
@ -2047,7 +2050,7 @@ func doExternalAuth(username, password string, pubKey []byte, keyboardInteractiv
if len(pkey) > 0 && !utils.IsStringPrefixInSlice(pkey, user.PublicKeys) {
user.PublicKeys = append(user.PublicKeys, pkey)
}
// some users want to map multiple login usernames with a single SGTPGo account
// some users want to map multiple login usernames with a single SFTPGo account
// for example an SFTP user logins using "user1" or "user2" and the external auth
// returns "user" in both cases, so we use the username returned from
// external auth and not the one used to login
@ -2058,10 +2061,10 @@ func doExternalAuth(username, password string, pubKey []byte, keyboardInteractiv
user.UsedQuotaFiles = u.UsedQuotaFiles
user.LastQuotaUpdate = u.LastQuotaUpdate
user.LastLogin = u.LastLogin
err = provider.updateUser(user)
} else {
err = provider.addUser(user)
err = provider.updateUser(&user)
return user, err
}
err = provider.addUser(&user)
if err != nil {
return user, err
}
@ -2174,7 +2177,7 @@ func CacheWebDAVUser(cachedUser *CachedUser, maxSize int) {
webDAVUsersCache.Range(func(k, v interface{}) bool {
cacheSize++
if len(userToRemove) == 0 {
if userToRemove == "" {
userToRemove = k.(string)
expirationTime = v.(*CachedUser).Expiration
return true

View file

@ -88,7 +88,7 @@ func (p MemoryProvider) close() error {
func (p MemoryProvider) validateUserAndPass(username, password, ip, protocol string) (User, error) {
var user User
if len(password) == 0 {
if password == "" {
return user, errors.New("Credentials cannot be null or empty")
}
user, err := p.userExists(username)
@ -178,13 +178,13 @@ func (p MemoryProvider) getUsedQuota(username string) (int, int64, error) {
return user.UsedQuotaFiles, user.UsedQuotaSize, err
}
func (p MemoryProvider) addUser(user User) error {
func (p MemoryProvider) addUser(user *User) error {
p.dbHandle.Lock()
defer p.dbHandle.Unlock()
if p.dbHandle.isClosed {
return errMemoryProviderClosed
}
err := validateUser(&user)
err := validateUser(user)
if err != nil {
return err
}
@ -198,20 +198,20 @@ func (p MemoryProvider) addUser(user User) error {
user.UsedQuotaFiles = 0
user.LastLogin = 0
user.VirtualFolders = p.joinVirtualFoldersFields(user)
p.dbHandle.users[user.Username] = user
p.dbHandle.users[user.Username] = user.getACopy()
p.dbHandle.usersIdx[user.ID] = user.Username
p.dbHandle.usernames = append(p.dbHandle.usernames, user.Username)
sort.Strings(p.dbHandle.usernames)
return nil
}
func (p MemoryProvider) updateUser(user User) error {
func (p MemoryProvider) updateUser(user *User) error {
p.dbHandle.Lock()
defer p.dbHandle.Unlock()
if p.dbHandle.isClosed {
return errMemoryProviderClosed
}
err := validateUser(&user)
err := validateUser(user)
if err != nil {
return err
}
@ -227,11 +227,12 @@ func (p MemoryProvider) updateUser(user User) error {
user.UsedQuotaSize = u.UsedQuotaSize
user.UsedQuotaFiles = u.UsedQuotaFiles
user.LastLogin = u.LastLogin
p.dbHandle.users[user.Username] = user
// pre-login and external auth hook will use the passed *user so save a copy
p.dbHandle.users[user.Username] = user.getACopy()
return nil
}
func (p MemoryProvider) deleteUser(user User) error {
func (p MemoryProvider) deleteUser(user *User) error {
p.dbHandle.Lock()
defer p.dbHandle.Unlock()
if p.dbHandle.isClosed {
@ -247,7 +248,7 @@ func (p MemoryProvider) deleteUser(user User) error {
delete(p.dbHandle.users, user.Username)
delete(p.dbHandle.usersIdx, user.ID)
// this could be more efficient
p.dbHandle.usernames = []string{}
p.dbHandle.usernames = make([]string, 0, len(p.dbHandle.users))
for username := range p.dbHandle.users {
p.dbHandle.usernames = append(p.dbHandle.usernames, username)
}
@ -396,7 +397,7 @@ func (p MemoryProvider) getUsedFolderQuota(mappedPath string) (int, int64, error
return folder.UsedQuotaFiles, folder.UsedQuotaSize, err
}
func (p MemoryProvider) joinVirtualFoldersFields(user User) []vfs.VirtualFolder {
func (p MemoryProvider) joinVirtualFoldersFields(user *User) []vfs.VirtualFolder {
var folders []vfs.VirtualFolder
for _, folder := range user.VirtualFolders {
f, err := p.addOrGetFolderInternal(folder.MappedPath, user.Username, folder.UsedQuotaSize, folder.UsedQuotaFiles,
@ -522,13 +523,13 @@ func (p MemoryProvider) getFolderByPath(mappedPath string) (vfs.BaseVirtualFolde
return p.folderExistsInternal(mappedPath)
}
func (p MemoryProvider) addFolder(folder vfs.BaseVirtualFolder) error {
func (p MemoryProvider) addFolder(folder *vfs.BaseVirtualFolder) error {
p.dbHandle.Lock()
defer p.dbHandle.Unlock()
if p.dbHandle.isClosed {
return errMemoryProviderClosed
}
err := validateFolder(&folder)
err := validateFolder(folder)
if err != nil {
return err
}
@ -537,13 +538,13 @@ func (p MemoryProvider) addFolder(folder vfs.BaseVirtualFolder) error {
return fmt.Errorf("folder %#v already exists", folder.MappedPath)
}
folder.ID = p.getNextFolderID()
p.dbHandle.vfolders[folder.MappedPath] = folder
p.dbHandle.vfolders[folder.MappedPath] = *folder
p.dbHandle.vfoldersPaths = append(p.dbHandle.vfoldersPaths, folder.MappedPath)
sort.Strings(p.dbHandle.vfoldersPaths)
return nil
}
func (p MemoryProvider) deleteFolder(folder vfs.BaseVirtualFolder) error {
func (p MemoryProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error {
p.dbHandle.Lock()
defer p.dbHandle.Unlock()
if p.dbHandle.isClosed {
@ -644,8 +645,9 @@ func (p MemoryProvider) reloadConfig() error {
logger.Debug(logSender, "", "folder %#v already exists, restore not needed", folder.MappedPath)
continue
}
folder := folder // pin
folder.Users = nil
err = p.addFolder(folder)
err = p.addFolder(&folder)
if err != nil {
providerLog(logger.LevelWarn, "error adding folder %#v: %v", folder.MappedPath, err)
return err
@ -653,15 +655,16 @@ func (p MemoryProvider) reloadConfig() error {
}
for _, user := range dump.Users {
u, err := p.userExists(user.Username)
user := user // pin
if err == nil {
user.ID = u.ID
err = p.updateUser(user)
err = p.updateUser(&user)
if err != nil {
providerLog(logger.LevelWarn, "error updating user %#v: %v", user.Username, err)
return err
}
} else {
err = p.addUser(user)
err = p.addUser(&user)
if err != nil {
providerLog(logger.LevelWarn, "error adding user %#v: %v", user.Username, err)
return err

View file

@ -74,7 +74,7 @@ func initializeMySQLProvider() error {
}
func getMySQLConnectionString(redactedPwd bool) string {
var connectionString string
if len(config.ConnectionString) == 0 {
if config.ConnectionString == "" {
password := config.Password
if redactedPwd {
password = "[redacted]"
@ -119,15 +119,15 @@ func (p MySQLProvider) userExists(username string) (User, error) {
return sqlCommonCheckUserExists(username, p.dbHandle)
}
func (p MySQLProvider) addUser(user User) error {
func (p MySQLProvider) addUser(user *User) error {
return sqlCommonAddUser(user, p.dbHandle)
}
func (p MySQLProvider) updateUser(user User) error {
func (p MySQLProvider) updateUser(user *User) error {
return sqlCommonUpdateUser(user, p.dbHandle)
}
func (p MySQLProvider) deleteUser(user User) error {
func (p MySQLProvider) deleteUser(user *User) error {
return sqlCommonDeleteUser(user, p.dbHandle)
}
@ -153,11 +153,11 @@ func (p MySQLProvider) getFolderByPath(mappedPath string) (vfs.BaseVirtualFolder
return sqlCommonCheckFolderExists(ctx, mappedPath, p.dbHandle)
}
func (p MySQLProvider) addFolder(folder vfs.BaseVirtualFolder) error {
func (p MySQLProvider) addFolder(folder *vfs.BaseVirtualFolder) error {
return sqlCommonAddFolder(folder, p.dbHandle)
}
func (p MySQLProvider) deleteFolder(folder vfs.BaseVirtualFolder) error {
func (p MySQLProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error {
return sqlCommonDeleteFolder(folder, p.dbHandle)
}

View file

@ -75,7 +75,7 @@ func initializePGSQLProvider() error {
func getPGSQLConnectionString(redactedPwd bool) string {
var connectionString string
if len(config.ConnectionString) == 0 {
if config.ConnectionString == "" {
password := config.Password
if redactedPwd {
password = "[redacted]"
@ -120,15 +120,15 @@ func (p PGSQLProvider) userExists(username string) (User, error) {
return sqlCommonCheckUserExists(username, p.dbHandle)
}
func (p PGSQLProvider) addUser(user User) error {
func (p PGSQLProvider) addUser(user *User) error {
return sqlCommonAddUser(user, p.dbHandle)
}
func (p PGSQLProvider) updateUser(user User) error {
func (p PGSQLProvider) updateUser(user *User) error {
return sqlCommonUpdateUser(user, p.dbHandle)
}
func (p PGSQLProvider) deleteUser(user User) error {
func (p PGSQLProvider) deleteUser(user *User) error {
return sqlCommonDeleteUser(user, p.dbHandle)
}
@ -154,11 +154,11 @@ func (p PGSQLProvider) getFolderByPath(mappedPath string) (vfs.BaseVirtualFolder
return sqlCommonCheckFolderExists(ctx, mappedPath, p.dbHandle)
}
func (p PGSQLProvider) addFolder(folder vfs.BaseVirtualFolder) error {
func (p PGSQLProvider) addFolder(folder *vfs.BaseVirtualFolder) error {
return sqlCommonAddFolder(folder, p.dbHandle)
}
func (p PGSQLProvider) deleteFolder(folder vfs.BaseVirtualFolder) error {
func (p PGSQLProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error {
return sqlCommonDeleteFolder(folder, p.dbHandle)
}

View file

@ -48,7 +48,7 @@ func getUserByUsername(username string, dbHandle sqlQuerier) (User, error) {
func sqlCommonValidateUserAndPass(username, password, ip, protocol string, dbHandle *sql.DB) (User, error) {
var user User
if len(password) == 0 {
if password == "" {
return user, errors.New("Credentials cannot be null or empty")
}
user, err := getUserByUsername(username, dbHandle)
@ -177,8 +177,8 @@ func sqlCommonCheckUserExists(username string, dbHandle *sql.DB) (User, error) {
return getUserWithVirtualFolders(user, dbHandle)
}
func sqlCommonAddUser(user User, dbHandle *sql.DB) error {
err := validateUser(&user)
func sqlCommonAddUser(user *User, dbHandle *sql.DB) error {
err := validateUser(user)
if err != nil {
return err
}
@ -231,8 +231,8 @@ func sqlCommonAddUser(user User, dbHandle *sql.DB) error {
return tx.Commit()
}
func sqlCommonUpdateUser(user User, dbHandle *sql.DB) error {
err := validateUser(&user)
func sqlCommonUpdateUser(user *User, dbHandle *sql.DB) error {
err := validateUser(user)
if err != nil {
return err
}
@ -285,7 +285,7 @@ func sqlCommonUpdateUser(user User, dbHandle *sql.DB) error {
return tx.Commit()
}
func sqlCommonDeleteUser(user User, dbHandle *sql.DB) error {
func sqlCommonDeleteUser(user *User, dbHandle *sql.DB) error {
ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
defer cancel()
q := getDeleteUserQuery()
@ -470,7 +470,7 @@ func sqlCommonCheckFolderExists(ctx context.Context, name string, dbHandle sqlQu
func sqlCommonAddOrGetFolder(ctx context.Context, name string, usedQuotaSize int64, usedQuotaFiles int, lastQuotaUpdate int64, dbHandle sqlQuerier) (vfs.BaseVirtualFolder, error) {
folder, err := sqlCommonCheckFolderExists(ctx, name, dbHandle)
if _, ok := err.(*RecordNotFoundError); ok {
f := vfs.BaseVirtualFolder{
f := &vfs.BaseVirtualFolder{
MappedPath: name,
UsedQuotaSize: usedQuotaSize,
UsedQuotaFiles: usedQuotaFiles,
@ -485,8 +485,8 @@ func sqlCommonAddOrGetFolder(ctx context.Context, name string, usedQuotaSize int
return folder, err
}
func sqlCommonAddFolder(folder vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
err := validateFolder(&folder)
func sqlCommonAddFolder(folder *vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
err := validateFolder(folder)
if err != nil {
return err
}
@ -503,7 +503,7 @@ func sqlCommonAddFolder(folder vfs.BaseVirtualFolder, dbHandle sqlQuerier) error
return err
}
func sqlCommonDeleteFolder(folder vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
func sqlCommonDeleteFolder(folder *vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
defer cancel()
q := getDeleteFolderQuery()
@ -585,7 +585,7 @@ func sqlCommonGetFolders(limit, offset int, order, folderPath string, dbHandle s
return getVirtualFoldersWithUsers(folders, dbHandle)
}
func sqlCommonClearFolderMapping(ctx context.Context, user User, dbHandle sqlQuerier) error {
func sqlCommonClearFolderMapping(ctx context.Context, user *User, dbHandle sqlQuerier) error {
q := getClearFolderMappingQuery()
stmt, err := dbHandle.PrepareContext(ctx, q)
if err != nil {
@ -597,7 +597,7 @@ func sqlCommonClearFolderMapping(ctx context.Context, user User, dbHandle sqlQue
return err
}
func sqlCommonAddFolderMapping(ctx context.Context, user User, folder vfs.VirtualFolder, dbHandle sqlQuerier) error {
func sqlCommonAddFolderMapping(ctx context.Context, user *User, folder vfs.VirtualFolder, dbHandle sqlQuerier) error {
q := getAddFolderMappingQuery()
stmt, err := dbHandle.PrepareContext(ctx, q)
if err != nil {
@ -609,7 +609,7 @@ func sqlCommonAddFolderMapping(ctx context.Context, user User, folder vfs.Virtua
return err
}
func generateVirtualFoldersMapping(ctx context.Context, user User, dbHandle sqlQuerier) error {
func generateVirtualFoldersMapping(ctx context.Context, user *User, dbHandle sqlQuerier) error {
err := sqlCommonClearFolderMapping(ctx, user, dbHandle)
if err != nil {
return err
@ -813,7 +813,7 @@ func sqlCommonExecSQLAndUpdateDBVersion(dbHandle *sql.DB, sql []string, newVersi
return err
}
for _, q := range sql {
if len(strings.TrimSpace(q)) == 0 {
if strings.TrimSpace(q) == "" {
continue
}
_, err = tx.ExecContext(ctx, q)
@ -892,7 +892,7 @@ func sqlCommonRestoreCompatVirtualFolders(ctx context.Context, users []userCompa
QuotaSize: quotaSize,
QuotaFiles: quotaFiles,
}
err = sqlCommonAddFolderMapping(ctx, u, f, dbHandle)
err = sqlCommonAddFolderMapping(ctx, &u, f, dbHandle)
if err != nil {
providerLog(logger.LevelWarn, "error adding virtual folder mapping for user %#v: %v", user.Username, err)
return foldersToScan, err
@ -923,7 +923,7 @@ func sqlCommonUpdateDatabaseFrom3To4(sqlV4 string, dbHandle *sql.DB) error {
return err
}
for _, q := range strings.Split(sql, ";") {
if len(strings.TrimSpace(q)) == 0 {
if strings.TrimSpace(q) == "" {
continue
}
_, err = tx.ExecContext(ctx, q)

View file

@ -93,7 +93,7 @@ func initializeSQLiteProvider(basePath string) error {
var err error
var connectionString string
logSender = fmt.Sprintf("dataprovider_%v", SQLiteDataProviderName)
if len(config.ConnectionString) == 0 {
if config.ConnectionString == "" {
dbPath := config.Name
if !utils.IsFileInputValid(dbPath) {
return fmt.Errorf("Invalid database path: %#v", dbPath)
@ -149,15 +149,15 @@ func (p SQLiteProvider) userExists(username string) (User, error) {
return sqlCommonCheckUserExists(username, p.dbHandle)
}
func (p SQLiteProvider) addUser(user User) error {
func (p SQLiteProvider) addUser(user *User) error {
return sqlCommonAddUser(user, p.dbHandle)
}
func (p SQLiteProvider) updateUser(user User) error {
func (p SQLiteProvider) updateUser(user *User) error {
return sqlCommonUpdateUser(user, p.dbHandle)
}
func (p SQLiteProvider) deleteUser(user User) error {
func (p SQLiteProvider) deleteUser(user *User) error {
return sqlCommonDeleteUser(user, p.dbHandle)
}
@ -183,11 +183,11 @@ func (p SQLiteProvider) getFolderByPath(mappedPath string) (vfs.BaseVirtualFolde
return sqlCommonCheckFolderExists(ctx, mappedPath, p.dbHandle)
}
func (p SQLiteProvider) addFolder(folder vfs.BaseVirtualFolder) error {
func (p SQLiteProvider) addFolder(folder *vfs.BaseVirtualFolder) error {
return sqlCommonAddFolder(folder, p.dbHandle)
}
func (p SQLiteProvider) deleteFolder(folder vfs.BaseVirtualFolder) error {
func (p SQLiteProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error {
return sqlCommonDeleteFolder(folder, p.dbHandle)
}

View file

@ -63,7 +63,7 @@ func addFolder(w http.ResponseWriter, r *http.Request) {
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
return
}
err = dataprovider.AddFolder(folder)
err = dataprovider.AddFolder(&folder)
if err == nil {
folder, err = dataprovider.GetFolderByPath(folder.MappedPath)
if err == nil {
@ -81,7 +81,7 @@ func deleteFolderByPath(w http.ResponseWriter, r *http.Request) {
if _, ok := r.URL.Query()["folder_path"]; ok {
folderPath = r.URL.Query().Get("folder_path")
}
if len(folderPath) == 0 {
if folderPath == "" {
err := errors.New("a non-empty folder path is required")
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
return
@ -92,7 +92,7 @@ func deleteFolderByPath(w http.ResponseWriter, r *http.Request) {
sendAPIResponse(w, r, err, "", getRespStatus(err))
return
}
err = dataprovider.DeleteFolder(folder)
err = dataprovider.DeleteFolder(&folder)
if err != nil {
sendAPIResponse(w, r, err, "", http.StatusInternalServerError)
} else {

View file

@ -25,7 +25,7 @@ func dumpData(w http.ResponseWriter, r *http.Request) {
if _, ok := r.URL.Query()["indent"]; ok {
indent = strings.TrimSpace(r.URL.Query().Get("indent"))
}
if len(outputFile) == 0 {
if outputFile == "" {
sendAPIResponse(w, r, errors.New("Invalid or missing output_file"), "", http.StatusBadRequest)
return
}
@ -147,8 +147,9 @@ func RestoreFolders(folders []vfs.BaseVirtualFolder, inputFile string, scanQuota
logger.Debug(logSender, "", "folder %#v already exists, restore not needed", folder.MappedPath)
continue
}
folder := folder // pin
folder.Users = nil
err = dataprovider.AddFolder(folder)
err = dataprovider.AddFolder(&folder)
logger.Debug(logSender, "", "adding new folder: %+v, dump file: %#v, error: %v", folder, inputFile, err)
if err != nil {
return err
@ -166,6 +167,7 @@ func RestoreFolders(folders []vfs.BaseVirtualFolder, inputFile string, scanQuota
// RestoreUsers restores the specified users
func RestoreUsers(users []dataprovider.User, inputFile string, mode, scanQuota int) error {
for _, user := range users {
user := user // pin
u, err := dataprovider.UserExists(user.Username)
if err == nil {
if mode == 1 {
@ -173,14 +175,14 @@ func RestoreUsers(users []dataprovider.User, inputFile string, mode, scanQuota i
continue
}
user.ID = u.ID
err = dataprovider.UpdateUser(user)
err = dataprovider.UpdateUser(&user)
user.Password = "[redacted]"
logger.Debug(logSender, "", "restoring existing user: %+v, dump file: %#v, error: %v", user, inputFile, err)
if mode == 2 && err == nil {
disconnectUser(user.Username)
}
} else {
err = dataprovider.AddUser(user)
err = dataprovider.AddUser(&user)
user.Password = "[redacted]"
logger.Debug(logSender, "", "adding new user: %+v, dump file: %#v, error: %v", user, inputFile, err)
}

View file

@ -115,7 +115,7 @@ func addUser(w http.ResponseWriter, r *http.Request) {
return
}
}
err = dataprovider.AddUser(user)
err = dataprovider.AddUser(&user)
if err == nil {
user, err = dataprovider.UserExists(user.Username)
if err == nil {
@ -181,7 +181,7 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
sendAPIResponse(w, r, err, "user ID in request body does not match user ID in path parameter", http.StatusBadRequest)
return
}
err = dataprovider.UpdateUser(user)
err = dataprovider.UpdateUser(&user)
if err != nil {
sendAPIResponse(w, r, err, "", getRespStatus(err))
} else {
@ -204,7 +204,7 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
sendAPIResponse(w, r, err, "", getRespStatus(err))
return
}
err = dataprovider.DeleteUser(user)
err = dataprovider.DeleteUser(&user)
if err != nil {
sendAPIResponse(w, r, err, "", http.StatusInternalServerError)
} else {

View file

@ -129,10 +129,10 @@ func (c Conf) Initialize(configDir string) error {
staticFilesPath := getConfigPath(c.StaticFilesPath, configDir)
templatesPath := getConfigPath(c.TemplatesPath, configDir)
enableWebAdmin := len(staticFilesPath) > 0 || len(templatesPath) > 0
if len(backupsPath) == 0 {
if backupsPath == "" {
return fmt.Errorf("Required directory is invalid, backup path %#v", backupsPath)
}
if enableWebAdmin && (len(staticFilesPath) == 0 || len(templatesPath) == 0) {
if enableWebAdmin && (staticFilesPath == "" || templatesPath == "") {
return fmt.Errorf("Required directory is invalid, static file path: %#v template path: %#v",
staticFilesPath, templatesPath)
}

View file

@ -3430,7 +3430,7 @@ func TestRenderWebCloneUserMock(t *testing.T) {
assert.NoError(t, err)
user.FsConfig.CryptConfig.Passphrase.SetStatus(kms.SecretStatusAWS)
user.Password = defaultPassword
err = dataprovider.UpdateUser(user)
err = dataprovider.UpdateUser(&user)
assert.NoError(t, err)
req, err = http.NewRequest(http.MethodGet, webUserPath+fmt.Sprintf("?cloneFromId=%v", user.ID), nil)

View file

@ -727,7 +727,7 @@ func handleWebAddUserPost(w http.ResponseWriter, r *http.Request) {
renderAddUserPage(w, user, err.Error())
return
}
err = dataprovider.AddUser(user)
err = dataprovider.AddUser(&user)
if err == nil {
http.Redirect(w, r, webUsersPath, http.StatusSeeOther)
} else {
@ -764,7 +764,7 @@ func handleWebUpdateUserPost(w http.ResponseWriter, r *http.Request) {
user.FsConfig.GCSConfig.Credentials, user.FsConfig.CryptConfig.Passphrase, user.FsConfig.SFTPConfig.Password,
user.FsConfig.SFTPConfig.PrivateKey)
err = dataprovider.UpdateUser(updatedUser)
err = dataprovider.UpdateUser(&updatedUser)
if err == nil {
if len(r.Form.Get("disconnect")) > 0 {
disconnectUser(user.Username)
@ -806,7 +806,7 @@ func handleWebAddFolderPost(w http.ResponseWriter, r *http.Request) {
}
folder.MappedPath = r.Form.Get("mapped_path")
err = dataprovider.AddFolder(folder)
err = dataprovider.AddFolder(&folder)
if err == nil {
http.Redirect(w, r, webFoldersPath, http.StatusSeeOther)
} else {

View file

@ -1,6 +1,5 @@
// Fully featured and highly configurable SFTP server with optional
// FTP/S and WebDAV support. It can serve local filesystem, S3 or
// Google Cloud Storage.
// FTP/S and WebDAV support.
// For more details about features, installation, configuration and usage
// please refer to the README inside the source tree:
// https://github.com/drakkan/sftpgo/blob/master/README.md

View file

@ -1,6 +1,6 @@
#!/bin/bash
NFPM_VERSION=2.2.1
NFPM_VERSION=2.2.2
NFPM_ARCH=${NFPM_ARCH:-amd64}
if [ -z ${SFTPGO_VERSION} ]
then

View file

@ -106,7 +106,7 @@ func (s *Service) Start() error {
if s.PortableMode == 1 {
// create the user for portable mode
err = dataprovider.AddUser(s.PortableUser)
err = dataprovider.AddUser(&s.PortableUser)
if err != nil {
logger.ErrorToConsole("error adding portable user: %v", err)
return err

View file

@ -245,7 +245,7 @@ func (s *Service) configurePortableUser() string {
if len(s.PortableUser.Password) > 0 {
printablePassword = "[redacted]"
}
if len(s.PortableUser.PublicKeys) == 0 && len(s.PortableUser.Password) == 0 {
if len(s.PortableUser.PublicKeys) == 0 && s.PortableUser.Password == "" {
var b strings.Builder
for i := 0; i < 8; i++ {
b.WriteRune(chars[rand.Intn(len(chars))])

View file

@ -668,7 +668,7 @@ func (c *scpCommand) parseUploadMessage(command string) (int64, string, error) {
return size, name, err
}
name = parts[2]
if len(name) == 0 {
if name == "" {
err = fmt.Errorf("error getting name from upload message, cannot be empty")
c.connection.Log(logger.LevelWarn, "error: %v", err)
c.sendErrorMessage(err)

View file

@ -323,7 +323,7 @@ func (c *Configuration) configureLoginBanner(serverConfig *ssh.ServerConfig, con
}
func (c *Configuration) configureKeyboardInteractiveAuth(serverConfig *ssh.ServerConfig) {
if len(c.KeyboardInteractiveHook) == 0 {
if c.KeyboardInteractiveHook == "" {
return
}
if !strings.HasPrefix(c.KeyboardInteractiveHook, "http") {

View file

@ -537,7 +537,7 @@ func (c *sshCommand) getCopyPaths() (string, string, error) {
if strings.HasSuffix(sshDestPath, "/") {
sshDestPath = path.Join(sshDestPath, path.Base(sshSourcePath))
}
if len(sshSourcePath) == 0 || len(sshDestPath) == 0 || len(c.args) != 2 {
if sshSourcePath == "" || sshDestPath == "" || len(c.args) != 2 {
err := errors.New("usage sftpgo-copy <source dir path> <destination dir path>")
return "", "", err
}
@ -606,7 +606,7 @@ func (c *sshCommand) checkCopyPermissions(fsSourcePath, fsDestPath, sshSourcePat
func (c *sshCommand) getRemovePath() (string, error) {
sshDestPath := c.getDestPath()
if len(sshDestPath) == 0 || len(c.args) != 1 {
if sshDestPath == "" || len(c.args) != 1 {
err := errors.New("usage sftpgo-remove <destination path>")
return "", err
}

View file

@ -896,7 +896,7 @@ func TestBasicUsersCache(t *testing.T) {
}
u.Permissions = make(map[string][]string)
u.Permissions["/"] = []string{dataprovider.PermAny}
err := dataprovider.AddUser(u)
err := dataprovider.AddUser(&u)
assert.NoError(t, err)
user, err := dataprovider.UserExists(u.Username)
assert.NoError(t, err)
@ -969,7 +969,7 @@ func TestBasicUsersCache(t *testing.T) {
assert.False(t, cachedUser.IsExpired())
}
// cache is invalidated after a user modification
err = dataprovider.UpdateUser(user)
err = dataprovider.UpdateUser(&user)
assert.NoError(t, err)
_, ok = dataprovider.GetCachedWebDAVUser(username)
assert.False(t, ok)
@ -980,7 +980,7 @@ func TestBasicUsersCache(t *testing.T) {
_, ok = dataprovider.GetCachedWebDAVUser(username)
assert.True(t, ok)
// cache is invalidated after user deletion
err = dataprovider.DeleteUser(user)
err = dataprovider.DeleteUser(&user)
assert.NoError(t, err)
_, ok = dataprovider.GetCachedWebDAVUser(username)
assert.False(t, ok)
@ -1001,25 +1001,25 @@ func TestUsersCacheSizeAndExpiration(t *testing.T) {
u.Password = password + "1"
u.Permissions = make(map[string][]string)
u.Permissions["/"] = []string{dataprovider.PermAny}
err := dataprovider.AddUser(u)
err := dataprovider.AddUser(&u)
assert.NoError(t, err)
user1, err := dataprovider.UserExists(u.Username)
assert.NoError(t, err)
u.Username = username + "2"
u.Password = password + "2"
err = dataprovider.AddUser(u)
err = dataprovider.AddUser(&u)
assert.NoError(t, err)
user2, err := dataprovider.UserExists(u.Username)
assert.NoError(t, err)
u.Username = username + "3"
u.Password = password + "3"
err = dataprovider.AddUser(u)
err = dataprovider.AddUser(&u)
assert.NoError(t, err)
user3, err := dataprovider.UserExists(u.Username)
assert.NoError(t, err)
u.Username = username + "4"
u.Password = password + "4"
err = dataprovider.AddUser(u)
err = dataprovider.AddUser(&u)
assert.NoError(t, err)
user4, err := dataprovider.UserExists(u.Username)
assert.NoError(t, err)
@ -1137,7 +1137,7 @@ func TestUsersCacheSizeAndExpiration(t *testing.T) {
assert.True(t, ok)
// now remove user1 after an update
err = dataprovider.UpdateUser(user1)
err = dataprovider.UpdateUser(&user1)
assert.NoError(t, err)
_, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
assert.False(t, ok)
@ -1164,13 +1164,13 @@ func TestUsersCacheSizeAndExpiration(t *testing.T) {
_, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
assert.True(t, ok)
err = dataprovider.DeleteUser(user1)
err = dataprovider.DeleteUser(&user1)
assert.NoError(t, err)
err = dataprovider.DeleteUser(user2)
err = dataprovider.DeleteUser(&user2)
assert.NoError(t, err)
err = dataprovider.DeleteUser(user3)
err = dataprovider.DeleteUser(&user3)
assert.NoError(t, err)
err = dataprovider.DeleteUser(user4)
err = dataprovider.DeleteUser(&user4)
assert.NoError(t, err)
err = os.RemoveAll(u.GetHomeDir())

View file

@ -207,7 +207,7 @@ func (s *webDavServer) authenticate(r *http.Request, ip string) (dataprovider.Us
if cachedUser.IsExpired() {
dataprovider.RemoveCachedWebDAVUser(username)
} else {
if len(password) > 0 && cachedUser.Password == password {
if password != "" && cachedUser.Password == password {
return cachedUser.User, true, cachedUser.LockSystem, nil
}
updateLoginMetrics(username, ip, dataprovider.ErrInvalidCredentials)