mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-21 23:20:24 +00:00
add new test cases
This commit is contained in:
parent
2a8ab620f3
commit
89986b9305
4 changed files with 98 additions and 32 deletions
|
@ -52,7 +52,7 @@ func TestMain(m *testing.M) {
|
||||||
configDir := ".."
|
configDir := ".."
|
||||||
logfilePath := filepath.Join(configDir, "sftpgo_api_test.log")
|
logfilePath := filepath.Join(configDir, "sftpgo_api_test.log")
|
||||||
confName := "sftpgo.conf"
|
confName := "sftpgo.conf"
|
||||||
logger.InitLogger(logfilePath, zerolog.DebugLevel)
|
logger.InitLogger(logfilePath, 5, 1, 28, false, zerolog.DebugLevel)
|
||||||
configFilePath := filepath.Join(configDir, confName)
|
configFilePath := filepath.Join(configDir, confName)
|
||||||
config.LoadConfig(configFilePath)
|
config.LoadConfig(configFilePath)
|
||||||
providerConf := config.GetProviderConf()
|
providerConf := config.GetProviderConf()
|
||||||
|
@ -630,11 +630,11 @@ func waitTCPListening(address string) {
|
||||||
for {
|
for {
|
||||||
conn, err := net.Dial("tcp", address)
|
conn, err := net.Dial("tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("tcp server %v not listening: %v\n", address, err)
|
logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("tcp server %v now listening\n", address)
|
logger.InfoToConsole("tcp server %v now listening\n", address)
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/drakkan/sftpgo/dataprovider"
|
"github.com/drakkan/sftpgo/dataprovider"
|
||||||
|
"github.com/drakkan/sftpgo/logger"
|
||||||
"github.com/drakkan/sftpgo/sftpd"
|
"github.com/drakkan/sftpgo/sftpd"
|
||||||
"github.com/drakkan/sftpgo/utils"
|
"github.com/drakkan/sftpgo/utils"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
|
@ -186,7 +187,7 @@ func checkResponse(actual int, expected int, resp *http.Response) error {
|
||||||
if expected != http.StatusOK && resp != nil {
|
if expected != http.StatusOK && resp != nil {
|
||||||
b, err := ioutil.ReadAll(resp.Body)
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Printf("request: %v, response body: %v", resp.Request.URL, string(b))
|
logger.InfoToConsole("request: %v, response body: %v", resp.Request.URL, string(b))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -54,7 +54,6 @@ func (c Configuration) Initialize(configDir string) error {
|
||||||
logger.Warn(logSender, "error reading umask, please fix your config file: %v", err)
|
logger.Warn(logSender, "error reading umask, please fix your config file: %v", err)
|
||||||
logger.WarnToConsole("error reading umask, please fix your config file: %v", err)
|
logger.WarnToConsole("error reading umask, please fix your config file: %v", err)
|
||||||
}
|
}
|
||||||
actions = c.Actions
|
|
||||||
serverConfig := &ssh.ServerConfig{
|
serverConfig := &ssh.ServerConfig{
|
||||||
NoClientAuth: false,
|
NoClientAuth: false,
|
||||||
MaxAuthTries: c.MaxAuthTries,
|
MaxAuthTries: c.MaxAuthTries,
|
||||||
|
@ -106,6 +105,7 @@ func (c Configuration) Initialize(configDir string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actions = c.Actions
|
||||||
logger.Info(logSender, "server listener registered address: %v", listener.Addr().String())
|
logger.Info(logSender, "server listener registered address: %v", listener.Addr().String())
|
||||||
if c.IdleTimeout > 0 {
|
if c.IdleTimeout > 0 {
|
||||||
startIdleTimer(time.Duration(c.IdleTimeout) * time.Minute)
|
startIdleTimer(time.Duration(c.IdleTimeout) * time.Minute)
|
||||||
|
|
|
@ -29,12 +29,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
logSender = "sftpdTesting"
|
logSender = "sftpdTesting"
|
||||||
sftpServerAddr = "127.0.0.1:2022"
|
sftpServerAddr = "127.0.0.1:2022"
|
||||||
defaultUsername = "test_user_sftp"
|
defaultUsername = "test_user_sftp"
|
||||||
defaultPassword = "test_password"
|
defaultPassword = "test_password"
|
||||||
testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
|
testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
|
||||||
testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
|
testInvalidPublicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCd60+/j+y8f0tLftihWV1YN9RSahMI9btQMDIMqts/jeNbD8jgoogM3nhF7KxfcaMKURuD47KC4Ey6iAJUJ0sWkSNNxOcIYuvA+5MlspfZDsa8Ag76Fe1vyz72WeHMHMeh/hwFo2TeIeIXg480T1VI6mzfDrVp2GzUx0SS0dMsQBjftXkuVR8YOiOwMCAH2a//M1OrvV7d/NBk6kBN0WnuIBb2jKm15PAA7+jQQG7tzwk2HedNH3jeL5GH31xkSRwlBczRK0xsCQXehAlx6cT/e/s44iJcJTHfpPKoSk6UAhPJYe7Z1QnuoawY9P9jQaxpyeImBZxxUEowhjpj2avBxKdRGBVK8R7EL8tSOeLbhdyWe5Mwc1+foEbq9Zz5j5Kd+hn3Wm1UnsGCrXUUUoZp1jnlNl0NakCto+5KmqnT9cHxaY+ix2RLUWAZyVFlRq71OYux1UHJnEJPiEI1/tr4jFBSL46qhQZv/TfpkfVW8FLz0lErfqu0gQEZnNHr3Fc= nicola@p1"
|
||||||
|
testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||||
NhAAAAAwEAAQAAAYEAtN449A/nY5O6cSH/9Doa8a3ISU0WZJaHydTaCLuO+dkqtNpnV5mq
|
NhAAAAAwEAAQAAAYEAtN449A/nY5O6cSH/9Doa8a3ISU0WZJaHydTaCLuO+dkqtNpnV5mq
|
||||||
zFbKidXAI1eSwVctw9ReVOl1uK6aZF3lbXdOD8W9PXobR9KUUT2qBx5QC4ibfAqDKWymDA
|
zFbKidXAI1eSwVctw9ReVOl1uK6aZF3lbXdOD8W9PXobR9KUUT2qBx5QC4ibfAqDKWymDA
|
||||||
|
@ -72,19 +73,19 @@ NbbCNsVroqKlChT5wyPNGS+phi2bPARBno7WSDvshTZ7dAVEP2c9MJW0XwoSevwKlhgSdt
|
||||||
RLFFQ/5nclJSdzPBOmQouC0OBcMFSrYtMeknJ4VvueVvve5HcHFaEsaMc7ABAGaLYaBQOm
|
RLFFQ/5nclJSdzPBOmQouC0OBcMFSrYtMeknJ4VvueVvve5HcHFaEsaMc7ABAGaLYaBQOm
|
||||||
iixITGvaNZh/tjAAAACW5pY29sYUBwMQE=
|
iixITGvaNZh/tjAAAACW5pY29sYUBwMQE=
|
||||||
-----END OPENSSH PRIVATE KEY-----`
|
-----END OPENSSH PRIVATE KEY-----`
|
||||||
|
configDir = ".."
|
||||||
|
confName = "sftpgo.conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
allPerms = []string{dataprovider.PermAny}
|
allPerms = []string{dataprovider.PermAny}
|
||||||
homeBasePath string
|
homeBasePath string
|
||||||
|
configFilePath = filepath.Join(configDir, confName)
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
configDir := ".."
|
|
||||||
logfilePath := filepath.Join(configDir, "sftpgo_sftpd_test.log")
|
logfilePath := filepath.Join(configDir, "sftpgo_sftpd_test.log")
|
||||||
confName := "sftpgo.conf"
|
logger.InitLogger(logfilePath, 5, 1, 28, false, zerolog.DebugLevel)
|
||||||
logger.InitLogger(logfilePath, zerolog.DebugLevel)
|
|
||||||
configFilePath := filepath.Join(configDir, confName)
|
|
||||||
config.LoadConfig(configFilePath)
|
config.LoadConfig(configFilePath)
|
||||||
providerConf := config.GetProviderConf()
|
providerConf := config.GetProviderConf()
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ func TestMain(m *testing.M) {
|
||||||
homeBasePath = "C:\\"
|
homeBasePath = "C:\\"
|
||||||
} else {
|
} else {
|
||||||
homeBasePath = "/tmp"
|
homeBasePath = "/tmp"
|
||||||
sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "delete"}
|
sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "rename"}
|
||||||
sftpdConf.Actions.Command = "/bin/true"
|
sftpdConf.Actions.Command = "/bin/true"
|
||||||
sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8080/"
|
sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8080/"
|
||||||
}
|
}
|
||||||
|
@ -138,6 +139,16 @@ func TestMain(m *testing.M) {
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInitialization(t *testing.T) {
|
||||||
|
config.LoadConfig(configFilePath)
|
||||||
|
sftpdConf := config.GetSFTPDConfig()
|
||||||
|
sftpdConf.Umask = "invalid umask"
|
||||||
|
err := sftpdConf.Initialize(configDir)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Inizialize must fail, a SFTP server should be already running")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBasicSFTPHandling(t *testing.T) {
|
func TestBasicSFTPHandling(t *testing.T) {
|
||||||
usePubKey := false
|
usePubKey := false
|
||||||
user, err := api.AddUser(getTestUser(usePubKey), http.StatusOK)
|
user, err := api.AddUser(getTestUser(usePubKey), http.StatusOK)
|
||||||
|
@ -450,26 +461,50 @@ func TestHomeSpecialChars(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoginPubKey(t *testing.T) {
|
func TestLogin(t *testing.T) {
|
||||||
usePubKey := true
|
u := getTestUser(false)
|
||||||
user, err := api.AddUser(getTestUser(usePubKey), http.StatusOK)
|
u.PublicKey = testPubKey
|
||||||
|
user, err := api.AddUser(u, http.StatusOK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to add user: %v", err)
|
t.Errorf("unable to add user: %v", err)
|
||||||
}
|
}
|
||||||
client, err := getSftpClient(user, usePubKey)
|
client, err := getSftpClient(user, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to create sftp client: %v", err)
|
t.Errorf("unable to create sftp client: %v", err)
|
||||||
} else {
|
} else {
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
_, err := client.Getwd()
|
_, err := client.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to get working dir: %v", err)
|
t.Errorf("sftp client with valid password must work")
|
||||||
}
|
}
|
||||||
_, err = client.ReadDir(".")
|
}
|
||||||
|
client, err = getSftpClient(user, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to create sftp client: %v", err)
|
||||||
|
} else {
|
||||||
|
defer client.Close()
|
||||||
|
_, err := client.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to read remote dir: %v", err)
|
t.Errorf("sftp client with valid public key must work")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
user.Password = "invalid password"
|
||||||
|
client, err = getSftpClient(user, false)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("login with invalid password must fail")
|
||||||
|
defer client.Close()
|
||||||
|
}
|
||||||
|
user.PublicKey = testInvalidPublicKey
|
||||||
|
user.Password = ""
|
||||||
|
_, err = api.UpdateUser(user, http.StatusOK)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to update user: %v", err)
|
||||||
|
}
|
||||||
|
client, err = getSftpClient(user, true)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("login with invalid public key must fail")
|
||||||
|
defer client.Close()
|
||||||
|
}
|
||||||
err = api.RemoveUser(user, http.StatusOK)
|
err = api.RemoveUser(user, http.StatusOK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to remove user: %v", err)
|
t.Errorf("unable to remove user: %v", err)
|
||||||
|
@ -580,16 +615,16 @@ func TestQuotaFileReplace(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to add user: %v", err)
|
t.Errorf("unable to add user: %v", err)
|
||||||
}
|
}
|
||||||
|
testFileSize := int64(65535)
|
||||||
|
testFileName := "test_file.dat"
|
||||||
|
testFilePath := filepath.Join(homeBasePath, testFileName)
|
||||||
client, err := getSftpClient(user, usePubKey)
|
client, err := getSftpClient(user, usePubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to create sftp client: %v", err)
|
t.Errorf("unable to create sftp client: %v", err)
|
||||||
} else {
|
} else {
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
testFileSize := int64(65535)
|
|
||||||
expectedQuotaSize := user.UsedQuotaSize + testFileSize
|
expectedQuotaSize := user.UsedQuotaSize + testFileSize
|
||||||
expectedQuotaFiles := user.UsedQuotaFiles + 1
|
expectedQuotaFiles := user.UsedQuotaFiles + 1
|
||||||
testFileName := "test_file.dat"
|
|
||||||
testFilePath := filepath.Join(homeBasePath, testFileName)
|
|
||||||
err = createTestFile(testFilePath, testFileSize)
|
err = createTestFile(testFilePath, testFileSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unable to create test file: %v", err)
|
t.Errorf("unable to create test file: %v", err)
|
||||||
|
@ -623,6 +658,21 @@ func TestQuotaFileReplace(t *testing.T) {
|
||||||
if expectedQuotaSize != user.UsedQuotaSize {
|
if expectedQuotaSize != user.UsedQuotaSize {
|
||||||
t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
|
t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// now set a quota size restriction and upload the same fail, upload should fail for space limit exceeded
|
||||||
|
user.QuotaSize = testFileSize - 1
|
||||||
|
user, err = api.UpdateUser(user, http.StatusOK)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error updating user: %v", err)
|
||||||
|
}
|
||||||
|
client, err = getSftpClient(user, usePubKey)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to create sftp client: %v", err)
|
||||||
|
} else {
|
||||||
|
err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("quota size exceeded, file upload must fail")
|
||||||
|
}
|
||||||
err = client.Remove(testFileName)
|
err = client.Remove(testFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error removing uploaded file: %v", err)
|
t.Errorf("error removing uploaded file: %v", err)
|
||||||
|
@ -1094,11 +1144,11 @@ func waitTCPListening(address string) {
|
||||||
for {
|
for {
|
||||||
conn, err := net.Dial("tcp", address)
|
conn, err := net.Dial("tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("tcp server %v not listening: %v\n", address, err)
|
logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("tcp server %v now listening\n", address)
|
logger.InfoToConsole("tcp server %v now listening\n", address)
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1148,10 +1198,21 @@ func doSSH(user dataprovider.User, usePubKey bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func modifyConf(sftpdConf sftpd.Configuration) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
homeBasePath = "C:\\"
|
||||||
|
} else {
|
||||||
|
homeBasePath = "/tmp"
|
||||||
|
sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "rename"}
|
||||||
|
sftpdConf.Actions.Command = "/bin/true"
|
||||||
|
sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8080/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error) {
|
func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error) {
|
||||||
var sftpClient *sftp.Client
|
var sftpClient *sftp.Client
|
||||||
config := &ssh.ClientConfig{
|
config := &ssh.ClientConfig{
|
||||||
User: defaultUsername,
|
User: user.Username,
|
||||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -1163,7 +1224,11 @@ func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error)
|
||||||
}
|
}
|
||||||
config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
|
config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
|
||||||
} else {
|
} else {
|
||||||
config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
|
if len(user.Password) > 0 {
|
||||||
|
config.Auth = []ssh.AuthMethod{ssh.Password(user.Password)}
|
||||||
|
} else {
|
||||||
|
config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
conn, err := ssh.Dial("tcp", sftpServerAddr, config)
|
conn, err := ssh.Dial("tcp", sftpServerAddr, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue