simplify data provider usage
remove the obsolete SQL scripts too. They are not required since v0.9.6
This commit is contained in:
parent
42877dd915
commit
0ea2ca3141
33 changed files with 151 additions and 412 deletions
|
@ -106,13 +106,7 @@ Take a look at the CLI usage to learn how to specify a different configuration f
|
|||
sftpgo initprovider --help
|
||||
```
|
||||
|
||||
The `initprovider` command is enough for new installations. From now on, the database structure will be automatically checked and updated, if required, at startup.
|
||||
|
||||
#### Upgrading
|
||||
|
||||
If you are upgrading from version 0.9.5 or before, you have to manually execute the SQL scripts to create the required database structure. These scripts can be found inside the source tree [sql](./sql "sql") directory. The SQL scripts filename is, by convention, the date as `YYYYMMDD` and the suffix `.sql`. You need to apply all the SQL scripts for your database ordered by name. For example, `20190828.sql` must be applied before `20191112.sql`, and so on.
|
||||
Example for SQLite: `find sql/sqlite/ -type f -iname '*.sql' -print | sort -n | xargs cat | sqlite3 sftpgo.db`.
|
||||
After applying these scripts, your database structure is the same as the one obtained using `initprovider` for new installations, so from now on, you don't have to manually upgrade your database anymore.
|
||||
After the initialization, the database structure will be automatically checked and updated, if required, at startup.
|
||||
|
||||
## Authentication options
|
||||
|
||||
|
|
|
@ -327,11 +327,6 @@ func (e *RecordNotFoundError) Error() string {
|
|||
return fmt.Sprintf("Not found: %s", e.err)
|
||||
}
|
||||
|
||||
// GetProvider returns the configured provider
|
||||
func GetProvider() Provider {
|
||||
return provider
|
||||
}
|
||||
|
||||
// GetQuotaTracking returns the configured mode for user's quota tracking
|
||||
func GetQuotaTracking() int {
|
||||
return config.TrackQuota
|
||||
|
@ -450,7 +445,7 @@ func InitializeDatabase(cnf Config, basePath string) error {
|
|||
}
|
||||
|
||||
// CheckUserAndPass retrieves the SFTP user with the given username and password if a match is found or an error
|
||||
func CheckUserAndPass(p Provider, username string, password string) (User, error) {
|
||||
func CheckUserAndPass(username string, password string) (User, error) {
|
||||
if len(config.ExternalAuthHook) > 0 && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&1 != 0) {
|
||||
user, err := doExternalAuth(username, password, nil, "")
|
||||
if err != nil {
|
||||
|
@ -465,11 +460,11 @@ func CheckUserAndPass(p Provider, username string, password string) (User, error
|
|||
}
|
||||
return checkUserAndPass(user, password)
|
||||
}
|
||||
return p.validateUserAndPass(username, password)
|
||||
return provider.validateUserAndPass(username, password)
|
||||
}
|
||||
|
||||
// CheckUserAndPubKey retrieves the SFTP user with the given username and public key if a match is found or an error
|
||||
func CheckUserAndPubKey(p Provider, username string, pubKey []byte) (User, string, error) {
|
||||
func CheckUserAndPubKey(username string, pubKey []byte) (User, string, error) {
|
||||
if len(config.ExternalAuthHook) > 0 && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&2 != 0) {
|
||||
user, err := doExternalAuth(username, "", pubKey, "")
|
||||
if err != nil {
|
||||
|
@ -484,12 +479,12 @@ func CheckUserAndPubKey(p Provider, username string, pubKey []byte) (User, strin
|
|||
}
|
||||
return checkUserAndPubKey(user, pubKey)
|
||||
}
|
||||
return p.validateUserAndPubKey(username, pubKey)
|
||||
return provider.validateUserAndPubKey(username, pubKey)
|
||||
}
|
||||
|
||||
// CheckKeyboardInteractiveAuth checks the keyboard interactive authentication and returns
|
||||
// the authenticated user or an error
|
||||
func CheckKeyboardInteractiveAuth(p Provider, username, authHook string, client ssh.KeyboardInteractiveChallenge) (User, error) {
|
||||
func CheckKeyboardInteractiveAuth(username, authHook string, client ssh.KeyboardInteractiveChallenge) (User, error) {
|
||||
var user User
|
||||
var err error
|
||||
if len(config.ExternalAuthHook) > 0 && (config.ExternalAuthScope == 0 || config.ExternalAuthScope&4 != 0) {
|
||||
|
@ -497,7 +492,7 @@ func CheckKeyboardInteractiveAuth(p Provider, username, authHook string, client
|
|||
} else if len(config.PreLoginHook) > 0 {
|
||||
user, err = executePreLoginHook(username, SSHLoginMethodKeyboardInteractive)
|
||||
} else {
|
||||
user, err = p.userExists(username)
|
||||
user, err = provider.userExists(username)
|
||||
}
|
||||
if err != nil {
|
||||
return user, err
|
||||
|
@ -506,16 +501,16 @@ func CheckKeyboardInteractiveAuth(p Provider, username, authHook string, client
|
|||
}
|
||||
|
||||
// UpdateLastLogin updates the last login fields for the given SFTP user
|
||||
func UpdateLastLogin(p Provider, user User) error {
|
||||
func UpdateLastLogin(user User) error {
|
||||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
return p.updateLastLogin(user.Username)
|
||||
return provider.updateLastLogin(user.Username)
|
||||
}
|
||||
|
||||
// UpdateUserQuota updates the quota for the given SFTP user adding filesAdd and sizeAdd.
|
||||
// If reset is true filesAdd and sizeAdd indicates the total files and the total size instead of the difference.
|
||||
func UpdateUserQuota(p Provider, user User, filesAdd int, sizeAdd int64, reset bool) error {
|
||||
func UpdateUserQuota(user User, filesAdd int, sizeAdd int64, reset bool) error {
|
||||
if config.TrackQuota == 0 {
|
||||
return &MethodDisabledError{err: trackQuotaDisabledError}
|
||||
} else if config.TrackQuota == 2 && !reset && !user.HasQuotaRestrictions() {
|
||||
|
@ -524,49 +519,49 @@ func UpdateUserQuota(p Provider, user User, filesAdd int, sizeAdd int64, reset b
|
|||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
return p.updateQuota(user.Username, filesAdd, sizeAdd, reset)
|
||||
return provider.updateQuota(user.Username, filesAdd, sizeAdd, reset)
|
||||
}
|
||||
|
||||
// UpdateVirtualFolderQuota updates the quota for the given virtual folder adding filesAdd and sizeAdd.
|
||||
// If reset is true filesAdd and sizeAdd indicates the total files and the total size instead of the difference.
|
||||
func UpdateVirtualFolderQuota(p Provider, vfolder vfs.BaseVirtualFolder, filesAdd int, sizeAdd int64, reset bool) error {
|
||||
func UpdateVirtualFolderQuota(vfolder vfs.BaseVirtualFolder, filesAdd int, sizeAdd int64, reset bool) error {
|
||||
if config.TrackQuota == 0 {
|
||||
return &MethodDisabledError{err: trackQuotaDisabledError}
|
||||
}
|
||||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
return p.updateFolderQuota(vfolder.MappedPath, filesAdd, sizeAdd, reset)
|
||||
return provider.updateFolderQuota(vfolder.MappedPath, filesAdd, sizeAdd, reset)
|
||||
}
|
||||
|
||||
// GetUsedQuota returns the used quota for the given SFTP user.
|
||||
func GetUsedQuota(p Provider, username string) (int, int64, error) {
|
||||
func GetUsedQuota(username string) (int, int64, error) {
|
||||
if config.TrackQuota == 0 {
|
||||
return 0, 0, &MethodDisabledError{err: trackQuotaDisabledError}
|
||||
}
|
||||
return p.getUsedQuota(username)
|
||||
return provider.getUsedQuota(username)
|
||||
}
|
||||
|
||||
// GetUsedVirtualFolderQuota returns the used quota for the given virtual folder.
|
||||
func GetUsedVirtualFolderQuota(p Provider, mappedPath string) (int, int64, error) {
|
||||
func GetUsedVirtualFolderQuota(mappedPath string) (int, int64, error) {
|
||||
if config.TrackQuota == 0 {
|
||||
return 0, 0, &MethodDisabledError{err: trackQuotaDisabledError}
|
||||
}
|
||||
return p.getUsedFolderQuota(mappedPath)
|
||||
return provider.getUsedFolderQuota(mappedPath)
|
||||
}
|
||||
|
||||
// UserExists checks if the given SFTP username exists, returns an error if no match is found
|
||||
func UserExists(p Provider, username string) (User, error) {
|
||||
return p.userExists(username)
|
||||
func UserExists(username string) (User, error) {
|
||||
return provider.userExists(username)
|
||||
}
|
||||
|
||||
// AddUser adds a new SFTP user.
|
||||
// ManageUsers configuration must be set to 1 to enable this method
|
||||
func AddUser(p Provider, user User) error {
|
||||
func AddUser(user User) error {
|
||||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
err := p.addUser(user)
|
||||
err := provider.addUser(user)
|
||||
if err == nil {
|
||||
go executeAction(operationAdd, user)
|
||||
}
|
||||
|
@ -575,11 +570,11 @@ func AddUser(p Provider, user User) error {
|
|||
|
||||
// UpdateUser updates an existing SFTP user.
|
||||
// ManageUsers configuration must be set to 1 to enable this method
|
||||
func UpdateUser(p Provider, user User) error {
|
||||
func UpdateUser(user User) error {
|
||||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
err := p.updateUser(user)
|
||||
err := provider.updateUser(user)
|
||||
if err == nil {
|
||||
go executeAction(operationUpdate, user)
|
||||
}
|
||||
|
@ -588,11 +583,11 @@ func UpdateUser(p Provider, user User) error {
|
|||
|
||||
// DeleteUser deletes an existing SFTP user.
|
||||
// ManageUsers configuration must be set to 1 to enable this method
|
||||
func DeleteUser(p Provider, user User) error {
|
||||
func DeleteUser(user User) error {
|
||||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
err := p.deleteUser(user)
|
||||
err := provider.deleteUser(user)
|
||||
if err == nil {
|
||||
go executeAction(operationDelete, user)
|
||||
}
|
||||
|
@ -607,51 +602,51 @@ func ReloadConfig() error {
|
|||
}
|
||||
|
||||
// GetUsers returns an array of users respecting limit and offset and filtered by username exact match if not empty
|
||||
func GetUsers(p Provider, limit, offset int, order string, username string) ([]User, error) {
|
||||
return p.getUsers(limit, offset, order, username)
|
||||
func GetUsers(limit, offset int, order string, username string) ([]User, error) {
|
||||
return provider.getUsers(limit, offset, order, username)
|
||||
}
|
||||
|
||||
// GetUserByID returns the user with the given database ID if a match is found or an error
|
||||
func GetUserByID(p Provider, ID int64) (User, error) {
|
||||
return p.getUserByID(ID)
|
||||
func GetUserByID(ID int64) (User, error) {
|
||||
return provider.getUserByID(ID)
|
||||
}
|
||||
|
||||
// AddFolder adds a new virtual folder.
|
||||
// ManageUsers configuration must be set to 1 to enable this method
|
||||
func AddFolder(p Provider, folder vfs.BaseVirtualFolder) error {
|
||||
func AddFolder(folder vfs.BaseVirtualFolder) error {
|
||||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
return p.addFolder(folder)
|
||||
return provider.addFolder(folder)
|
||||
}
|
||||
|
||||
// DeleteFolder deletes an existing folder.
|
||||
// ManageUsers configuration must be set to 1 to enable this method
|
||||
func DeleteFolder(p Provider, folder vfs.BaseVirtualFolder) error {
|
||||
func DeleteFolder(folder vfs.BaseVirtualFolder) error {
|
||||
if config.ManageUsers == 0 {
|
||||
return &MethodDisabledError{err: manageUsersDisabledError}
|
||||
}
|
||||
return p.deleteFolder(folder)
|
||||
return provider.deleteFolder(folder)
|
||||
}
|
||||
|
||||
// GetFolderByPath returns the folder with the specified path if any
|
||||
func GetFolderByPath(p Provider, mappedPath string) (vfs.BaseVirtualFolder, error) {
|
||||
return p.getFolderByPath(mappedPath)
|
||||
func GetFolderByPath(mappedPath string) (vfs.BaseVirtualFolder, error) {
|
||||
return provider.getFolderByPath(mappedPath)
|
||||
}
|
||||
|
||||
// GetFolders returns an array of folders respecting limit and offset
|
||||
func GetFolders(p Provider, limit, offset int, order, folderPath string) ([]vfs.BaseVirtualFolder, error) {
|
||||
return p.getFolders(limit, offset, order, folderPath)
|
||||
func GetFolders(limit, offset int, order, folderPath string) ([]vfs.BaseVirtualFolder, error) {
|
||||
return provider.getFolders(limit, offset, order, folderPath)
|
||||
}
|
||||
|
||||
// DumpData returns all users and folders
|
||||
func DumpData(p Provider) (BackupData, error) {
|
||||
func DumpData() (BackupData, error) {
|
||||
var data BackupData
|
||||
users, err := p.dumpUsers()
|
||||
users, err := provider.dumpUsers()
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
folders, err := p.dumpFolders()
|
||||
folders, err := provider.dumpFolders()
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
|
@ -661,17 +656,17 @@ func DumpData(p Provider) (BackupData, error) {
|
|||
}
|
||||
|
||||
// GetProviderStatus returns an error if the provider is not available
|
||||
func GetProviderStatus(p Provider) error {
|
||||
return p.checkAvailability()
|
||||
func GetProviderStatus() error {
|
||||
return provider.checkAvailability()
|
||||
}
|
||||
|
||||
// Close releases all provider resources.
|
||||
// This method is used in test cases.
|
||||
// Closing an uninitialized provider is not supported
|
||||
func Close(p Provider) error {
|
||||
func Close() error {
|
||||
availabilityTicker.Stop()
|
||||
availabilityTickerDone <- true
|
||||
return p.close()
|
||||
return provider.close()
|
||||
}
|
||||
|
||||
func createProvider(basePath string) error {
|
||||
|
@ -1744,7 +1739,7 @@ func updateVFoldersQuotaAfterRestore(foldersToScan []string) {
|
|||
providerLog(logger.LevelWarn, "error scanning folder %#v: %v", folder, err)
|
||||
continue
|
||||
}
|
||||
err = UpdateVirtualFolderQuota(provider, vfolder, numFiles, size, true)
|
||||
err = UpdateVirtualFolderQuota(vfolder, numFiles, size, true)
|
||||
providerLog(logger.LevelDebug, "quota updated for virtual folder %#v, error: %v", vfolder.MappedPath, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ func getFolders(w http.ResponseWriter, r *http.Request) {
|
|||
if _, ok := r.URL.Query()["folder_path"]; ok {
|
||||
folderPath = r.URL.Query().Get("folder_path")
|
||||
}
|
||||
folders, err := dataprovider.GetFolders(dataProvider, limit, offset, order, folderPath)
|
||||
folders, err := dataprovider.GetFolders(limit, offset, order, folderPath)
|
||||
if err == nil {
|
||||
render.JSON(w, r, folders)
|
||||
} else {
|
||||
|
@ -63,9 +63,9 @@ func addFolder(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
err = dataprovider.AddFolder(dataProvider, folder)
|
||||
err = dataprovider.AddFolder(folder)
|
||||
if err == nil {
|
||||
folder, err = dataprovider.GetFolderByPath(dataProvider, folder.MappedPath)
|
||||
folder, err = dataprovider.GetFolderByPath(folder.MappedPath)
|
||||
if err == nil {
|
||||
render.JSON(w, r, folder)
|
||||
} else {
|
||||
|
@ -87,12 +87,12 @@ func deleteFolderByPath(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
folder, err := dataprovider.GetFolderByPath(dataProvider, folderPath)
|
||||
folder, err := dataprovider.GetFolderByPath(folderPath)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
}
|
||||
err = dataprovider.DeleteFolder(dataProvider, folder)
|
||||
err = dataprovider.DeleteFolder(folder)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusInternalServerError)
|
||||
} else {
|
||||
|
|
|
@ -46,7 +46,7 @@ func dumpData(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
logger.Debug(logSender, "", "dumping data to: %#v", outputFile)
|
||||
|
||||
backup, err := dataprovider.DumpData(dataProvider)
|
||||
backup, err := dataprovider.DumpData()
|
||||
if err != nil {
|
||||
logger.Warn(logSender, "", "dumping data error: %v, output file: %#v", err, outputFile)
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
|
@ -142,13 +142,13 @@ func getLoaddataOptions(r *http.Request) (string, int, int, error) {
|
|||
|
||||
func restoreFolders(folders []vfs.BaseVirtualFolder, inputFile string, scanQuota int) error {
|
||||
for _, folder := range folders {
|
||||
_, err := dataprovider.GetFolderByPath(dataProvider, folder.MappedPath)
|
||||
_, err := dataprovider.GetFolderByPath(folder.MappedPath)
|
||||
if err == nil {
|
||||
logger.Debug(logSender, "", "folder %#v already exists, restore not needed", folder.MappedPath)
|
||||
continue
|
||||
}
|
||||
folder.Users = nil
|
||||
err = dataprovider.AddFolder(dataProvider, 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
|
||||
|
@ -165,18 +165,18 @@ func restoreFolders(folders []vfs.BaseVirtualFolder, inputFile string, scanQuota
|
|||
|
||||
func restoreUsers(users []dataprovider.User, inputFile string, mode, scanQuota int) error {
|
||||
for _, user := range users {
|
||||
u, err := dataprovider.UserExists(dataProvider, user.Username)
|
||||
u, err := dataprovider.UserExists(user.Username)
|
||||
if err == nil {
|
||||
if mode == 1 {
|
||||
logger.Debug(logSender, "", "loaddata mode 1, existing user %#v not updated", u.Username)
|
||||
continue
|
||||
}
|
||||
user.ID = u.ID
|
||||
err = dataprovider.UpdateUser(dataProvider, user)
|
||||
err = dataprovider.UpdateUser(user)
|
||||
user.Password = "[redacted]"
|
||||
logger.Debug(logSender, "", "restoring existing user: %+v, dump file: %#v, error: %v", user, inputFile, err)
|
||||
} else {
|
||||
err = dataprovider.AddUser(dataProvider, user)
|
||||
err = dataprovider.AddUser(user)
|
||||
user.Password = "[redacted]"
|
||||
logger.Debug(logSender, "", "adding new user: %+v, dump file: %#v, error: %v", user, inputFile, err)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func updateUserQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.UserExists(dataProvider, u.Username)
|
||||
user, err := dataprovider.UserExists(u.Username)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
|
@ -58,7 +58,7 @@ func updateUserQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
defer sftpd.RemoveQuotaScan(user.Username) //nolint:errcheck
|
||||
err = dataprovider.UpdateUserQuota(dataProvider, user, u.UsedQuotaFiles, u.UsedQuotaSize, mode == quotaUpdateModeReset)
|
||||
err = dataprovider.UpdateUserQuota(user, u.UsedQuotaFiles, u.UsedQuotaSize, mode == quotaUpdateModeReset)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
} else {
|
||||
|
@ -84,7 +84,7 @@ func updateVFolderQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
folder, err := dataprovider.GetFolderByPath(dataProvider, f.MappedPath)
|
||||
folder, err := dataprovider.GetFolderByPath(f.MappedPath)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
|
@ -94,7 +94,7 @@ func updateVFolderQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
defer sftpd.RemoveVFolderQuotaScan(folder.MappedPath) //nolint:errcheck
|
||||
err = dataprovider.UpdateVirtualFolderQuota(dataProvider, folder, f.UsedQuotaFiles, f.UsedQuotaSize, mode == quotaUpdateModeReset)
|
||||
err = dataprovider.UpdateVirtualFolderQuota(folder, f.UsedQuotaFiles, f.UsedQuotaSize, mode == quotaUpdateModeReset)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
} else {
|
||||
|
@ -114,7 +114,7 @@ func startQuotaScan(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.UserExists(dataProvider, u.Username)
|
||||
user, err := dataprovider.UserExists(u.Username)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
|
@ -139,7 +139,7 @@ func startVFolderQuotaScan(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
folder, err := dataprovider.GetFolderByPath(dataProvider, f.MappedPath)
|
||||
folder, err := dataprovider.GetFolderByPath(f.MappedPath)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
|
@ -164,7 +164,7 @@ func doQuotaScan(user dataprovider.User) error {
|
|||
logger.Warn(logSender, "", "error scanning user home dir %#v: %v", user.Username, err)
|
||||
return err
|
||||
}
|
||||
err = dataprovider.UpdateUserQuota(dataProvider, user, numFiles, size, true)
|
||||
err = dataprovider.UpdateUserQuota(user, numFiles, size, true)
|
||||
logger.Debug(logSender, "", "user home dir scanned, user: %#v, error: %v", user.Username, err)
|
||||
return err
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ func doFolderQuotaScan(folder vfs.BaseVirtualFolder) error {
|
|||
logger.Warn(logSender, "", "error scanning folder %#v: %v", folder.MappedPath, err)
|
||||
return err
|
||||
}
|
||||
err = dataprovider.UpdateVirtualFolderQuota(dataProvider, folder, numFiles, size, true)
|
||||
err = dataprovider.UpdateVirtualFolderQuota(folder, numFiles, size, true)
|
||||
logger.Debug(logSender, "", "virtual folder %#v scanned, error: %v", folder.MappedPath, err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ func getUsers(w http.ResponseWriter, r *http.Request) {
|
|||
if _, ok := r.URL.Query()["username"]; ok {
|
||||
username = r.URL.Query().Get("username")
|
||||
}
|
||||
users, err := dataprovider.GetUsers(dataProvider, limit, offset, order, username)
|
||||
users, err := dataprovider.GetUsers(limit, offset, order, username)
|
||||
if err == nil {
|
||||
render.JSON(w, r, users)
|
||||
} else {
|
||||
|
@ -63,7 +63,7 @@ func getUserByID(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.GetUserByID(dataProvider, userID)
|
||||
user, err := dataprovider.GetUserByID(userID)
|
||||
if err == nil {
|
||||
render.JSON(w, r, dataprovider.HideUserSensitiveData(&user))
|
||||
} else {
|
||||
|
@ -79,9 +79,9 @@ func addUser(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
err = dataprovider.AddUser(dataProvider, user)
|
||||
err = dataprovider.AddUser(user)
|
||||
if err == nil {
|
||||
user, err = dataprovider.UserExists(dataProvider, user.Username)
|
||||
user, err = dataprovider.UserExists(user.Username)
|
||||
if err == nil {
|
||||
render.JSON(w, r, dataprovider.HideUserSensitiveData(&user))
|
||||
} else {
|
||||
|
@ -100,7 +100,7 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.GetUserByID(dataProvider, userID)
|
||||
user, err := dataprovider.GetUserByID(userID)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
|
@ -137,7 +137,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(dataProvider, user)
|
||||
err = dataprovider.UpdateUser(user)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
} else {
|
||||
|
@ -152,12 +152,12 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.GetUserByID(dataProvider, userID)
|
||||
user, err := dataprovider.GetUserByID(userID)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
}
|
||||
err = dataprovider.DeleteUser(dataProvider, user)
|
||||
err = dataprovider.DeleteUser(user)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusInternalServerError)
|
||||
} else {
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
|
||||
"github.com/go-chi/chi"
|
||||
|
||||
"github.com/drakkan/sftpgo/dataprovider"
|
||||
"github.com/drakkan/sftpgo/logger"
|
||||
"github.com/drakkan/sftpgo/utils"
|
||||
)
|
||||
|
@ -49,7 +48,6 @@ const (
|
|||
|
||||
var (
|
||||
router *chi.Mux
|
||||
dataProvider dataprovider.Provider
|
||||
backupsPath string
|
||||
httpAuth httpAuthProvider
|
||||
certMgr *certManager
|
||||
|
@ -88,11 +86,6 @@ type apiResponse struct {
|
|||
HTTPStatus int `json:"status"`
|
||||
}
|
||||
|
||||
// SetDataProvider sets the data provider to use to fetch the data about users
|
||||
func SetDataProvider(provider dataprovider.Provider) {
|
||||
dataProvider = provider
|
||||
}
|
||||
|
||||
// Initialize configures and starts the HTTP server
|
||||
func (c Conf) Initialize(configDir string, enableProfiler bool) error {
|
||||
var err error
|
||||
|
|
|
@ -118,7 +118,6 @@ func TestMain(m *testing.M) {
|
|||
httpConfig := config.GetHTTPConfig()
|
||||
httpConfig.Initialize(configDir)
|
||||
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
httpdConf := config.GetHTTPDConfig()
|
||||
|
||||
httpdConf.BindPort = 8081
|
||||
|
@ -131,9 +130,6 @@ func TestMain(m *testing.M) {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
sftpd.SetDataProvider(dataProvider)
|
||||
httpd.SetDataProvider(dataProvider)
|
||||
|
||||
go func() {
|
||||
if err := httpdConf.Initialize(configDir, true); err != nil {
|
||||
logger.ErrorToConsole("could not start HTTP server: %v", err)
|
||||
|
@ -1177,8 +1173,7 @@ func TestCloseActiveConnection(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUserBaseDir(t *testing.T) {
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1186,7 +1181,6 @@ func TestUserBaseDir(t *testing.T) {
|
|||
providerConf.UsersBaseDir = homeBasePath
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
u := getTestUser()
|
||||
u.HomeDir = ""
|
||||
user, _, err := httpd.AddUser(u, http.StatusOK)
|
||||
|
@ -1196,8 +1190,7 @@ func TestUserBaseDir(t *testing.T) {
|
|||
assert.Equal(t, filepath.Join(providerConf.UsersBaseDir, u.Username), user.HomeDir)
|
||||
_, err = httpd.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1207,13 +1200,10 @@ func TestUserBaseDir(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
}
|
||||
|
||||
func TestQuotaTrackingDisabled(t *testing.T) {
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1221,7 +1211,6 @@ func TestQuotaTrackingDisabled(t *testing.T) {
|
|||
providerConf.TrackQuota = 0
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
// user quota scan must fail
|
||||
user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
@ -1244,8 +1233,7 @@ func TestQuotaTrackingDisabled(t *testing.T) {
|
|||
_, err = httpd.RemoveFolder(folder, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1255,13 +1243,10 @@ func TestQuotaTrackingDisabled(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
}
|
||||
|
||||
func TestProviderErrors(t *testing.T) {
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
_, _, err = httpd.GetUserByID(0, http.StatusInternalServerError)
|
||||
assert.NoError(t, err)
|
||||
|
@ -1307,8 +1292,6 @@ func TestProviderErrors(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
}
|
||||
|
||||
func TestFolders(t *testing.T) {
|
||||
|
@ -1372,16 +1355,13 @@ func TestFolders(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDumpdata(t *testing.T) {
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf := config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
_, _, err = httpd.Dumpdata("", "", http.StatusBadRequest)
|
||||
assert.NoError(t, err)
|
||||
_, _, err = httpd.Dumpdata(filepath.Join(backupsPath, "backup.json"), "", http.StatusBadRequest)
|
||||
|
@ -1405,8 +1385,7 @@ func TestDumpdata(t *testing.T) {
|
|||
err = os.Chmod(backupsPath, 0755)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1416,8 +1395,6 @@ func TestDumpdata(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
}
|
||||
|
||||
func TestLoaddata(t *testing.T) {
|
||||
|
@ -2747,8 +2724,7 @@ func TestWebFoldersMock(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestProviderClosedMock(t *testing.T) {
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
dataprovider.Close(dataProvider)
|
||||
dataprovider.Close()
|
||||
req, _ := http.NewRequest(http.MethodGet, webFoldersPath, nil)
|
||||
rr := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusInternalServerError, rr.Code)
|
||||
|
@ -2771,8 +2747,6 @@ func TestProviderClosedMock(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
}
|
||||
|
||||
func TestGetWebConnectionsMock(t *testing.T) {
|
||||
|
|
|
@ -59,7 +59,7 @@ func initializeRouter(staticFilesPath string, enableProfiler, enableWebAdmin boo
|
|||
})
|
||||
|
||||
router.Get(providerStatusPath, func(w http.ResponseWriter, r *http.Request) {
|
||||
err := dataprovider.GetProviderStatus(dataProvider)
|
||||
err := dataprovider.GetProviderStatus()
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusInternalServerError)
|
||||
} else {
|
||||
|
|
14
httpd/web.go
14
httpd/web.go
|
@ -518,7 +518,7 @@ func handleGetWebUsers(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
users := make([]dataprovider.User, 0, limit)
|
||||
for {
|
||||
u, err := dataprovider.GetUsers(dataProvider, limit, len(users), dataprovider.OrderASC, "")
|
||||
u, err := dataprovider.GetUsers(limit, len(users), dataprovider.OrderASC, "")
|
||||
if err != nil {
|
||||
renderInternalServerErrorPage(w, err)
|
||||
return
|
||||
|
@ -545,7 +545,7 @@ func handleWebUpdateUserGet(w http.ResponseWriter, r *http.Request) {
|
|||
renderBadRequestPage(w, err)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.GetUserByID(dataProvider, id)
|
||||
user, err := dataprovider.GetUserByID(id)
|
||||
if err == nil {
|
||||
renderUpdateUserPage(w, user, "")
|
||||
} else if _, ok := err.(*dataprovider.RecordNotFoundError); ok {
|
||||
|
@ -562,7 +562,7 @@ func handleWebAddUserPost(w http.ResponseWriter, r *http.Request) {
|
|||
renderAddUserPage(w, user, err.Error())
|
||||
return
|
||||
}
|
||||
err = dataprovider.AddUser(dataProvider, user)
|
||||
err = dataprovider.AddUser(user)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, webUsersPath, http.StatusSeeOther)
|
||||
} else {
|
||||
|
@ -577,7 +577,7 @@ func handleWebUpdateUserPost(w http.ResponseWriter, r *http.Request) {
|
|||
renderBadRequestPage(w, err)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.GetUserByID(dataProvider, id)
|
||||
user, err := dataprovider.GetUserByID(id)
|
||||
if _, ok := err.(*dataprovider.RecordNotFoundError); ok {
|
||||
renderNotFoundPage(w, err)
|
||||
return
|
||||
|
@ -594,7 +594,7 @@ func handleWebUpdateUserPost(w http.ResponseWriter, r *http.Request) {
|
|||
if len(updatedUser.Password) == 0 {
|
||||
updatedUser.Password = user.Password
|
||||
}
|
||||
err = dataprovider.UpdateUser(dataProvider, updatedUser)
|
||||
err = dataprovider.UpdateUser(updatedUser)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, webUsersPath, http.StatusSeeOther)
|
||||
} else {
|
||||
|
@ -625,7 +625,7 @@ func handleWebAddFolderPost(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
folder.MappedPath = r.Form.Get("mapped_path")
|
||||
|
||||
err = dataprovider.AddFolder(dataProvider, folder)
|
||||
err = dataprovider.AddFolder(folder)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, webFoldersPath, http.StatusSeeOther)
|
||||
} else {
|
||||
|
@ -644,7 +644,7 @@ func handleWebGetFolders(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
folders := make([]vfs.BaseVirtualFolder, 0, limit)
|
||||
for {
|
||||
f, err := dataprovider.GetFolders(dataProvider, limit, len(folders), dataprovider.OrderASC, "")
|
||||
f, err := dataprovider.GetFolders(limit, len(folders), dataprovider.OrderASC, "")
|
||||
if err != nil {
|
||||
renderInternalServerErrorPage(w, err)
|
||||
return
|
||||
|
|
|
@ -8,9 +8,7 @@ import (
|
|||
|
||||
"github.com/drakkan/sftpgo/config"
|
||||
"github.com/drakkan/sftpgo/dataprovider"
|
||||
"github.com/drakkan/sftpgo/httpd"
|
||||
"github.com/drakkan/sftpgo/logger"
|
||||
"github.com/drakkan/sftpgo/sftpd"
|
||||
"github.com/drakkan/sftpgo/utils"
|
||||
"github.com/drakkan/sftpgo/version"
|
||||
)
|
||||
|
@ -77,21 +75,18 @@ func (s *Service) Start() error {
|
|||
httpConfig := config.GetHTTPConfig()
|
||||
httpConfig.Initialize(s.ConfigDir)
|
||||
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
sftpdConf := config.GetSFTPDConfig()
|
||||
httpdConf := config.GetHTTPDConfig()
|
||||
|
||||
if s.PortableMode == 1 {
|
||||
// create the user for portable mode
|
||||
err = dataprovider.AddUser(dataProvider, s.PortableUser)
|
||||
err = dataprovider.AddUser(s.PortableUser)
|
||||
if err != nil {
|
||||
logger.ErrorToConsole("error adding portable user: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
sftpd.SetDataProvider(dataProvider)
|
||||
|
||||
go func() {
|
||||
logger.Debug(logSender, "", "initializing SFTP server with config %+v", sftpdConf)
|
||||
if err := sftpdConf.Initialize(s.ConfigDir); err != nil {
|
||||
|
@ -102,8 +97,6 @@ func (s *Service) Start() error {
|
|||
}()
|
||||
|
||||
if httpdConf.BindPort > 0 {
|
||||
httpd.SetDataProvider(dataProvider)
|
||||
|
||||
go func() {
|
||||
if err := httpdConf.Initialize(s.ConfigDir, s.Profiler); err != nil {
|
||||
logger.Error(logSender, "", "could not start HTTP server: %v", err)
|
||||
|
|
|
@ -489,12 +489,12 @@ func (c Connection) handleSFTPRemove(filePath string, request *sftp.Request) err
|
|||
if fi.Mode()&os.ModeSymlink != os.ModeSymlink {
|
||||
vfolder, err := c.User.GetVirtualFolderForPath(path.Dir(request.Filepath))
|
||||
if err == nil {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, vfolder.BaseVirtualFolder, -1, -size, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(vfolder.BaseVirtualFolder, -1, -size, false) //nolint:errcheck
|
||||
if vfolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, -1, -size, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, -1, -size, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, -1, -size, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, -1, -size, false) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
if actionErr != nil {
|
||||
|
@ -588,12 +588,12 @@ func (c Connection) handleSFTPUploadToExistingFile(pflags sftp.FileOpenFlags, re
|
|||
if vfs.IsLocalOsFs(c.fs) {
|
||||
vfolder, err := c.User.GetVirtualFolderForPath(path.Dir(requestPath))
|
||||
if err == nil {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, vfolder.BaseVirtualFolder, 0, -fileSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(vfolder.BaseVirtualFolder, 0, -fileSize, false) //nolint:errcheck
|
||||
if vfolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, 0, -fileSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, 0, -fileSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, 0, -fileSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, 0, -fileSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
initialSize = fileSize
|
||||
|
@ -736,14 +736,14 @@ func (c Connection) hasSpace(checkFiles bool, requestPath string) vfs.QuotaCheck
|
|||
}
|
||||
result.QuotaSize = vfolder.QuotaSize
|
||||
result.QuotaFiles = vfolder.QuotaFiles
|
||||
result.UsedFiles, result.UsedSize, err = dataprovider.GetUsedVirtualFolderQuota(dataProvider, vfolder.MappedPath)
|
||||
result.UsedFiles, result.UsedSize, err = dataprovider.GetUsedVirtualFolderQuota(vfolder.MappedPath)
|
||||
} else {
|
||||
if c.User.HasNoQuotaRestrictions(checkFiles) {
|
||||
return result
|
||||
}
|
||||
result.QuotaSize = c.User.QuotaSize
|
||||
result.QuotaFiles = c.User.QuotaFiles
|
||||
result.UsedFiles, result.UsedSize, err = dataprovider.GetUsedQuota(dataProvider, c.User.Username)
|
||||
result.UsedFiles, result.UsedSize, err = dataprovider.GetUsedQuota(c.User.Username)
|
||||
}
|
||||
if err != nil {
|
||||
c.Log(logger.LevelWarn, logSender, "error getting used quota for %#v request path %#v: %v", c.User.Username, requestPath, err)
|
||||
|
@ -882,59 +882,59 @@ func (c Connection) updateQuotaMoveBetweenVFolders(sourceFolder, dstFolder vfs.V
|
|||
if sourceFolder.MappedPath == dstFolder.MappedPath {
|
||||
// both files are inside the same virtual folder
|
||||
if initialSize != -1 {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, dstFolder.BaseVirtualFolder, -numFiles, -initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(dstFolder.BaseVirtualFolder, -numFiles, -initialSize, false) //nolint:errcheck
|
||||
if dstFolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, -numFiles, -initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, -numFiles, -initialSize, false) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
// files are inside different virtual folders
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, sourceFolder.BaseVirtualFolder, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(sourceFolder.BaseVirtualFolder, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
if sourceFolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
}
|
||||
if initialSize == -1 {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, dstFolder.BaseVirtualFolder, numFiles, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(dstFolder.BaseVirtualFolder, numFiles, filesSize, false) //nolint:errcheck
|
||||
if dstFolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, numFiles, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, numFiles, filesSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
// we cannot have a directory here, initialSize != -1 only for files
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, dstFolder.BaseVirtualFolder, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(dstFolder.BaseVirtualFolder, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
if dstFolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c Connection) updateQuotaMoveFromVFolder(sourceFolder vfs.VirtualFolder, initialSize, filesSize int64, numFiles int) {
|
||||
// move between a virtual folder and the user home dir
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, sourceFolder.BaseVirtualFolder, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(sourceFolder.BaseVirtualFolder, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
if sourceFolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
}
|
||||
if initialSize == -1 {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, numFiles, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, numFiles, filesSize, false) //nolint:errcheck
|
||||
} else {
|
||||
// we cannot have a directory here, initialSize != -1 only for files
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
||||
func (c Connection) updateQuotaMoveToVFolder(dstFolder vfs.VirtualFolder, initialSize, filesSize int64, numFiles int) {
|
||||
// move between the user home dir and a virtual folder
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, -numFiles, -filesSize, false) //nolint:errcheck
|
||||
if initialSize == -1 {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, dstFolder.BaseVirtualFolder, numFiles, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(dstFolder.BaseVirtualFolder, numFiles, filesSize, false) //nolint:errcheck
|
||||
if dstFolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, numFiles, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, numFiles, filesSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
// we cannot have a directory here, initialSize != -1 only for files
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, dstFolder.BaseVirtualFolder, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(dstFolder.BaseVirtualFolder, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
if dstFolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, 0, filesSize-initialSize, false) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -951,7 +951,7 @@ func (c Connection) updateQuotaAfterRename(request *sftp.Request, targetPath str
|
|||
// both files are contained inside the user home dir
|
||||
if initialSize != -1 {
|
||||
// we cannot have a directory here
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.User, -1, -initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.User, -1, -initialSize, false) //nolint:errcheck
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -209,12 +209,12 @@ func (c *scpCommand) handleUploadFile(resolvedPath, filePath string, sizeToRead
|
|||
if vfs.IsLocalOsFs(c.connection.fs) {
|
||||
vfolder, err := c.connection.User.GetVirtualFolderForPath(path.Dir(requestPath))
|
||||
if err == nil {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, vfolder.BaseVirtualFolder, 0, -fileSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(vfolder.BaseVirtualFolder, 0, -fileSize, false) //nolint:errcheck
|
||||
if vfolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.connection.User, 0, -fileSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.connection.User, 0, -fileSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.connection.User, 0, -fileSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.connection.User, 0, -fileSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
initialSize = fileSize
|
||||
|
|
|
@ -184,7 +184,7 @@ func (c Configuration) Initialize(configDir string) error {
|
|||
},
|
||||
NextAuthMethodsCallback: func(conn ssh.ConnMetadata) []string {
|
||||
var nextMethods []string
|
||||
user, err := dataprovider.UserExists(dataProvider, conn.User())
|
||||
user, err := dataprovider.UserExists(conn.User())
|
||||
if err == nil {
|
||||
nextMethods = user.GetNextAuthMethods(conn.PartialSuccessMethods())
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ func (c Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Server
|
|||
|
||||
connection.Log(logger.LevelInfo, logSender, "User id: %d, logged in with: %#v, username: %#v, home_dir: %#v remote addr: %#v",
|
||||
user.ID, loginType, user.Username, user.HomeDir, remoteAddr.String())
|
||||
dataprovider.UpdateLastLogin(dataProvider, user) //nolint:errcheck
|
||||
dataprovider.UpdateLastLogin(user) //nolint:errcheck
|
||||
|
||||
go ssh.DiscardRequests(reqs)
|
||||
|
||||
|
@ -668,7 +668,7 @@ func (c Configuration) validatePublicKeyCredentials(conn ssh.ConnMetadata, pubKe
|
|||
}
|
||||
certPerm = &cert.Permissions
|
||||
}
|
||||
if user, keyID, err = dataprovider.CheckUserAndPubKey(dataProvider, conn.User(), pubKey.Marshal()); err == nil {
|
||||
if user, keyID, err = dataprovider.CheckUserAndPubKey(conn.User(), pubKey.Marshal()); err == nil {
|
||||
if user.IsPartialAuth(method) {
|
||||
logger.Debug(logSender, connectionID, "user %#v authenticated with partial success", conn.User())
|
||||
return certPerm, ssh.ErrPartialSuccess
|
||||
|
@ -698,7 +698,7 @@ func (c Configuration) validatePasswordCredentials(conn ssh.ConnMetadata, pass [
|
|||
if len(conn.PartialSuccessMethods()) == 1 {
|
||||
method = dataprovider.SSHLoginMethodKeyAndPassword
|
||||
}
|
||||
if user, err = dataprovider.CheckUserAndPass(dataProvider, conn.User(), string(pass)); err == nil {
|
||||
if user, err = dataprovider.CheckUserAndPass(conn.User(), string(pass)); err == nil {
|
||||
sshPerm, err = loginUser(user, method, "", conn)
|
||||
}
|
||||
updateLoginMetrics(conn, method, err)
|
||||
|
@ -714,7 +714,7 @@ func (c Configuration) validateKeyboardInteractiveCredentials(conn ssh.ConnMetad
|
|||
if len(conn.PartialSuccessMethods()) == 1 {
|
||||
method = dataprovider.SSHLoginMethodKeyAndKeyboardInt
|
||||
}
|
||||
if user, err = dataprovider.CheckKeyboardInteractiveAuth(dataProvider, conn.User(), c.KeyboardInteractiveHook, client); err == nil {
|
||||
if user, err = dataprovider.CheckKeyboardInteractiveAuth(conn.User(), c.KeyboardInteractiveHook, client); err == nil {
|
||||
sshPerm, err = loginUser(user, method, "", conn)
|
||||
}
|
||||
updateLoginMetrics(conn, method, err)
|
||||
|
|
|
@ -65,7 +65,6 @@ var (
|
|||
idleTimeout time.Duration
|
||||
activeQuotaScans []ActiveQuotaScan
|
||||
activeVFoldersQuotaScan []ActiveVirtualFolderQuotaScan
|
||||
dataProvider dataprovider.Provider
|
||||
actions Actions
|
||||
uploadMode int
|
||||
setstatMode int
|
||||
|
@ -272,11 +271,6 @@ func (t connectionTransfer) getConnectionTransferAsString() string {
|
|||
return result
|
||||
}
|
||||
|
||||
// SetDataProvider sets the data provider to use to authenticate users and to get/update their disk quota
|
||||
func SetDataProvider(provider dataprovider.Provider) {
|
||||
dataProvider = provider
|
||||
}
|
||||
|
||||
func getActiveSessions(username string) int {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
|
|
|
@ -155,7 +155,6 @@ func TestMain(m *testing.M) {
|
|||
httpConfig := config.GetHTTPConfig()
|
||||
httpConfig.Initialize(configDir)
|
||||
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
sftpdConf := config.GetSFTPDConfig()
|
||||
httpdConf := config.GetHTTPDConfig()
|
||||
sftpdConf.BindPort = 2022
|
||||
|
@ -214,8 +213,6 @@ func TestMain(m *testing.M) {
|
|||
logger.WarnToConsole("unable to save trusted CA user key: %v", err)
|
||||
}
|
||||
sftpdConf.TrustedUserCAKeys = append(sftpdConf.TrustedUserCAKeys, trustedCAUserKey)
|
||||
sftpd.SetDataProvider(dataProvider)
|
||||
httpd.SetDataProvider(dataProvider)
|
||||
|
||||
go func() {
|
||||
logger.Debug(logSender, "", "initializing SFTP server with config %+v", sftpdConf)
|
||||
|
@ -1283,8 +1280,7 @@ func TestPreLoginScript(t *testing.T) {
|
|||
}
|
||||
usePubKey := true
|
||||
u := getTestUser(usePubKey)
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1294,8 +1290,6 @@ func TestPreLoginScript(t *testing.T) {
|
|||
providerConf.PreLoginHook = preLoginPath
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
user, _, err := httpd.AddUser(u, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
@ -1321,16 +1315,13 @@ func TestPreLoginScript(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(user.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
err = os.Remove(preLoginPath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -1341,8 +1332,7 @@ func TestPreLoginUserCreation(t *testing.T) {
|
|||
}
|
||||
usePubKey := false
|
||||
u := getTestUser(usePubKey)
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1352,8 +1342,6 @@ func TestPreLoginUserCreation(t *testing.T) {
|
|||
providerConf.PreLoginHook = preLoginPath
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
users, _, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
@ -1369,16 +1357,13 @@ func TestPreLoginUserCreation(t *testing.T) {
|
|||
user := users[0]
|
||||
err = os.RemoveAll(user.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
err = os.Remove(preLoginPath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -1390,8 +1375,7 @@ func TestLoginExternalAuthPwdAndPubKey(t *testing.T) {
|
|||
usePubKey := true
|
||||
u := getTestUser(usePubKey)
|
||||
u.QuotaFiles = 1000
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1402,8 +1386,6 @@ func TestLoginExternalAuthPwdAndPubKey(t *testing.T) {
|
|||
providerConf.ExternalAuthScope = 0
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
testFileSize := int64(65535)
|
||||
client, err := getSftpClient(u, usePubKey)
|
||||
|
@ -1447,16 +1429,13 @@ func TestLoginExternalAuthPwdAndPubKey(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
err = os.Remove(extAuthPath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -1469,8 +1448,7 @@ func TestExternalAuthDifferentUsername(t *testing.T) {
|
|||
extAuthUsername := "common_user"
|
||||
u := getTestUser(usePubKey)
|
||||
u.QuotaFiles = 1000
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1481,8 +1459,6 @@ func TestExternalAuthDifferentUsername(t *testing.T) {
|
|||
providerConf.ExternalAuthScope = 0
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
// the user logins using "defaultUsername" and the external auth returns "extAuthUsername"
|
||||
testFileSize := int64(65535)
|
||||
|
@ -1525,16 +1501,13 @@ func TestExternalAuthDifferentUsername(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
err = os.Remove(extAuthPath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -1561,8 +1534,7 @@ func TestLoginExternalAuth(t *testing.T) {
|
|||
QuotaFiles: 1 + authScope,
|
||||
QuotaSize: 10 + int64(authScope),
|
||||
})
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1573,8 +1545,6 @@ func TestLoginExternalAuth(t *testing.T) {
|
|||
providerConf.ExternalAuthScope = authScope
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
client, err := getSftpClient(u, usePubKey)
|
||||
if assert.NoError(t, err) {
|
||||
|
@ -1610,16 +1580,13 @@ func TestLoginExternalAuth(t *testing.T) {
|
|||
|
||||
_, err = httpd.RemoveFolder(vfs.BaseVirtualFolder{MappedPath: mappedPath}, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
err = os.Remove(extAuthPath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -1631,8 +1598,7 @@ func TestLoginExternalAuthInteractive(t *testing.T) {
|
|||
}
|
||||
usePubKey := false
|
||||
u := getTestUser(usePubKey)
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1643,8 +1609,6 @@ func TestLoginExternalAuthInteractive(t *testing.T) {
|
|||
providerConf.ExternalAuthScope = 4
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
err = ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 0, false, 1), 0755)
|
||||
assert.NoError(t, err)
|
||||
|
@ -1673,16 +1637,13 @@ func TestLoginExternalAuthInteractive(t *testing.T) {
|
|||
err = os.RemoveAll(user.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
err = os.Remove(extAuthPath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -1693,8 +1654,7 @@ func TestLoginExternalAuthErrors(t *testing.T) {
|
|||
}
|
||||
usePubKey := true
|
||||
u := getTestUser(usePubKey)
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1705,8 +1665,6 @@ func TestLoginExternalAuthErrors(t *testing.T) {
|
|||
providerConf.ExternalAuthScope = 0
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
client, err := getSftpClient(u, usePubKey)
|
||||
if !assert.Error(t, err, "login must fail, external auth returns a non json response") {
|
||||
|
@ -1723,23 +1681,19 @@ func TestLoginExternalAuthErrors(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(users))
|
||||
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
err = os.Remove(extAuthPath)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestQuotaDisabledError(t *testing.T) {
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -1747,8 +1701,6 @@ func TestQuotaDisabledError(t *testing.T) {
|
|||
providerConf.TrackQuota = 0
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
usePubKey := false
|
||||
u := getTestUser(usePubKey)
|
||||
u.QuotaFiles = 1
|
||||
|
@ -1776,16 +1728,13 @@ func TestQuotaDisabledError(t *testing.T) {
|
|||
err = os.RemoveAll(user.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
}
|
||||
|
||||
func TestMaxSessions(t *testing.T) {
|
||||
|
@ -3743,8 +3692,7 @@ func TestVirtualFoldersLink(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestOverlappedMappedFolders(t *testing.T) {
|
||||
dataProvider := dataprovider.GetProvider()
|
||||
err := dataprovider.Close(dataProvider)
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -3752,8 +3700,6 @@ func TestOverlappedMappedFolders(t *testing.T) {
|
|||
providerConf.TrackQuota = 0
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
usePubKey := false
|
||||
u := getTestUser(usePubKey)
|
||||
|
@ -3824,16 +3770,13 @@ func TestOverlappedMappedFolders(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
dataProvider = dataprovider.GetProvider()
|
||||
err = dataprovider.Close(dataProvider)
|
||||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf = config.GetProviderConf()
|
||||
err = dataprovider.Initialize(providerConf, configDir)
|
||||
assert.NoError(t, err)
|
||||
httpd.SetDataProvider(dataprovider.GetProvider())
|
||||
sftpd.SetDataProvider(dataprovider.GetProvider())
|
||||
|
||||
if providerConf.Driver != dataprovider.MemoryDataProviderName {
|
||||
client, err = getSftpClient(user, usePubKey)
|
||||
|
|
|
@ -243,12 +243,12 @@ func (c *sshCommand) handeSFTPGoRemove() error {
|
|||
func (c *sshCommand) updateQuota(sshDestPath string, filesNum int, filesSize int64) {
|
||||
vfolder, err := c.connection.User.GetVirtualFolderForPath(sshDestPath)
|
||||
if err == nil {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, vfolder.BaseVirtualFolder, filesNum, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(vfolder.BaseVirtualFolder, filesNum, filesSize, false) //nolint:errcheck
|
||||
if vfolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.connection.User, filesNum, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.connection.User, filesNum, filesSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
dataprovider.UpdateUserQuota(dataProvider, c.connection.User, filesNum, filesSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(c.connection.User, filesNum, filesSize, false) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -208,13 +208,13 @@ func (t *Transfer) updateQuota(numFiles int) bool {
|
|||
if t.transferType == transferUpload && (numFiles != 0 || t.bytesReceived > 0) {
|
||||
vfolder, err := t.user.GetVirtualFolderForPath(path.Dir(t.requestPath))
|
||||
if err == nil {
|
||||
dataprovider.UpdateVirtualFolderQuota(dataProvider, vfolder.BaseVirtualFolder, numFiles, //nolint:errcheck
|
||||
dataprovider.UpdateVirtualFolderQuota(vfolder.BaseVirtualFolder, numFiles, //nolint:errcheck
|
||||
t.bytesReceived-t.initialSize, false)
|
||||
if vfolder.IsIncludedInUserQuota() {
|
||||
dataprovider.UpdateUserQuota(dataProvider, t.user, numFiles, t.bytesReceived-t.initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(t.user, numFiles, t.bytesReceived-t.initialSize, false) //nolint:errcheck
|
||||
}
|
||||
} else {
|
||||
dataprovider.UpdateUserQuota(dataProvider, t.user, numFiles, t.bytesReceived-t.initialSize, false) //nolint:errcheck
|
||||
dataprovider.UpdateUserQuota(t.user, numFiles, t.bytesReceived-t.initialSize, false) //nolint:errcheck
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Create model User
|
||||
--
|
||||
CREATE TABLE `users` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `username` varchar(255) NOT NULL UNIQUE, `password` varchar(255) NULL, `public_keys` longtext NULL, `home_dir` varchar(255) NOT NULL, `uid` integer NOT NULL, `gid` integer NOT NULL, `max_sessions` integer NOT NULL, `quota_size` bigint NOT NULL, `quota_files` integer NOT NULL, `permissions` longtext NOT NULL, `used_quota_size` bigint NOT NULL, `used_quota_files` integer NOT NULL, `last_quota_update` bigint NOT NULL, `upload_bandwidth` integer NOT NULL, `download_bandwidth` integer NOT NULL);
|
||||
COMMIT;
|
|
@ -1,17 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field expiration_date to user
|
||||
--
|
||||
ALTER TABLE `users` ADD COLUMN `expiration_date` bigint DEFAULT 0 NOT NULL;
|
||||
ALTER TABLE `users` ALTER COLUMN `expiration_date` DROP DEFAULT;
|
||||
--
|
||||
-- Add field last_login to user
|
||||
--
|
||||
ALTER TABLE `users` ADD COLUMN `last_login` bigint DEFAULT 0 NOT NULL;
|
||||
ALTER TABLE `users` ALTER COLUMN `last_login` DROP DEFAULT;
|
||||
--
|
||||
-- Add field status to user
|
||||
--
|
||||
ALTER TABLE `users` ADD COLUMN `status` integer DEFAULT 1 NOT NULL;
|
||||
ALTER TABLE `users` ALTER COLUMN `status` DROP DEFAULT;
|
||||
COMMIT;
|
|
@ -1,6 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field filters to user
|
||||
--
|
||||
ALTER TABLE `users` ADD COLUMN `filters` longtext NULL;
|
||||
COMMIT;
|
|
@ -1,6 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field filesystem to user
|
||||
--
|
||||
ALTER TABLE `users` ADD COLUMN `filesystem` longtext NULL;
|
||||
COMMIT;
|
|
@ -1,10 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Create model SchemaVersion
|
||||
--
|
||||
CREATE TABLE `schema_version` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `version` integer NOT NULL);
|
||||
---
|
||||
--- Add initial version
|
||||
---
|
||||
INSERT INTO schema_version (version) VALUES (1);
|
||||
COMMIT;
|
|
@ -1,6 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Create model User
|
||||
--
|
||||
CREATE TABLE "users" ("id" serial NOT NULL PRIMARY KEY, "username" varchar(255) NOT NULL UNIQUE, "password" varchar(255) NULL, "public_keys" text NULL, "home_dir" varchar(255) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL, "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL, "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL);
|
||||
COMMIT;
|
|
@ -1,17 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field expiration_date to user
|
||||
--
|
||||
ALTER TABLE "users" ADD COLUMN "expiration_date" bigint DEFAULT 0 NOT NULL;
|
||||
ALTER TABLE "users" ALTER COLUMN "expiration_date" DROP DEFAULT;
|
||||
--
|
||||
-- Add field last_login to user
|
||||
--
|
||||
ALTER TABLE "users" ADD COLUMN "last_login" bigint DEFAULT 0 NOT NULL;
|
||||
ALTER TABLE "users" ALTER COLUMN "last_login" DROP DEFAULT;
|
||||
--
|
||||
-- Add field status to user
|
||||
--
|
||||
ALTER TABLE "users" ADD COLUMN "status" integer DEFAULT 1 NOT NULL;
|
||||
ALTER TABLE "users" ALTER COLUMN "status" DROP DEFAULT;
|
||||
COMMIT;
|
|
@ -1,6 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field filters to user
|
||||
--
|
||||
ALTER TABLE "users" ADD COLUMN "filters" text NULL;
|
||||
COMMIT;
|
|
@ -1,6 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field filesystem to user
|
||||
--
|
||||
ALTER TABLE "users" ADD COLUMN "filesystem" text NULL;
|
||||
COMMIT;
|
|
@ -1,10 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Create model SchemaVersion
|
||||
--
|
||||
CREATE TABLE "schema_version" ("id" serial NOT NULL PRIMARY KEY, "version" integer NOT NULL);
|
||||
---
|
||||
--- Add initial version
|
||||
---
|
||||
INSERT INTO schema_version (version) VALUES (1);
|
||||
COMMIT;
|
|
@ -1,6 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Create model User
|
||||
--
|
||||
CREATE TABLE "users" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL UNIQUE, "password" varchar(255) NULL, "public_keys" text NULL, "home_dir" varchar(255) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL, "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL, "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL);
|
||||
COMMIT;
|
|
@ -1,23 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field expiration_date to user
|
||||
--
|
||||
CREATE TABLE "new__users" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "expiration_date" bigint NOT NULL, "username" varchar(255) NOT NULL UNIQUE, "password" varchar(255) NULL, "public_keys" text NULL, "home_dir" varchar(255) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL, "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL, "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL);
|
||||
INSERT INTO "new__users" ("id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date") SELECT "id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", 0 FROM "users";
|
||||
DROP TABLE "users";
|
||||
ALTER TABLE "new__users" RENAME TO "users";
|
||||
--
|
||||
-- Add field last_login to user
|
||||
--
|
||||
CREATE TABLE "new__users" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL UNIQUE, "password" varchar(255) NULL, "public_keys" text NULL, "home_dir" varchar(255) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL, "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL, "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL, "expiration_date" bigint NOT NULL, "last_login" bigint NOT NULL);
|
||||
INSERT INTO "new__users" ("id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", "last_login") SELECT "id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", 0 FROM "users";
|
||||
DROP TABLE "users";
|
||||
ALTER TABLE "new__users" RENAME TO "users";
|
||||
--
|
||||
-- Add field status to user
|
||||
--
|
||||
CREATE TABLE "new__users" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL UNIQUE, "password" varchar(255) NULL, "public_keys" text NULL, "home_dir" varchar(255) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL, "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL, "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL, "expiration_date" bigint NOT NULL, "last_login" bigint NOT NULL, "status" integer NOT NULL);
|
||||
INSERT INTO "new__users" ("id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", "last_login", "status") SELECT "id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", "last_login", 1 FROM "users";
|
||||
DROP TABLE "users";
|
||||
ALTER TABLE "new__users" RENAME TO "users";
|
||||
COMMIT;
|
|
@ -1,9 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field filters to user
|
||||
--
|
||||
CREATE TABLE "new__users" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "filters" text NULL, "username" varchar(255) NOT NULL UNIQUE, "password" varchar(255) NULL, "public_keys" text NULL, "home_dir" varchar(255) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL, "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL, "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL, "expiration_date" bigint NOT NULL, "last_login" bigint NOT NULL, "status" integer NOT NULL);
|
||||
INSERT INTO "new__users" ("id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", "last_login", "status", "filters") SELECT "id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", "last_login", "status", NULL FROM "users";
|
||||
DROP TABLE "users";
|
||||
ALTER TABLE "new__users" RENAME TO "users";
|
||||
COMMIT;
|
|
@ -1,9 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Add field filesystem to user
|
||||
--
|
||||
CREATE TABLE "new__users" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL UNIQUE, "password" varchar(255) NULL, "public_keys" text NULL, "home_dir" varchar(255) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL, "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL, "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL, "expiration_date" bigint NOT NULL, "last_login" bigint NOT NULL, "status" integer NOT NULL, "filters" text NULL, "filesystem" text NULL);
|
||||
INSERT INTO "new__users" ("id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", "last_login", "status", "filters", "filesystem") SELECT "id", "username", "password", "public_keys", "home_dir", "uid", "gid", "max_sessions", "quota_size", "quota_files", "permissions", "used_quota_size", "used_quota_files", "last_quota_update", "upload_bandwidth", "download_bandwidth", "expiration_date", "last_login", "status", "filters", NULL FROM "users";
|
||||
DROP TABLE "users";
|
||||
ALTER TABLE "new__users" RENAME TO "users";
|
||||
COMMIT;
|
|
@ -1,10 +0,0 @@
|
|||
BEGIN;
|
||||
--
|
||||
-- Create model SchemaVersion
|
||||
--
|
||||
CREATE TABLE "schema_version" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "version" integer NOT NULL);
|
||||
---
|
||||
--- Add initial version
|
||||
---
|
||||
INSERT INTO schema_version (version) VALUES (1);
|
||||
COMMIT;
|
Loading…
Reference in a new issue