api_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. package api_test
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "net/http"
  8. "net/http/httptest"
  9. "os"
  10. "path/filepath"
  11. "runtime"
  12. "strconv"
  13. "testing"
  14. "time"
  15. "github.com/go-chi/render"
  16. _ "github.com/go-sql-driver/mysql"
  17. _ "github.com/lib/pq"
  18. _ "github.com/mattn/go-sqlite3"
  19. "github.com/rs/zerolog"
  20. "github.com/drakkan/sftpgo/api"
  21. "github.com/drakkan/sftpgo/config"
  22. "github.com/drakkan/sftpgo/dataprovider"
  23. "github.com/drakkan/sftpgo/logger"
  24. "github.com/drakkan/sftpgo/sftpd"
  25. )
  26. const (
  27. defaultUsername = "test_user"
  28. defaultPassword = "test_password"
  29. testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  30. logSender = "APITesting"
  31. userPath = "/api/v1/user"
  32. activeConnectionsPath = "/api/v1/sftp_connection"
  33. quotaScanPath = "/api/v1/quota_scan"
  34. )
  35. var (
  36. defaultPerms = []string{dataprovider.PermAny}
  37. homeBasePath string
  38. testServer *httptest.Server
  39. )
  40. func TestMain(m *testing.M) {
  41. if runtime.GOOS == "windows" {
  42. homeBasePath = "C:\\"
  43. } else {
  44. homeBasePath = "/tmp"
  45. }
  46. configDir := ".."
  47. logfilePath := filepath.Join(configDir, "sftpgo_api_test.log")
  48. confName := "sftpgo.conf"
  49. logger.InitLogger(logfilePath, zerolog.DebugLevel)
  50. configFilePath := filepath.Join(configDir, confName)
  51. config.LoadConfig(configFilePath)
  52. providerConf := config.GetProviderConf()
  53. err := dataprovider.Initialize(providerConf, configDir)
  54. if err != nil {
  55. logger.Warn(logSender, "error initializing data provider: %v", err)
  56. os.Exit(1)
  57. }
  58. dataProvider := dataprovider.GetProvider()
  59. httpdConf := config.GetHTTPDConfig()
  60. router := api.GetHTTPRouter()
  61. httpdConf.BindPort = 8081
  62. api.SetBaseURL("http://127.0.0.1:8081")
  63. sftpd.SetDataProvider(dataProvider)
  64. api.SetDataProvider(dataProvider)
  65. go func() {
  66. logger.Debug(logSender, "initializing HTTP server with config %+v", httpdConf)
  67. s := &http.Server{
  68. Addr: fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort),
  69. Handler: router,
  70. ReadTimeout: 300 * time.Second,
  71. WriteTimeout: 300 * time.Second,
  72. MaxHeaderBytes: 1 << 20, // 1MB
  73. }
  74. if err := s.ListenAndServe(); err != nil {
  75. logger.Error(logSender, "could not start HTTP server: %v", err)
  76. }
  77. }()
  78. testServer = httptest.NewServer(api.GetHTTPRouter())
  79. defer testServer.Close()
  80. waitTCPListening(fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort))
  81. exitCode := m.Run()
  82. os.Remove(logfilePath)
  83. os.Exit(exitCode)
  84. }
  85. func waitTCPListening(address string) {
  86. for {
  87. conn, err := net.Dial("tcp", address)
  88. if err != nil {
  89. fmt.Printf("tcp server %v not listening: %v\n", address, err)
  90. time.Sleep(100 * time.Millisecond)
  91. continue
  92. }
  93. fmt.Printf("tcp server %v now listening\n", address)
  94. defer conn.Close()
  95. break
  96. }
  97. }
  98. func getTestUser() dataprovider.User {
  99. return dataprovider.User{
  100. Username: defaultUsername,
  101. Password: defaultPassword,
  102. HomeDir: filepath.Join(homeBasePath, defaultUsername),
  103. Permissions: defaultPerms,
  104. }
  105. }
  106. func getUserAsJSON(t *testing.T, user dataprovider.User) []byte {
  107. json, err := json.Marshal(user)
  108. if err != nil {
  109. t.Errorf("error get user as json: %v", err)
  110. return []byte("{}")
  111. }
  112. return json
  113. }
  114. func executeRequest(req *http.Request) *httptest.ResponseRecorder {
  115. rr := httptest.NewRecorder()
  116. testServer.Config.Handler.ServeHTTP(rr, req)
  117. return rr
  118. }
  119. func checkResponseCode(t *testing.T, expected, actual int) {
  120. if expected != actual {
  121. t.Errorf("Expected response code %d. Got %d", expected, actual)
  122. }
  123. }
  124. func TestBasicUserHandling(t *testing.T) {
  125. user, err := api.AddUser(getTestUser(), http.StatusOK)
  126. if err != nil {
  127. t.Errorf("unable to add user: %v", err)
  128. }
  129. user.MaxSessions = 10
  130. user.QuotaSize = 4096
  131. user.QuotaFiles = 2
  132. user.UploadBandwidth = 128
  133. user.DownloadBandwidth = 64
  134. user, err = api.UpdateUser(user, http.StatusOK)
  135. if err != nil {
  136. t.Errorf("unable to update user: %v", err)
  137. }
  138. users, err := api.GetUsers(0, 0, defaultUsername, http.StatusOK)
  139. if err != nil {
  140. t.Errorf("unable to get users: %v", err)
  141. }
  142. if len(users) != 1 {
  143. t.Errorf("number of users mismatch, expected: 1, actual: %v", len(users))
  144. }
  145. err = api.RemoveUser(user, http.StatusOK)
  146. if err != nil {
  147. t.Errorf("unable to remove: %v", err)
  148. }
  149. }
  150. func TestAddUserNoCredentials(t *testing.T) {
  151. u := getTestUser()
  152. u.Password = ""
  153. u.PublicKey = ""
  154. _, err := api.AddUser(u, http.StatusBadRequest)
  155. if err != nil {
  156. t.Errorf("unexpected error adding user with no credentials: %v", err)
  157. }
  158. }
  159. func TestAddUserNoUsername(t *testing.T) {
  160. u := getTestUser()
  161. u.Username = ""
  162. _, err := api.AddUser(u, http.StatusBadRequest)
  163. if err != nil {
  164. t.Errorf("unexpected error adding user with no home dir: %v", err)
  165. }
  166. }
  167. func TestAddUserNoHomeDir(t *testing.T) {
  168. u := getTestUser()
  169. u.HomeDir = ""
  170. _, err := api.AddUser(u, http.StatusBadRequest)
  171. if err != nil {
  172. t.Errorf("unexpected error adding user with no home dir: %v", err)
  173. }
  174. }
  175. func TestAddUserInvalidHomeDir(t *testing.T) {
  176. u := getTestUser()
  177. u.HomeDir = "relative_path"
  178. _, err := api.AddUser(u, http.StatusBadRequest)
  179. if err != nil {
  180. t.Errorf("unexpected error adding user with invalid home dir: %v", err)
  181. }
  182. }
  183. func TestAddUserNoPerms(t *testing.T) {
  184. u := getTestUser()
  185. u.Permissions = []string{}
  186. _, err := api.AddUser(u, http.StatusBadRequest)
  187. if err != nil {
  188. t.Errorf("unexpected error adding user with no perms: %v", err)
  189. }
  190. }
  191. func TestAddUserInvalidPerms(t *testing.T) {
  192. u := getTestUser()
  193. u.Permissions = []string{"invalidPerm"}
  194. _, err := api.AddUser(u, http.StatusBadRequest)
  195. if err != nil {
  196. t.Errorf("unexpected error adding user with no perms: %v", err)
  197. }
  198. }
  199. func TestUpdateUser(t *testing.T) {
  200. user, err := api.AddUser(getTestUser(), http.StatusOK)
  201. if err != nil {
  202. t.Errorf("unable to add user: %v", err)
  203. }
  204. user.HomeDir = filepath.Join(homeBasePath, "testmod")
  205. user.UID = 33
  206. user.GID = 101
  207. user.MaxSessions = 10
  208. user.QuotaSize = 4096
  209. user.QuotaFiles = 2
  210. user.Permissions = []string{dataprovider.PermCreateDirs, dataprovider.PermDelete, dataprovider.PermDownload}
  211. user.UploadBandwidth = 1024
  212. user.DownloadBandwidth = 512
  213. user, err = api.UpdateUser(user, http.StatusOK)
  214. if err != nil {
  215. t.Errorf("unable to update user: %v", err)
  216. }
  217. err = api.RemoveUser(user, http.StatusOK)
  218. if err != nil {
  219. t.Errorf("unable to remove: %v", err)
  220. }
  221. }
  222. func TestUpdateUserNoCredentials(t *testing.T) {
  223. user, err := api.AddUser(getTestUser(), http.StatusOK)
  224. if err != nil {
  225. t.Errorf("unable to add user: %v", err)
  226. }
  227. user.Password = ""
  228. user.PublicKey = ""
  229. // password and public key will be omitted from json serialization if empty and so they will remain unchanged
  230. // and no validation error will be raised
  231. _, err = api.UpdateUser(user, http.StatusOK)
  232. if err != nil {
  233. t.Errorf("unexpected error updating user with no credentials: %v", err)
  234. }
  235. err = api.RemoveUser(user, http.StatusOK)
  236. if err != nil {
  237. t.Errorf("unable to remove: %v", err)
  238. }
  239. }
  240. func TestUpdateUserEmptyHomeDir(t *testing.T) {
  241. user, err := api.AddUser(getTestUser(), http.StatusOK)
  242. if err != nil {
  243. t.Errorf("unable to add user: %v", err)
  244. }
  245. user.HomeDir = ""
  246. _, err = api.UpdateUser(user, http.StatusBadRequest)
  247. if err != nil {
  248. t.Errorf("unexpected error updating user with empty home dir: %v", err)
  249. }
  250. err = api.RemoveUser(user, http.StatusOK)
  251. if err != nil {
  252. t.Errorf("unable to remove: %v", err)
  253. }
  254. }
  255. func TestUpdateUserInvalidHomeDir(t *testing.T) {
  256. user, err := api.AddUser(getTestUser(), http.StatusOK)
  257. if err != nil {
  258. t.Errorf("unable to add user: %v", err)
  259. }
  260. user.HomeDir = "relative_path"
  261. _, err = api.UpdateUser(user, http.StatusBadRequest)
  262. if err != nil {
  263. t.Errorf("unexpected error updating user with empty home dir: %v", err)
  264. }
  265. err = api.RemoveUser(user, http.StatusOK)
  266. if err != nil {
  267. t.Errorf("unable to remove: %v", err)
  268. }
  269. }
  270. func TestUpdateNonExistentUser(t *testing.T) {
  271. _, err := api.UpdateUser(getTestUser(), http.StatusNotFound)
  272. if err != nil {
  273. t.Errorf("unable to update user: %v", err)
  274. }
  275. }
  276. func TestGetNonExistentUser(t *testing.T) {
  277. _, err := api.GetUserByID(0, http.StatusNotFound)
  278. if err != nil {
  279. t.Errorf("unable to get user: %v", err)
  280. }
  281. }
  282. func TestDeleteNonExistentUser(t *testing.T) {
  283. err := api.RemoveUser(getTestUser(), http.StatusNotFound)
  284. if err != nil {
  285. t.Errorf("unable to remove user: %v", err)
  286. }
  287. }
  288. func TestAddDuplicateUser(t *testing.T) {
  289. user, err := api.AddUser(getTestUser(), http.StatusOK)
  290. if err != nil {
  291. t.Errorf("unable to add user: %v", err)
  292. }
  293. _, err = api.AddUser(getTestUser(), http.StatusInternalServerError)
  294. if err != nil {
  295. t.Errorf("unable to add second user: %v", err)
  296. }
  297. err = api.RemoveUser(user, http.StatusOK)
  298. if err != nil {
  299. t.Errorf("unable to remove user: %v", err)
  300. }
  301. }
  302. func TestGetUsers(t *testing.T) {
  303. user1, err := api.AddUser(getTestUser(), http.StatusOK)
  304. if err != nil {
  305. t.Errorf("unable to add user: %v", err)
  306. }
  307. u := getTestUser()
  308. u.Username = defaultUsername + "1"
  309. user2, err := api.AddUser(u, http.StatusOK)
  310. if err != nil {
  311. t.Errorf("unable to add second user: %v", err)
  312. }
  313. users, err := api.GetUsers(0, 0, "", http.StatusOK)
  314. if err != nil {
  315. t.Errorf("unable to get users: %v", err)
  316. }
  317. if len(users) < 2 {
  318. t.Errorf("at least 2 users are expected")
  319. }
  320. users, err = api.GetUsers(1, 0, "", http.StatusOK)
  321. if err != nil {
  322. t.Errorf("unable to get users: %v", err)
  323. }
  324. if len(users) != 1 {
  325. t.Errorf("1 user is expected")
  326. }
  327. users, err = api.GetUsers(1, 1, "", http.StatusOK)
  328. if err != nil {
  329. t.Errorf("unable to get users: %v", err)
  330. }
  331. if len(users) != 1 {
  332. t.Errorf("1 user is expected")
  333. }
  334. err = api.RemoveUser(user1, http.StatusOK)
  335. if err != nil {
  336. t.Errorf("unable to remove user: %v", err)
  337. }
  338. err = api.RemoveUser(user2, http.StatusOK)
  339. if err != nil {
  340. t.Errorf("unable to remove user: %v", err)
  341. }
  342. }
  343. func TestGetQuotaScans(t *testing.T) {
  344. _, err := api.GetQuotaScans(http.StatusOK)
  345. if err != nil {
  346. t.Errorf("unable to get quota scans: %v", err)
  347. }
  348. }
  349. func TestStartQuotaScan(t *testing.T) {
  350. user, err := api.AddUser(getTestUser(), http.StatusOK)
  351. if err != nil {
  352. t.Errorf("unable to add user: %v", err)
  353. }
  354. err = api.StartQuotaScan(user, http.StatusCreated)
  355. if err != nil {
  356. t.Errorf("unable to start quota scan: %v", err)
  357. }
  358. err = api.RemoveUser(user, http.StatusOK)
  359. if err != nil {
  360. t.Errorf("unable to remove user: %v", err)
  361. }
  362. }
  363. // test using mock http server
  364. func TestBasicUserHandlingMock(t *testing.T) {
  365. user := getTestUser()
  366. userAsJSON := getUserAsJSON(t, user)
  367. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  368. rr := executeRequest(req)
  369. checkResponseCode(t, http.StatusOK, rr.Code)
  370. err := render.DecodeJSON(rr.Body, &user)
  371. if err != nil {
  372. t.Errorf("Error get user: %v", err)
  373. }
  374. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  375. rr = executeRequest(req)
  376. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  377. user.MaxSessions = 10
  378. user.UploadBandwidth = 128
  379. userAsJSON = getUserAsJSON(t, user)
  380. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  381. rr = executeRequest(req)
  382. checkResponseCode(t, http.StatusOK, rr.Code)
  383. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  384. rr = executeRequest(req)
  385. checkResponseCode(t, http.StatusOK, rr.Code)
  386. var updatedUser dataprovider.User
  387. err = render.DecodeJSON(rr.Body, &updatedUser)
  388. if err != nil {
  389. t.Errorf("Error decoding updated user: %v", err)
  390. }
  391. if user.MaxSessions != updatedUser.MaxSessions || user.UploadBandwidth != updatedUser.UploadBandwidth {
  392. t.Errorf("Error modifying user actual: %v, %v", updatedUser.MaxSessions, updatedUser.UploadBandwidth)
  393. }
  394. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  395. rr = executeRequest(req)
  396. checkResponseCode(t, http.StatusOK, rr.Code)
  397. }
  398. func TestGetUserByIdInvalidParamsMock(t *testing.T) {
  399. req, _ := http.NewRequest(http.MethodGet, userPath+"/0", nil)
  400. rr := executeRequest(req)
  401. checkResponseCode(t, http.StatusNotFound, rr.Code)
  402. req, _ = http.NewRequest(http.MethodGet, userPath+"/a", nil)
  403. rr = executeRequest(req)
  404. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  405. }
  406. func TestAddUserNoUsernameMock(t *testing.T) {
  407. user := getTestUser()
  408. user.Username = ""
  409. userAsJSON := getUserAsJSON(t, user)
  410. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  411. rr := executeRequest(req)
  412. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  413. }
  414. func TestAddUserInvalidHomeDirMock(t *testing.T) {
  415. user := getTestUser()
  416. user.HomeDir = "relative_path"
  417. userAsJSON := getUserAsJSON(t, user)
  418. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  419. rr := executeRequest(req)
  420. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  421. }
  422. func TestAddUserInvalidPermsMock(t *testing.T) {
  423. user := getTestUser()
  424. user.Permissions = []string{}
  425. userAsJSON := getUserAsJSON(t, user)
  426. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  427. rr := executeRequest(req)
  428. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  429. }
  430. func TestAddUserInvalidJsonMock(t *testing.T) {
  431. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer([]byte("invalid json")))
  432. rr := executeRequest(req)
  433. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  434. }
  435. func TestUpdateUserInvalidJsonMock(t *testing.T) {
  436. user := getTestUser()
  437. userAsJSON := getUserAsJSON(t, user)
  438. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  439. rr := executeRequest(req)
  440. checkResponseCode(t, http.StatusOK, rr.Code)
  441. err := render.DecodeJSON(rr.Body, &user)
  442. if err != nil {
  443. t.Errorf("Error get user: %v", err)
  444. }
  445. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer([]byte("Invalid json")))
  446. rr = executeRequest(req)
  447. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  448. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  449. rr = executeRequest(req)
  450. checkResponseCode(t, http.StatusOK, rr.Code)
  451. }
  452. func TestUpdateUserInvalidParamsMock(t *testing.T) {
  453. user := getTestUser()
  454. userAsJSON := getUserAsJSON(t, user)
  455. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  456. rr := executeRequest(req)
  457. checkResponseCode(t, http.StatusOK, rr.Code)
  458. err := render.DecodeJSON(rr.Body, &user)
  459. if err != nil {
  460. t.Errorf("Error get user: %v", err)
  461. }
  462. user.HomeDir = ""
  463. userAsJSON = getUserAsJSON(t, user)
  464. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  465. rr = executeRequest(req)
  466. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  467. userID := user.ID
  468. user.ID = 0
  469. userAsJSON = getUserAsJSON(t, user)
  470. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(userID, 10), bytes.NewBuffer(userAsJSON))
  471. rr = executeRequest(req)
  472. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  473. user.ID = userID
  474. req, _ = http.NewRequest(http.MethodPut, userPath+"/0", bytes.NewBuffer(userAsJSON))
  475. rr = executeRequest(req)
  476. checkResponseCode(t, http.StatusNotFound, rr.Code)
  477. req, _ = http.NewRequest(http.MethodPut, userPath+"/a", bytes.NewBuffer(userAsJSON))
  478. rr = executeRequest(req)
  479. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  480. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  481. rr = executeRequest(req)
  482. checkResponseCode(t, http.StatusOK, rr.Code)
  483. }
  484. func TestGetUsersMock(t *testing.T) {
  485. user := getTestUser()
  486. userAsJSON := getUserAsJSON(t, user)
  487. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  488. rr := executeRequest(req)
  489. checkResponseCode(t, http.StatusOK, rr.Code)
  490. err := render.DecodeJSON(rr.Body, &user)
  491. if err != nil {
  492. t.Errorf("Error get user: %v", err)
  493. }
  494. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=510&offset=0&order=ASC&username="+defaultUsername, nil)
  495. rr = executeRequest(req)
  496. checkResponseCode(t, http.StatusOK, rr.Code)
  497. var users []dataprovider.User
  498. err = render.DecodeJSON(rr.Body, &users)
  499. if err != nil {
  500. t.Errorf("Error decoding users: %v", err)
  501. }
  502. if len(users) != 1 {
  503. t.Errorf("1 user is expected")
  504. }
  505. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=a&offset=0&order=ASC", nil)
  506. rr = executeRequest(req)
  507. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  508. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=a&order=ASC", nil)
  509. rr = executeRequest(req)
  510. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  511. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASCa", nil)
  512. rr = executeRequest(req)
  513. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  514. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  515. rr = executeRequest(req)
  516. checkResponseCode(t, http.StatusOK, rr.Code)
  517. }
  518. func TestDeleteUserInvalidParamsMock(t *testing.T) {
  519. req, _ := http.NewRequest(http.MethodDelete, userPath+"/0", nil)
  520. rr := executeRequest(req)
  521. checkResponseCode(t, http.StatusNotFound, rr.Code)
  522. req, _ = http.NewRequest(http.MethodDelete, userPath+"/a", nil)
  523. rr = executeRequest(req)
  524. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  525. }
  526. func TestGetQuotaScansMock(t *testing.T) {
  527. req, err := http.NewRequest("GET", quotaScanPath, nil)
  528. if err != nil {
  529. t.Errorf("error get quota scan: %v", err)
  530. }
  531. rr := executeRequest(req)
  532. checkResponseCode(t, http.StatusOK, rr.Code)
  533. }
  534. func TestStartQuotaScanMock(t *testing.T) {
  535. user := getTestUser()
  536. userAsJSON := getUserAsJSON(t, user)
  537. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  538. rr := executeRequest(req)
  539. checkResponseCode(t, http.StatusOK, rr.Code)
  540. err := render.DecodeJSON(rr.Body, &user)
  541. if err != nil {
  542. t.Errorf("Error get user: %v", err)
  543. }
  544. _, err = os.Stat(user.HomeDir)
  545. if err == nil {
  546. os.Remove(user.HomeDir)
  547. }
  548. userAsJSON = getUserAsJSON(t, user)
  549. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  550. rr = executeRequest(req)
  551. checkResponseCode(t, http.StatusCreated, rr.Code)
  552. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  553. rr = executeRequest(req)
  554. checkResponseCode(t, http.StatusOK, rr.Code)
  555. var scans []sftpd.ActiveQuotaScan
  556. err = render.DecodeJSON(rr.Body, &scans)
  557. if err != nil {
  558. t.Errorf("Error get active scans: %v", err)
  559. }
  560. for len(scans) > 0 {
  561. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  562. rr = executeRequest(req)
  563. checkResponseCode(t, http.StatusOK, rr.Code)
  564. err = render.DecodeJSON(rr.Body, &scans)
  565. if err != nil {
  566. t.Errorf("Error get active scans: %v", err)
  567. break
  568. }
  569. }
  570. _, err = os.Stat(user.HomeDir)
  571. if err != nil && os.IsNotExist(err) {
  572. os.MkdirAll(user.HomeDir, 0777)
  573. }
  574. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  575. rr = executeRequest(req)
  576. checkResponseCode(t, http.StatusCreated, rr.Code)
  577. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  578. rr = executeRequest(req)
  579. checkResponseCode(t, http.StatusOK, rr.Code)
  580. }
  581. func TestStartQuotaScanBadUserMock(t *testing.T) {
  582. user := getTestUser()
  583. userAsJSON := getUserAsJSON(t, user)
  584. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  585. rr := executeRequest(req)
  586. checkResponseCode(t, http.StatusNotFound, rr.Code)
  587. }
  588. func TestStartQuotaScanNonExistentUserMock(t *testing.T) {
  589. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer([]byte("invalid json")))
  590. rr := executeRequest(req)
  591. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  592. }
  593. func TestGetSFTPConnectionsMock(t *testing.T) {
  594. req, _ := http.NewRequest(http.MethodGet, activeConnectionsPath, nil)
  595. rr := executeRequest(req)
  596. checkResponseCode(t, http.StatusOK, rr.Code)
  597. }
  598. func TestDeleteActiveConnectionMock(t *testing.T) {
  599. req, _ := http.NewRequest(http.MethodDelete, activeConnectionsPath+"/connectionID", nil)
  600. rr := executeRequest(req)
  601. checkResponseCode(t, http.StatusNotFound, rr.Code)
  602. }
  603. func TestNotFoundMock(t *testing.T) {
  604. req, _ := http.NewRequest(http.MethodGet, "/non/existing/path", nil)
  605. rr := executeRequest(req)
  606. checkResponseCode(t, http.StatusNotFound, rr.Code)
  607. }
  608. func TestMethodNotAllowedMock(t *testing.T) {
  609. req, _ := http.NewRequest(http.MethodPost, activeConnectionsPath, nil)
  610. rr := executeRequest(req)
  611. checkResponseCode(t, http.StatusMethodNotAllowed, rr.Code)
  612. }