internal_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. package httpd
  2. import (
  3. "context"
  4. "fmt"
  5. "html/template"
  6. "io/ioutil"
  7. "net/http"
  8. "net/http/httptest"
  9. "net/url"
  10. "os"
  11. "path/filepath"
  12. "runtime"
  13. "strings"
  14. "testing"
  15. "github.com/drakkan/sftpgo/dataprovider"
  16. "github.com/drakkan/sftpgo/sftpd"
  17. "github.com/drakkan/sftpgo/utils"
  18. "github.com/drakkan/sftpgo/vfs"
  19. "github.com/go-chi/chi"
  20. )
  21. const (
  22. invalidURL = "http://foo\x7f.com/"
  23. inactiveURL = "http://127.0.0.1:12345"
  24. )
  25. func TestGetRespStatus(t *testing.T) {
  26. var err error
  27. err = &dataprovider.MethodDisabledError{}
  28. respStatus := getRespStatus(err)
  29. if respStatus != http.StatusForbidden {
  30. t.Errorf("wrong resp status extected: %d got: %d", http.StatusForbidden, respStatus)
  31. }
  32. err = fmt.Errorf("generic error")
  33. respStatus = getRespStatus(err)
  34. if respStatus != http.StatusInternalServerError {
  35. t.Errorf("wrong resp status extected: %d got: %d", http.StatusInternalServerError, respStatus)
  36. }
  37. }
  38. func TestCheckResponse(t *testing.T) {
  39. err := checkResponse(http.StatusOK, http.StatusCreated)
  40. if err == nil {
  41. t.Errorf("check must fail")
  42. }
  43. err = checkResponse(http.StatusBadRequest, http.StatusBadRequest)
  44. if err != nil {
  45. t.Errorf("test must succeed, error: %v", err)
  46. }
  47. }
  48. func TestCheckUser(t *testing.T) {
  49. expected := &dataprovider.User{}
  50. actual := &dataprovider.User{}
  51. actual.Password = "password"
  52. err := checkUser(expected, actual)
  53. if err == nil {
  54. t.Errorf("actual password must be nil")
  55. }
  56. actual.Password = ""
  57. err = checkUser(expected, actual)
  58. if err == nil {
  59. t.Errorf("actual ID must be > 0")
  60. }
  61. expected.ID = 1
  62. actual.ID = 2
  63. err = checkUser(expected, actual)
  64. if err == nil {
  65. t.Errorf("actual ID must be equal to expected ID")
  66. }
  67. expected.ID = 2
  68. actual.ID = 2
  69. expected.Permissions = make(map[string][]string)
  70. expected.Permissions["/"] = []string{dataprovider.PermCreateDirs, dataprovider.PermDelete, dataprovider.PermDownload}
  71. actual.Permissions = make(map[string][]string)
  72. err = checkUser(expected, actual)
  73. if err == nil {
  74. t.Errorf("Permissions are not equal")
  75. }
  76. actual.Permissions["/"] = []string{dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks}
  77. err = checkUser(expected, actual)
  78. if err == nil {
  79. t.Errorf("Permissions are not equal")
  80. }
  81. expected.Permissions["/"] = append(expected.Permissions["/"], dataprovider.PermRename)
  82. err = checkUser(expected, actual)
  83. if err == nil {
  84. t.Errorf("Permissions are not equal")
  85. }
  86. expected.Permissions = make(map[string][]string)
  87. expected.Permissions["/somedir"] = []string{dataprovider.PermAny}
  88. actual.Permissions = make(map[string][]string)
  89. actual.Permissions["/otherdir"] = []string{dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks}
  90. err = checkUser(expected, actual)
  91. if err == nil {
  92. t.Errorf("Permissions are not equal")
  93. }
  94. expected.Permissions = make(map[string][]string)
  95. actual.Permissions = make(map[string][]string)
  96. actual.FsConfig.Provider = 1
  97. err = checkUser(expected, actual)
  98. if err == nil {
  99. t.Errorf("Fs providers are not equal")
  100. }
  101. actual.FsConfig.Provider = 0
  102. expected.VirtualFolders = append(expected.VirtualFolders, vfs.VirtualFolder{
  103. VirtualPath: "/vdir",
  104. MappedPath: os.TempDir(),
  105. })
  106. err = checkUser(expected, actual)
  107. if err == nil {
  108. t.Errorf("Virtual folders are not equal")
  109. }
  110. actual.VirtualFolders = append(actual.VirtualFolders, vfs.VirtualFolder{
  111. VirtualPath: "/vdir1",
  112. MappedPath: os.TempDir(),
  113. })
  114. err = checkUser(expected, actual)
  115. if err == nil {
  116. t.Errorf("Virtual folders are not equal")
  117. }
  118. }
  119. func TestCompareUserFilters(t *testing.T) {
  120. expected := &dataprovider.User{}
  121. actual := &dataprovider.User{}
  122. actual.ID = 1
  123. expected.ID = 1
  124. expected.Filters.AllowedIP = []string{}
  125. actual.Filters.AllowedIP = []string{"192.168.1.2/32"}
  126. err := checkUser(expected, actual)
  127. if err == nil {
  128. t.Errorf("AllowedIP are not equal")
  129. }
  130. expected.Filters.AllowedIP = []string{"192.168.1.3/32"}
  131. err = checkUser(expected, actual)
  132. if err == nil {
  133. t.Errorf("AllowedIP contents are not equal")
  134. }
  135. expected.Filters.AllowedIP = []string{}
  136. actual.Filters.AllowedIP = []string{}
  137. expected.Filters.DeniedIP = []string{}
  138. actual.Filters.DeniedIP = []string{"192.168.1.2/32"}
  139. err = checkUser(expected, actual)
  140. if err == nil {
  141. t.Errorf("DeniedIP are not equal")
  142. }
  143. expected.Filters.DeniedIP = []string{"192.168.1.3/32"}
  144. err = checkUser(expected, actual)
  145. if err == nil {
  146. t.Errorf("DeniedIP contents are not equal")
  147. }
  148. expected.Filters.DeniedIP = []string{}
  149. actual.Filters.DeniedIP = []string{}
  150. expected.Filters.DeniedLoginMethods = []string{}
  151. actual.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodPublicKey}
  152. err = checkUser(expected, actual)
  153. if err == nil {
  154. t.Errorf("Denied login methods are not equal")
  155. }
  156. expected.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodPassword}
  157. err = checkUser(expected, actual)
  158. if err == nil {
  159. t.Errorf("Denied login methods contents are not equal")
  160. }
  161. expected.Filters.DeniedLoginMethods = []string{}
  162. actual.Filters.DeniedLoginMethods = []string{}
  163. expected.Filters.FileExtensions = append(expected.Filters.FileExtensions, dataprovider.ExtensionsFilter{
  164. Path: "/",
  165. AllowedExtensions: []string{".jpg", ".png"},
  166. DeniedExtensions: []string{".zip", ".rar"},
  167. })
  168. err = checkUser(expected, actual)
  169. if err == nil {
  170. t.Errorf("file extensons are not equal")
  171. }
  172. actual.Filters.FileExtensions = append(actual.Filters.FileExtensions, dataprovider.ExtensionsFilter{
  173. Path: "/sub",
  174. AllowedExtensions: []string{".jpg", ".png"},
  175. DeniedExtensions: []string{".zip", ".rar"},
  176. })
  177. err = checkUser(expected, actual)
  178. if err == nil {
  179. t.Errorf("file extensons contents are not equal")
  180. }
  181. actual.Filters.FileExtensions[0] = dataprovider.ExtensionsFilter{
  182. Path: "/",
  183. AllowedExtensions: []string{".jpg"},
  184. DeniedExtensions: []string{".zip", ".rar"},
  185. }
  186. err = checkUser(expected, actual)
  187. if err == nil {
  188. t.Errorf("file extensons contents are not equal")
  189. }
  190. actual.Filters.FileExtensions[0] = dataprovider.ExtensionsFilter{
  191. Path: "/",
  192. AllowedExtensions: []string{".tiff", ".png"},
  193. DeniedExtensions: []string{".zip", ".rar"},
  194. }
  195. err = checkUser(expected, actual)
  196. if err == nil {
  197. t.Errorf("file extensons contents are not equal")
  198. }
  199. actual.Filters.FileExtensions[0] = dataprovider.ExtensionsFilter{
  200. Path: "/",
  201. AllowedExtensions: []string{".jpg", ".png"},
  202. DeniedExtensions: []string{".tar.gz", ".rar"},
  203. }
  204. err = checkUser(expected, actual)
  205. if err == nil {
  206. t.Errorf("file extensons contents are not equal")
  207. }
  208. }
  209. func TestCompareUserFields(t *testing.T) {
  210. expected := &dataprovider.User{}
  211. actual := &dataprovider.User{}
  212. expected.Permissions = make(map[string][]string)
  213. actual.Permissions = make(map[string][]string)
  214. expected.Username = "test"
  215. err := compareEqualsUserFields(expected, actual)
  216. if err == nil {
  217. t.Errorf("Username does not match")
  218. }
  219. expected.Username = ""
  220. expected.HomeDir = "homedir"
  221. err = compareEqualsUserFields(expected, actual)
  222. if err == nil {
  223. t.Errorf("HomeDir does not match")
  224. }
  225. expected.HomeDir = ""
  226. expected.UID = 1
  227. err = compareEqualsUserFields(expected, actual)
  228. if err == nil {
  229. t.Errorf("UID does not match")
  230. }
  231. expected.UID = 0
  232. expected.GID = 1
  233. err = compareEqualsUserFields(expected, actual)
  234. if err == nil {
  235. t.Errorf("GID does not match")
  236. }
  237. expected.GID = 0
  238. expected.MaxSessions = 2
  239. err = compareEqualsUserFields(expected, actual)
  240. if err == nil {
  241. t.Errorf("MaxSessions do not match")
  242. }
  243. expected.MaxSessions = 0
  244. expected.QuotaSize = 4096
  245. err = compareEqualsUserFields(expected, actual)
  246. if err == nil {
  247. t.Errorf("QuotaSize does not match")
  248. }
  249. expected.QuotaSize = 0
  250. expected.QuotaFiles = 2
  251. err = compareEqualsUserFields(expected, actual)
  252. if err == nil {
  253. t.Errorf("QuotaFiles do not match")
  254. }
  255. expected.QuotaFiles = 0
  256. expected.Permissions["/"] = []string{dataprovider.PermCreateDirs}
  257. err = compareEqualsUserFields(expected, actual)
  258. if err == nil {
  259. t.Errorf("Permissions are not equal")
  260. }
  261. expected.Permissions = nil
  262. expected.UploadBandwidth = 64
  263. err = compareEqualsUserFields(expected, actual)
  264. if err == nil {
  265. t.Errorf("UploadBandwidth does not match")
  266. }
  267. expected.UploadBandwidth = 0
  268. expected.DownloadBandwidth = 128
  269. err = compareEqualsUserFields(expected, actual)
  270. if err == nil {
  271. t.Errorf("DownloadBandwidth does not match")
  272. }
  273. expected.DownloadBandwidth = 0
  274. expected.Status = 1
  275. err = compareEqualsUserFields(expected, actual)
  276. if err == nil {
  277. t.Errorf("Status does not match")
  278. }
  279. expected.Status = 0
  280. expected.ExpirationDate = 123
  281. err = compareEqualsUserFields(expected, actual)
  282. if err == nil {
  283. t.Errorf("Expiration date does not match")
  284. }
  285. }
  286. func TestCompareUserFsConfig(t *testing.T) {
  287. expected := &dataprovider.User{}
  288. actual := &dataprovider.User{}
  289. expected.FsConfig.Provider = 1
  290. err := compareUserFsConfig(expected, actual)
  291. if err == nil {
  292. t.Errorf("Provider does not match")
  293. }
  294. expected.FsConfig.Provider = 0
  295. expected.FsConfig.S3Config.Bucket = "bucket"
  296. err = compareUserFsConfig(expected, actual)
  297. if err == nil {
  298. t.Errorf("S3 bucket does not match")
  299. }
  300. expected.FsConfig.S3Config.Bucket = ""
  301. expected.FsConfig.S3Config.Region = "region"
  302. err = compareUserFsConfig(expected, actual)
  303. if err == nil {
  304. t.Errorf("S3 region does not match")
  305. }
  306. expected.FsConfig.S3Config.Region = ""
  307. expected.FsConfig.S3Config.AccessKey = "access key"
  308. err = compareUserFsConfig(expected, actual)
  309. if err == nil {
  310. t.Errorf("S3 access key does not match")
  311. }
  312. expected.FsConfig.S3Config.AccessKey = ""
  313. actual.FsConfig.S3Config.AccessSecret = "access secret"
  314. err = compareUserFsConfig(expected, actual)
  315. if err == nil {
  316. t.Errorf("S3 access secret does not match")
  317. }
  318. secret, _ := utils.EncryptData("access secret")
  319. actual.FsConfig.S3Config.AccessSecret = ""
  320. expected.FsConfig.S3Config.AccessSecret = secret
  321. err = compareUserFsConfig(expected, actual)
  322. if err == nil {
  323. t.Errorf("S3 access secret does not match")
  324. }
  325. expected.FsConfig.S3Config.AccessSecret = utils.RemoveDecryptionKey(secret)
  326. actual.FsConfig.S3Config.AccessSecret = utils.RemoveDecryptionKey(secret) + "a"
  327. err = compareUserFsConfig(expected, actual)
  328. if err == nil {
  329. t.Errorf("S3 access secret does not match")
  330. }
  331. expected.FsConfig.S3Config.AccessSecret = "test"
  332. actual.FsConfig.S3Config.AccessSecret = ""
  333. err = compareUserFsConfig(expected, actual)
  334. if err == nil {
  335. t.Errorf("S3 access secret does not match")
  336. }
  337. expected.FsConfig.S3Config.AccessSecret = ""
  338. actual.FsConfig.S3Config.AccessSecret = ""
  339. expected.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/"
  340. err = compareUserFsConfig(expected, actual)
  341. if err == nil {
  342. t.Errorf("S3 endpoint does not match")
  343. }
  344. expected.FsConfig.S3Config.Endpoint = ""
  345. expected.FsConfig.S3Config.StorageClass = "Standard"
  346. err = compareUserFsConfig(expected, actual)
  347. if err == nil {
  348. t.Errorf("S3 storage class does not match")
  349. }
  350. expected.FsConfig.S3Config.StorageClass = ""
  351. expected.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  352. err = compareUserFsConfig(expected, actual)
  353. if err == nil {
  354. t.Errorf("S3 key prefix does not match")
  355. }
  356. expected.FsConfig.S3Config.KeyPrefix = ""
  357. expected.FsConfig.S3Config.UploadPartSize = 10
  358. err = compareUserFsConfig(expected, actual)
  359. if err == nil {
  360. t.Errorf("S3 upload part size does not match")
  361. }
  362. expected.FsConfig.S3Config.UploadPartSize = 0
  363. expected.FsConfig.S3Config.UploadConcurrency = 3
  364. err = compareUserFsConfig(expected, actual)
  365. if err == nil {
  366. t.Errorf("S3 upload concurrency does not match")
  367. }
  368. }
  369. func TestCompareUserGCSConfig(t *testing.T) {
  370. expected := &dataprovider.User{}
  371. actual := &dataprovider.User{}
  372. expected.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir"
  373. err := compareUserFsConfig(expected, actual)
  374. if err == nil {
  375. t.Errorf("GCS key prefix does not match")
  376. }
  377. expected.FsConfig.GCSConfig.KeyPrefix = ""
  378. expected.FsConfig.GCSConfig.Bucket = "bucket"
  379. err = compareUserFsConfig(expected, actual)
  380. if err == nil {
  381. t.Errorf("GCS bucket does not match")
  382. }
  383. expected.FsConfig.GCSConfig.Bucket = ""
  384. expected.FsConfig.GCSConfig.StorageClass = "Standard"
  385. err = compareUserFsConfig(expected, actual)
  386. if err == nil {
  387. t.Errorf("GCS storage class does not match")
  388. }
  389. expected.FsConfig.GCSConfig.StorageClass = ""
  390. expected.FsConfig.GCSConfig.AutomaticCredentials = 1
  391. err = compareUserFsConfig(expected, actual)
  392. if err == nil {
  393. t.Errorf("GCS automatic credentials does not match")
  394. }
  395. expected.FsConfig.GCSConfig.AutomaticCredentials = 0
  396. }
  397. func TestGCSWebInvalidFormFile(t *testing.T) {
  398. form := make(url.Values)
  399. form.Set("username", "test_username")
  400. form.Set("fs_provider", "2")
  401. req, _ := http.NewRequest(http.MethodPost, webUserPath, strings.NewReader(form.Encode()))
  402. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  403. req.ParseForm()
  404. _, err := getFsConfigFromUserPostFields(req)
  405. if err != http.ErrNotMultipart {
  406. t.Errorf("unexpected error: %v", err)
  407. }
  408. }
  409. func TestApiCallsWithBadURL(t *testing.T) {
  410. oldBaseURL := httpBaseURL
  411. oldAuthUsername := authUsername
  412. oldAuthPassword := authPassword
  413. SetBaseURLAndCredentials(invalidURL, oldAuthUsername, oldAuthPassword)
  414. u := dataprovider.User{}
  415. _, _, err := UpdateUser(u, http.StatusBadRequest)
  416. if err == nil {
  417. t.Error("request with invalid URL must fail")
  418. }
  419. _, err = RemoveUser(u, http.StatusNotFound)
  420. if err == nil {
  421. t.Error("request with invalid URL must fail")
  422. }
  423. _, _, err = GetUsers(1, 0, "", http.StatusBadRequest)
  424. if err == nil {
  425. t.Error("request with invalid URL must fail")
  426. }
  427. _, err = CloseConnection("non_existent_id", http.StatusNotFound)
  428. if err == nil {
  429. t.Error("request with invalid URL must fail")
  430. }
  431. _, _, err = Dumpdata("backup.json", "", http.StatusBadRequest)
  432. if err == nil {
  433. t.Error("request with invalid URL must fail")
  434. }
  435. _, _, err = Loaddata("/tmp/backup.json", "", "", http.StatusBadRequest)
  436. if err == nil {
  437. t.Error("request with invalid URL must fail")
  438. }
  439. SetBaseURLAndCredentials(oldBaseURL, oldAuthUsername, oldAuthPassword)
  440. }
  441. func TestApiCallToNotListeningServer(t *testing.T) {
  442. oldBaseURL := httpBaseURL
  443. oldAuthUsername := authUsername
  444. oldAuthPassword := authPassword
  445. SetBaseURLAndCredentials(inactiveURL, oldAuthUsername, oldAuthPassword)
  446. u := dataprovider.User{}
  447. _, _, err := AddUser(u, http.StatusBadRequest)
  448. if err == nil {
  449. t.Errorf("request to an inactive URL must fail")
  450. }
  451. _, _, err = UpdateUser(u, http.StatusNotFound)
  452. if err == nil {
  453. t.Errorf("request to an inactive URL must fail")
  454. }
  455. _, err = RemoveUser(u, http.StatusNotFound)
  456. if err == nil {
  457. t.Errorf("request to an inactive URL must fail")
  458. }
  459. _, _, err = GetUserByID(-1, http.StatusNotFound)
  460. if err == nil {
  461. t.Errorf("request to an inactive URL must fail")
  462. }
  463. _, _, err = GetUsers(100, 0, "", http.StatusOK)
  464. if err == nil {
  465. t.Errorf("request to an inactive URL must fail")
  466. }
  467. _, _, err = GetQuotaScans(http.StatusOK)
  468. if err == nil {
  469. t.Errorf("request to an inactive URL must fail")
  470. }
  471. _, err = StartQuotaScan(u, http.StatusNotFound)
  472. if err == nil {
  473. t.Errorf("request to an inactive URL must fail")
  474. }
  475. _, _, err = GetConnections(http.StatusOK)
  476. if err == nil {
  477. t.Errorf("request to an inactive URL must fail")
  478. }
  479. _, err = CloseConnection("non_existent_id", http.StatusNotFound)
  480. if err == nil {
  481. t.Errorf("request to an inactive URL must fail")
  482. }
  483. _, _, err = GetVersion(http.StatusOK)
  484. if err == nil {
  485. t.Errorf("request to an inactive URL must fail")
  486. }
  487. _, _, err = GetProviderStatus(http.StatusOK)
  488. if err == nil {
  489. t.Errorf("request to an inactive URL must fail")
  490. }
  491. _, _, err = Dumpdata("backup.json", "0", http.StatusOK)
  492. if err == nil {
  493. t.Errorf("request to an inactive URL must fail")
  494. }
  495. _, _, err = Loaddata("/tmp/backup.json", "", "", http.StatusOK)
  496. if err == nil {
  497. t.Errorf("request to an inactive URL must fail")
  498. }
  499. SetBaseURLAndCredentials(oldBaseURL, oldAuthUsername, oldAuthPassword)
  500. }
  501. func TestBasicAuth(t *testing.T) {
  502. oldAuthUsername := authUsername
  503. oldAuthPassword := authPassword
  504. authUserFile := filepath.Join(os.TempDir(), "http_users.txt")
  505. authUserData := []byte("test1:$2y$05$bcHSED7aO1cfLto6ZdDBOOKzlwftslVhtpIkRhAtSa4GuLmk5mola\n")
  506. ioutil.WriteFile(authUserFile, authUserData, 0666)
  507. httpAuth, _ = newBasicAuthProvider(authUserFile)
  508. _, _, err := GetVersion(http.StatusUnauthorized)
  509. if err != nil {
  510. t.Errorf("unexpected error: %v", err)
  511. }
  512. SetBaseURLAndCredentials(httpBaseURL, "test1", "password1")
  513. _, _, err = GetVersion(http.StatusOK)
  514. if err != nil {
  515. t.Errorf("unexpected error: %v", err)
  516. }
  517. SetBaseURLAndCredentials(httpBaseURL, "test1", "wrong_password")
  518. resp, _ := sendHTTPRequest(http.MethodGet, buildURLRelativeToBase(metricsPath), nil, "")
  519. defer resp.Body.Close()
  520. if resp.StatusCode != http.StatusUnauthorized {
  521. t.Errorf("request with wrong password must fail, status code: %v", resp.StatusCode)
  522. }
  523. authUserData = append(authUserData, []byte("test2:$apr1$gLnIkRIf$Xr/6aJfmIrihP4b2N2tcs/\n")...)
  524. ioutil.WriteFile(authUserFile, authUserData, 0666)
  525. SetBaseURLAndCredentials(httpBaseURL, "test2", "password2")
  526. _, _, err = GetVersion(http.StatusOK)
  527. if err != nil {
  528. t.Errorf("unexpected error: %v", err)
  529. }
  530. SetBaseURLAndCredentials(httpBaseURL, "test2", "wrong_password")
  531. _, _, err = GetVersion(http.StatusOK)
  532. if err == nil {
  533. t.Error("request with wrong password must fail")
  534. }
  535. authUserData = append(authUserData, []byte("test3:$apr1$gLnIkRIf$Xr/6$aJfmIr$ihP4b2N2tcs/\n")...)
  536. ioutil.WriteFile(authUserFile, authUserData, 0666)
  537. SetBaseURLAndCredentials(httpBaseURL, "test3", "wrong_password")
  538. _, _, err = GetVersion(http.StatusUnauthorized)
  539. if err != nil {
  540. t.Errorf("unexpected error: %v", err)
  541. }
  542. authUserData = append(authUserData, []byte("test4:$invalid$gLnIkRIf$Xr/6$aJfmIr$ihP4b2N2tcs/\n")...)
  543. ioutil.WriteFile(authUserFile, authUserData, 0666)
  544. SetBaseURLAndCredentials(httpBaseURL, "test3", "password2")
  545. _, _, err = GetVersion(http.StatusUnauthorized)
  546. if err != nil {
  547. t.Errorf("unexpected error: %v", err)
  548. }
  549. if runtime.GOOS != "windows" {
  550. authUserData = append(authUserData, []byte("test5:$apr1$gLnIkRIf$Xr/6aJfmIrihP4b2N2tcs/\n")...)
  551. ioutil.WriteFile(authUserFile, authUserData, 0666)
  552. os.Chmod(authUserFile, 0001)
  553. SetBaseURLAndCredentials(httpBaseURL, "test5", "password2")
  554. _, _, err = GetVersion(http.StatusUnauthorized)
  555. if err != nil {
  556. t.Errorf("unexpected error: %v", err)
  557. }
  558. os.Chmod(authUserFile, 0666)
  559. }
  560. authUserData = append(authUserData, []byte("\"foo\"bar\"\r\n")...)
  561. ioutil.WriteFile(authUserFile, authUserData, 0666)
  562. SetBaseURLAndCredentials(httpBaseURL, "test2", "password2")
  563. _, _, err = GetVersion(http.StatusUnauthorized)
  564. if err != nil {
  565. t.Errorf("unexpected error: %v", err)
  566. }
  567. os.Remove(authUserFile)
  568. SetBaseURLAndCredentials(httpBaseURL, oldAuthUsername, oldAuthPassword)
  569. httpAuth, _ = newBasicAuthProvider("")
  570. }
  571. func TestCloseConnectionHandler(t *testing.T) {
  572. req, _ := http.NewRequest(http.MethodDelete, activeConnectionsPath+"/connectionID", nil)
  573. rctx := chi.NewRouteContext()
  574. rctx.URLParams.Add("connectionID", "")
  575. req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
  576. rr := httptest.NewRecorder()
  577. handleCloseConnection(rr, req)
  578. if rr.Code != http.StatusBadRequest {
  579. t.Errorf("Expected response code 400. Got %d", rr.Code)
  580. }
  581. }
  582. func TestRenderInvalidTemplate(t *testing.T) {
  583. tmpl, err := template.New("test").Parse("{{.Count}}")
  584. if err != nil {
  585. t.Errorf("error making test template: %v", err)
  586. } else {
  587. templates["no_match"] = tmpl
  588. rw := httptest.NewRecorder()
  589. renderTemplate(rw, "no_match", map[string]string{})
  590. if rw.Code != http.StatusInternalServerError {
  591. t.Errorf("invalid template rendering must fail")
  592. }
  593. }
  594. }
  595. func TestQuotaScanInvalidFs(t *testing.T) {
  596. user := dataprovider.User{
  597. Username: "test",
  598. HomeDir: os.TempDir(),
  599. FsConfig: dataprovider.Filesystem{
  600. Provider: 1,
  601. },
  602. }
  603. sftpd.AddQuotaScan(user.Username)
  604. err := doQuotaScan(user)
  605. if err == nil {
  606. t.Error("quota scan with bad fs must fail")
  607. }
  608. }