httpd_test.go 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324
  1. package httpd_test
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/base64"
  6. "encoding/json"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "mime/multipart"
  11. "net"
  12. "net/http"
  13. "net/http/httptest"
  14. "net/url"
  15. "os"
  16. "path/filepath"
  17. "runtime"
  18. "strconv"
  19. "strings"
  20. "testing"
  21. "time"
  22. "github.com/go-chi/render"
  23. _ "github.com/go-sql-driver/mysql"
  24. _ "github.com/lib/pq"
  25. _ "github.com/mattn/go-sqlite3"
  26. "github.com/rs/zerolog"
  27. "github.com/drakkan/sftpgo/config"
  28. "github.com/drakkan/sftpgo/dataprovider"
  29. "github.com/drakkan/sftpgo/httpd"
  30. "github.com/drakkan/sftpgo/logger"
  31. "github.com/drakkan/sftpgo/sftpd"
  32. "github.com/drakkan/sftpgo/utils"
  33. "github.com/drakkan/sftpgo/vfs"
  34. )
  35. const (
  36. defaultUsername = "test_user"
  37. defaultPassword = "test_password"
  38. testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  39. logSender = "APITesting"
  40. userPath = "/api/v1/user"
  41. activeConnectionsPath = "/api/v1/connection"
  42. quotaScanPath = "/api/v1/quota_scan"
  43. versionPath = "/api/v1/version"
  44. providerStatusPath = "/api/v1/providerstatus"
  45. dumpDataPath = "/api/v1/dumpdata"
  46. loadDataPath = "/api/v1/loaddata"
  47. metricsPath = "/metrics"
  48. webBasePath = "/web"
  49. webUsersPath = "/web/users"
  50. webUserPath = "/web/user"
  51. webConnectionsPath = "/web/connections"
  52. configDir = ".."
  53. httpsCert = `-----BEGIN CERTIFICATE-----
  54. MIICHTCCAaKgAwIBAgIUHnqw7QnB1Bj9oUsNpdb+ZkFPOxMwCgYIKoZIzj0EAwIw
  55. RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
  56. dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDAyMDQwOTUzMDRaFw0zMDAyMDEw
  57. OTUzMDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
  58. VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
  59. IgNiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVqWvrJ51t5OxV0v25NsOgR82CA
  60. NXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIVCzgWkxiz7XE4lgUwX44FCXZM
  61. 3+JeUbKjUzBRMB0GA1UdDgQWBBRhLw+/o3+Z02MI/d4tmaMui9W16jAfBgNVHSME
  62. GDAWgBRhLw+/o3+Z02MI/d4tmaMui9W16jAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
  63. SM49BAMCA2kAMGYCMQDqLt2lm8mE+tGgtjDmtFgdOcI72HSbRQ74D5rYTzgST1rY
  64. /8wTi5xl8TiFUyLMUsICMQC5ViVxdXbhuG7gX6yEqSkMKZICHpO8hqFwOD/uaFVI
  65. dV4vKmHUzwK/eIx+8Ay3neE=
  66. -----END CERTIFICATE-----`
  67. httpsKey = `-----BEGIN EC PARAMETERS-----
  68. BgUrgQQAIg==
  69. -----END EC PARAMETERS-----
  70. -----BEGIN EC PRIVATE KEY-----
  71. MIGkAgEBBDCfMNsN6miEE3rVyUPwElfiJSWaR5huPCzUenZOfJT04GAcQdWvEju3
  72. UM2lmBLIXpGgBwYFK4EEACKhZANiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVq
  73. WvrJ51t5OxV0v25NsOgR82CANXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIV
  74. CzgWkxiz7XE4lgUwX44FCXZM3+JeUbI=
  75. -----END EC PRIVATE KEY-----`
  76. )
  77. var (
  78. defaultPerms = []string{dataprovider.PermAny}
  79. homeBasePath string
  80. backupsPath string
  81. credentialsPath string
  82. testServer *httptest.Server
  83. providerDriverName string
  84. )
  85. func TestMain(m *testing.M) {
  86. homeBasePath = os.TempDir()
  87. logfilePath := filepath.Join(configDir, "sftpgo_api_test.log")
  88. logger.InitLogger(logfilePath, 5, 1, 28, false, zerolog.DebugLevel)
  89. config.LoadConfig(configDir, "")
  90. providerConf := config.GetProviderConf()
  91. credentialsPath = filepath.Join(os.TempDir(), "test_credentials")
  92. providerConf.CredentialsPath = credentialsPath
  93. providerDriverName = providerConf.Driver
  94. os.RemoveAll(credentialsPath)
  95. err := dataprovider.Initialize(providerConf, configDir)
  96. if err != nil {
  97. logger.Warn(logSender, "", "error initializing data provider: %v", err)
  98. os.Exit(1)
  99. }
  100. dataProvider := dataprovider.GetProvider()
  101. httpdConf := config.GetHTTPDConfig()
  102. httpdConf.BindPort = 8081
  103. httpd.SetBaseURLAndCredentials("http://127.0.0.1:8081", "", "")
  104. backupsPath = filepath.Join(os.TempDir(), "test_backups")
  105. httpdConf.BackupsPath = backupsPath
  106. os.MkdirAll(backupsPath, 0777)
  107. sftpd.SetDataProvider(dataProvider)
  108. httpd.SetDataProvider(dataProvider)
  109. go func() {
  110. if err := httpdConf.Initialize(configDir); err != nil {
  111. logger.Error(logSender, "", "could not start HTTP server: %v", err)
  112. }
  113. }()
  114. waitTCPListening(fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort))
  115. // now start an https server
  116. certPath := filepath.Join(os.TempDir(), "test.crt")
  117. keyPath := filepath.Join(os.TempDir(), "test.key")
  118. ioutil.WriteFile(certPath, []byte(httpsCert), 0666)
  119. ioutil.WriteFile(keyPath, []byte(httpsKey), 0666)
  120. httpdConf.BindPort = 8443
  121. httpdConf.CertificateFile = certPath
  122. httpdConf.CertificateKeyFile = keyPath
  123. go func() {
  124. if err := httpdConf.Initialize(configDir); err != nil {
  125. logger.Error(logSender, "", "could not start HTTPS server: %v", err)
  126. }
  127. }()
  128. waitTCPListening(fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort))
  129. httpd.ReloadTLSCertificate()
  130. testServer = httptest.NewServer(httpd.GetHTTPRouter())
  131. defer testServer.Close()
  132. exitCode := m.Run()
  133. os.Remove(logfilePath)
  134. os.RemoveAll(backupsPath)
  135. os.RemoveAll(credentialsPath)
  136. os.Remove(certPath)
  137. os.Remove(keyPath)
  138. os.Exit(exitCode)
  139. }
  140. func TestInitialization(t *testing.T) {
  141. config.LoadConfig(configDir, "")
  142. httpdConf := config.GetHTTPDConfig()
  143. httpdConf.BackupsPath = "test_backups"
  144. httpdConf.AuthUserFile = "invalid file"
  145. err := httpdConf.Initialize(configDir)
  146. if err == nil {
  147. t.Error("Inizialize must fail")
  148. }
  149. httpdConf.BackupsPath = backupsPath
  150. httpdConf.AuthUserFile = ""
  151. httpdConf.CertificateFile = "invalid file"
  152. httpdConf.CertificateKeyFile = "invalid file"
  153. err = httpdConf.Initialize(configDir)
  154. if err == nil {
  155. t.Error("Inizialize must fail")
  156. }
  157. }
  158. func TestBasicUserHandling(t *testing.T) {
  159. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  160. if err != nil {
  161. t.Errorf("unable to add user: %v", err)
  162. }
  163. user.MaxSessions = 10
  164. user.QuotaSize = 4096
  165. user.QuotaFiles = 2
  166. user.UploadBandwidth = 128
  167. user.DownloadBandwidth = 64
  168. user.ExpirationDate = utils.GetTimeAsMsSinceEpoch(time.Now())
  169. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  170. if err != nil {
  171. t.Errorf("unable to update user: %v", err)
  172. }
  173. users, _, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  174. if err != nil {
  175. t.Errorf("unable to get users: %v", err)
  176. }
  177. if len(users) != 1 {
  178. t.Errorf("number of users mismatch, expected: 1, actual: %v", len(users))
  179. }
  180. _, err = httpd.RemoveUser(user, http.StatusOK)
  181. if err != nil {
  182. t.Errorf("unable to remove: %v", err)
  183. }
  184. }
  185. func TestUserStatus(t *testing.T) {
  186. u := getTestUser()
  187. u.Status = 3
  188. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  189. if err != nil {
  190. t.Errorf("unexpected error adding user with bad status: %v", err)
  191. }
  192. u.Status = 0
  193. user, _, err := httpd.AddUser(u, http.StatusOK)
  194. if err != nil {
  195. t.Errorf("unable to add user: %v", err)
  196. }
  197. user.Status = 2
  198. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest)
  199. if err != nil {
  200. t.Errorf("unexpected error updating user with bad status: %v", err)
  201. }
  202. user.Status = 1
  203. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  204. if err != nil {
  205. t.Errorf("unable to update user: %v", err)
  206. }
  207. _, err = httpd.RemoveUser(user, http.StatusOK)
  208. if err != nil {
  209. t.Errorf("unable to remove: %v", err)
  210. }
  211. }
  212. func TestAddUserNoCredentials(t *testing.T) {
  213. u := getTestUser()
  214. u.Password = ""
  215. u.PublicKeys = []string{}
  216. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  217. if err != nil {
  218. t.Errorf("unexpected error adding user with no credentials: %v", err)
  219. }
  220. }
  221. func TestAddUserNoUsername(t *testing.T) {
  222. u := getTestUser()
  223. u.Username = ""
  224. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  225. if err != nil {
  226. t.Errorf("unexpected error adding user with no home dir: %v", err)
  227. }
  228. }
  229. func TestAddUserNoHomeDir(t *testing.T) {
  230. u := getTestUser()
  231. u.HomeDir = ""
  232. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  233. if err != nil {
  234. t.Errorf("unexpected error adding user with no home dir: %v", err)
  235. }
  236. }
  237. func TestAddUserInvalidHomeDir(t *testing.T) {
  238. u := getTestUser()
  239. u.HomeDir = "relative_path"
  240. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  241. if err != nil {
  242. t.Errorf("unexpected error adding user with invalid home dir: %v", err)
  243. }
  244. }
  245. func TestAddUserNoPerms(t *testing.T) {
  246. u := getTestUser()
  247. u.Permissions = make(map[string][]string)
  248. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  249. if err != nil {
  250. t.Errorf("unexpected error adding user with no perms: %v", err)
  251. }
  252. u.Permissions["/"] = []string{}
  253. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  254. if err != nil {
  255. t.Errorf("unexpected error adding user with no perms: %v", err)
  256. }
  257. }
  258. func TestAddUserInvalidPerms(t *testing.T) {
  259. u := getTestUser()
  260. u.Permissions["/"] = []string{"invalidPerm"}
  261. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  262. if err != nil {
  263. t.Errorf("unexpected error adding user with invalid perms: %v", err)
  264. }
  265. // permissions for root dir are mandatory
  266. u.Permissions["/"] = []string{}
  267. u.Permissions["/somedir"] = []string{dataprovider.PermAny}
  268. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  269. if err != nil {
  270. t.Errorf("unexpected error adding user with no root dir perms: %v", err)
  271. }
  272. u.Permissions["/"] = []string{dataprovider.PermAny}
  273. u.Permissions["/subdir/.."] = []string{dataprovider.PermAny}
  274. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  275. if err != nil {
  276. t.Errorf("unexpected error adding user with invalid dir perms: %v", err)
  277. }
  278. }
  279. func TestAddUserInvalidFilters(t *testing.T) {
  280. u := getTestUser()
  281. u.Filters.AllowedIP = []string{"192.168.1.0/24", "192.168.2.0"}
  282. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  283. if err != nil {
  284. t.Errorf("unexpected error adding user with invalid filters: %v", err)
  285. }
  286. u.Filters.AllowedIP = []string{}
  287. u.Filters.DeniedIP = []string{"192.168.3.0/16", "invalid"}
  288. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  289. if err != nil {
  290. t.Errorf("unexpected error adding user with invalid filters: %v", err)
  291. }
  292. u.Filters.DeniedIP = []string{}
  293. u.Filters.DeniedLoginMethods = []string{"invalid"}
  294. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  295. if err != nil {
  296. t.Errorf("unexpected error adding user with invalid filters: %v", err)
  297. }
  298. u.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodKeyboardInteractive,
  299. dataprovider.SSHLoginMethodPassword, dataprovider.SSHLoginMethodPublicKey}
  300. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  301. if err != nil {
  302. t.Errorf("unexpected error adding user with invalid filters: %v", err)
  303. }
  304. u.Filters.DeniedLoginMethods = []string{}
  305. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  306. dataprovider.ExtensionsFilter{
  307. Path: "relative",
  308. AllowedExtensions: []string{},
  309. DeniedExtensions: []string{},
  310. },
  311. }
  312. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  313. if err != nil {
  314. t.Errorf("unexpected error adding user with invalid extensions filters: %v", err)
  315. }
  316. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  317. dataprovider.ExtensionsFilter{
  318. Path: "/",
  319. AllowedExtensions: []string{},
  320. DeniedExtensions: []string{},
  321. },
  322. }
  323. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  324. if err != nil {
  325. t.Errorf("unexpected error adding user with invalid extensions filters: %v", err)
  326. }
  327. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  328. dataprovider.ExtensionsFilter{
  329. Path: "/subdir",
  330. AllowedExtensions: []string{".zip"},
  331. DeniedExtensions: []string{},
  332. },
  333. dataprovider.ExtensionsFilter{
  334. Path: "/subdir",
  335. AllowedExtensions: []string{".rar"},
  336. DeniedExtensions: []string{".jpg"},
  337. },
  338. }
  339. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  340. if err != nil {
  341. t.Errorf("unexpected error adding user with invalid extensions filters: %v", err)
  342. }
  343. }
  344. func TestAddUserInvalidFsConfig(t *testing.T) {
  345. u := getTestUser()
  346. u.FsConfig.Provider = 1
  347. u.FsConfig.S3Config.Bucket = ""
  348. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  349. if err != nil {
  350. t.Errorf("unexpected error adding user with invalid fs config: %v", err)
  351. }
  352. os.RemoveAll(credentialsPath)
  353. os.MkdirAll(credentialsPath, 0700)
  354. u.FsConfig.S3Config.Bucket = "test"
  355. u.FsConfig.S3Config.Region = "eu-west-1"
  356. u.FsConfig.S3Config.AccessKey = "access-key"
  357. u.FsConfig.S3Config.AccessSecret = "access-secret"
  358. u.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/path?a=b"
  359. u.FsConfig.S3Config.StorageClass = "Standard"
  360. u.FsConfig.S3Config.KeyPrefix = "/somedir/subdir/"
  361. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  362. if err != nil {
  363. t.Errorf("unexpected error adding user with invalid fs config: %v", err)
  364. }
  365. u = getTestUser()
  366. u.FsConfig.Provider = 2
  367. u.FsConfig.GCSConfig.Bucket = ""
  368. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  369. if err != nil {
  370. t.Errorf("unexpected error adding user with invalid fs config: %v", err)
  371. }
  372. u.FsConfig.GCSConfig.Bucket = "test"
  373. u.FsConfig.GCSConfig.StorageClass = "Standard"
  374. u.FsConfig.GCSConfig.KeyPrefix = "/somedir/subdir/"
  375. u.FsConfig.GCSConfig.Credentials = base64.StdEncoding.EncodeToString([]byte("test"))
  376. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  377. if err != nil {
  378. t.Errorf("unexpected error adding user with invalid fs config: %v", err)
  379. }
  380. u.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir/"
  381. u.FsConfig.GCSConfig.Credentials = ""
  382. u.FsConfig.GCSConfig.AutomaticCredentials = 0
  383. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  384. if err != nil {
  385. t.Errorf("unexpected error adding user with invalid fs config: %v", err)
  386. }
  387. u.FsConfig.GCSConfig.Credentials = "no base64 encoded"
  388. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  389. if err != nil {
  390. t.Errorf("unexpected error adding user with invalid fs config: %v", err)
  391. }
  392. }
  393. func TestAddUserInvalidVirtualFolders(t *testing.T) {
  394. u := getTestUser()
  395. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  396. VirtualPath: "vdir",
  397. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  398. })
  399. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  400. if err != nil {
  401. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  402. }
  403. u.VirtualFolders = nil
  404. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  405. VirtualPath: "/",
  406. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  407. })
  408. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  409. if err != nil {
  410. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  411. }
  412. u.VirtualFolders = nil
  413. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  414. VirtualPath: "/vdir",
  415. MappedPath: filepath.Join(u.GetHomeDir(), "mapped_dir"),
  416. })
  417. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  418. if err != nil {
  419. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  420. }
  421. u.VirtualFolders = nil
  422. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  423. VirtualPath: "/vdir",
  424. MappedPath: u.GetHomeDir(),
  425. })
  426. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  427. if err != nil {
  428. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  429. }
  430. u.VirtualFolders = nil
  431. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  432. VirtualPath: "/vdir",
  433. MappedPath: filepath.Join(u.GetHomeDir(), ".."),
  434. })
  435. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  436. if err != nil {
  437. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  438. }
  439. u.VirtualFolders = nil
  440. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  441. VirtualPath: "/vdir",
  442. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  443. })
  444. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  445. VirtualPath: "/vdir",
  446. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  447. })
  448. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  449. if err != nil {
  450. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  451. }
  452. u.VirtualFolders = nil
  453. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  454. VirtualPath: "/vdir1",
  455. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  456. })
  457. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  458. VirtualPath: "/vdir2",
  459. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  460. })
  461. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  462. if err != nil {
  463. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  464. }
  465. u.VirtualFolders = nil
  466. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  467. VirtualPath: "/vdir1",
  468. MappedPath: filepath.Join(os.TempDir(), "mapped_dir", "subdir"),
  469. })
  470. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  471. VirtualPath: "/vdir2",
  472. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  473. })
  474. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  475. if err != nil {
  476. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  477. }
  478. u.VirtualFolders = nil
  479. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  480. VirtualPath: "/vdir1",
  481. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  482. })
  483. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  484. VirtualPath: "/vdir2",
  485. MappedPath: filepath.Join(os.TempDir(), "mapped_dir", "subdir"),
  486. })
  487. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  488. if err != nil {
  489. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  490. }
  491. u.VirtualFolders = nil
  492. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  493. VirtualPath: "/vdir1/subdir",
  494. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  495. })
  496. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  497. VirtualPath: "/vdir1/../vdir1",
  498. MappedPath: filepath.Join(os.TempDir(), "mapped_dir2"),
  499. })
  500. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  501. if err != nil {
  502. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  503. }
  504. u.VirtualFolders = nil
  505. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  506. VirtualPath: "/vdir1/",
  507. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  508. })
  509. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  510. VirtualPath: "/vdir1/subdir",
  511. MappedPath: filepath.Join(os.TempDir(), "mapped_dir2"),
  512. })
  513. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  514. if err != nil {
  515. t.Errorf("unexpected error adding user with invalid virtual folder: %v", err)
  516. }
  517. }
  518. func TestUserPublicKey(t *testing.T) {
  519. u := getTestUser()
  520. invalidPubKey := "invalid"
  521. validPubKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  522. u.PublicKeys = []string{invalidPubKey}
  523. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  524. if err != nil {
  525. t.Errorf("unexpected error adding user with invalid pub key: %v", err)
  526. }
  527. u.PublicKeys = []string{validPubKey}
  528. user, _, err := httpd.AddUser(u, http.StatusOK)
  529. if err != nil {
  530. t.Errorf("unable to add user: %v", err)
  531. }
  532. user.PublicKeys = []string{validPubKey, invalidPubKey}
  533. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest)
  534. if err != nil {
  535. t.Errorf("update user with invalid public key must fail: %v", err)
  536. }
  537. user.PublicKeys = []string{validPubKey, validPubKey, validPubKey}
  538. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  539. if err != nil {
  540. t.Errorf("unable to update user: %v", err)
  541. }
  542. _, err = httpd.RemoveUser(user, http.StatusOK)
  543. if err != nil {
  544. t.Errorf("unable to remove: %v", err)
  545. }
  546. }
  547. func TestUpdateUser(t *testing.T) {
  548. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  549. if err != nil {
  550. t.Errorf("unable to add user: %v", err)
  551. }
  552. user.HomeDir = filepath.Join(homeBasePath, "testmod")
  553. user.UID = 33
  554. user.GID = 101
  555. user.MaxSessions = 10
  556. user.QuotaSize = 4096
  557. user.QuotaFiles = 2
  558. user.Permissions["/"] = []string{dataprovider.PermCreateDirs, dataprovider.PermDelete, dataprovider.PermDownload}
  559. user.Permissions["/subdir"] = []string{dataprovider.PermListItems, dataprovider.PermUpload}
  560. user.Filters.AllowedIP = []string{"192.168.1.0/24", "192.168.2.0/24"}
  561. user.Filters.DeniedIP = []string{"192.168.3.0/24", "192.168.4.0/24"}
  562. user.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodPassword}
  563. user.Filters.FileExtensions = append(user.Filters.FileExtensions, dataprovider.ExtensionsFilter{
  564. Path: "/subdir",
  565. AllowedExtensions: []string{".zip", ".rar"},
  566. DeniedExtensions: []string{".jpg", ".png"},
  567. })
  568. user.UploadBandwidth = 1024
  569. user.DownloadBandwidth = 512
  570. user.VirtualFolders = nil
  571. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  572. VirtualPath: "/vdir1",
  573. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  574. })
  575. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  576. VirtualPath: "/vdir12/subdir",
  577. MappedPath: filepath.Join(os.TempDir(), "mapped_dir2"),
  578. })
  579. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  580. if err != nil {
  581. t.Errorf("unable to update user: %v", err)
  582. }
  583. user.Permissions["/subdir"] = []string{}
  584. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  585. if err != nil {
  586. t.Errorf("unable to update user: %v", err)
  587. }
  588. if len(user.Permissions["/subdir"]) > 0 {
  589. t.Errorf("unexpected subdir permissions, must be empty")
  590. }
  591. _, err = httpd.RemoveUser(user, http.StatusOK)
  592. if err != nil {
  593. t.Errorf("unable to remove: %v", err)
  594. }
  595. }
  596. func TestUserS3Config(t *testing.T) {
  597. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  598. if err != nil {
  599. t.Errorf("unable to add user: %v", err)
  600. }
  601. user.FsConfig.Provider = 1
  602. user.FsConfig.S3Config.Bucket = "test"
  603. user.FsConfig.S3Config.Region = "us-east-1"
  604. user.FsConfig.S3Config.AccessKey = "Server-Access-Key"
  605. user.FsConfig.S3Config.AccessSecret = "Server-Access-Secret"
  606. user.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000"
  607. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  608. if err != nil {
  609. t.Errorf("unable to update user: %v", err)
  610. }
  611. _, err = httpd.RemoveUser(user, http.StatusOK)
  612. if err != nil {
  613. t.Errorf("unable to remove: %v", err)
  614. }
  615. user.Password = defaultPassword
  616. user.ID = 0
  617. secret, _ := utils.EncryptData("Server-Access-Secret")
  618. user.FsConfig.S3Config.AccessSecret = secret
  619. user, _, err = httpd.AddUser(user, http.StatusOK)
  620. if err != nil {
  621. t.Errorf("unable to add user: %v", err)
  622. }
  623. user.FsConfig.Provider = 1
  624. user.FsConfig.S3Config.Bucket = "test1"
  625. user.FsConfig.S3Config.Region = "us-east-1"
  626. user.FsConfig.S3Config.AccessKey = "Server-Access-Key1"
  627. user.FsConfig.S3Config.Endpoint = "http://localhost:9000"
  628. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  629. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  630. if err != nil {
  631. t.Errorf("unable to update user: %v", err)
  632. }
  633. user.FsConfig.Provider = 0
  634. user.FsConfig.S3Config.Bucket = ""
  635. user.FsConfig.S3Config.Region = ""
  636. user.FsConfig.S3Config.AccessKey = ""
  637. user.FsConfig.S3Config.AccessSecret = ""
  638. user.FsConfig.S3Config.Endpoint = ""
  639. user.FsConfig.S3Config.KeyPrefix = ""
  640. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  641. if err != nil {
  642. t.Errorf("unable to update user: %v", err)
  643. }
  644. // test user without access key and access secret (shared config state)
  645. user.FsConfig.Provider = 1
  646. user.FsConfig.S3Config.Bucket = "test1"
  647. user.FsConfig.S3Config.Region = "us-east-1"
  648. user.FsConfig.S3Config.AccessKey = ""
  649. user.FsConfig.S3Config.AccessSecret = ""
  650. user.FsConfig.S3Config.Endpoint = ""
  651. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  652. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  653. if err != nil {
  654. t.Errorf("unable to update user: %v", err)
  655. }
  656. _, err = httpd.RemoveUser(user, http.StatusOK)
  657. if err != nil {
  658. t.Errorf("unable to remove: %v", err)
  659. }
  660. }
  661. func TestUserGCSConfig(t *testing.T) {
  662. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  663. if err != nil {
  664. t.Errorf("unable to add user: %v", err)
  665. }
  666. os.RemoveAll(credentialsPath)
  667. os.MkdirAll(credentialsPath, 0700)
  668. user.FsConfig.Provider = 2
  669. user.FsConfig.GCSConfig.Bucket = "test"
  670. user.FsConfig.GCSConfig.Credentials = base64.StdEncoding.EncodeToString([]byte("fake credentials"))
  671. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  672. if err != nil {
  673. t.Errorf("unable to update user: %v", err)
  674. }
  675. _, err = httpd.RemoveUser(user, http.StatusOK)
  676. if err != nil {
  677. t.Errorf("unable to remove: %v", err)
  678. }
  679. user.Password = defaultPassword
  680. user.ID = 0
  681. // the user will be added since the credentials file is found
  682. user, _, err = httpd.AddUser(user, http.StatusOK)
  683. if err != nil {
  684. t.Errorf("unable to add user: %v", err)
  685. }
  686. os.RemoveAll(credentialsPath)
  687. os.MkdirAll(credentialsPath, 0700)
  688. user.FsConfig.GCSConfig.Credentials = ""
  689. user.FsConfig.GCSConfig.AutomaticCredentials = 1
  690. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  691. if err != nil {
  692. t.Errorf("unable to update user: %v", err)
  693. }
  694. user.FsConfig.Provider = 1
  695. user.FsConfig.S3Config.Bucket = "test1"
  696. user.FsConfig.S3Config.Region = "us-east-1"
  697. user.FsConfig.S3Config.AccessKey = "Server-Access-Key1"
  698. user.FsConfig.S3Config.AccessSecret = "secret"
  699. user.FsConfig.S3Config.Endpoint = "http://localhost:9000"
  700. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  701. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  702. if err != nil {
  703. t.Errorf("unable to update user: %v", err)
  704. }
  705. user.FsConfig.Provider = 2
  706. user.FsConfig.GCSConfig.Bucket = "test1"
  707. user.FsConfig.GCSConfig.Credentials = base64.StdEncoding.EncodeToString([]byte("fake credentials"))
  708. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  709. if err != nil {
  710. t.Errorf("unable to update user: %v", err)
  711. }
  712. _, err = httpd.RemoveUser(user, http.StatusOK)
  713. if err != nil {
  714. t.Errorf("unable to remove: %v", err)
  715. }
  716. }
  717. func TestUpdateUserNoCredentials(t *testing.T) {
  718. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  719. if err != nil {
  720. t.Errorf("unable to add user: %v", err)
  721. }
  722. user.Password = ""
  723. user.PublicKeys = []string{}
  724. // password and public key will be omitted from json serialization if empty and so they will remain unchanged
  725. // and no validation error will be raised
  726. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  727. if err != nil {
  728. t.Errorf("unexpected error updating user with no credentials: %v", err)
  729. }
  730. _, err = httpd.RemoveUser(user, http.StatusOK)
  731. if err != nil {
  732. t.Errorf("unable to remove: %v", err)
  733. }
  734. }
  735. func TestUpdateUserEmptyHomeDir(t *testing.T) {
  736. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  737. if err != nil {
  738. t.Errorf("unable to add user: %v", err)
  739. }
  740. user.HomeDir = ""
  741. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest)
  742. if err != nil {
  743. t.Errorf("unexpected error updating user with empty home dir: %v", err)
  744. }
  745. _, err = httpd.RemoveUser(user, http.StatusOK)
  746. if err != nil {
  747. t.Errorf("unable to remove: %v", err)
  748. }
  749. }
  750. func TestUpdateUserInvalidHomeDir(t *testing.T) {
  751. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  752. if err != nil {
  753. t.Errorf("unable to add user: %v", err)
  754. }
  755. user.HomeDir = "relative_path"
  756. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest)
  757. if err != nil {
  758. t.Errorf("unexpected error updating user with empty home dir: %v", err)
  759. }
  760. _, err = httpd.RemoveUser(user, http.StatusOK)
  761. if err != nil {
  762. t.Errorf("unable to remove: %v", err)
  763. }
  764. }
  765. func TestUpdateNonExistentUser(t *testing.T) {
  766. _, _, err := httpd.UpdateUser(getTestUser(), http.StatusNotFound)
  767. if err != nil {
  768. t.Errorf("unable to update user: %v", err)
  769. }
  770. }
  771. func TestGetNonExistentUser(t *testing.T) {
  772. _, _, err := httpd.GetUserByID(0, http.StatusNotFound)
  773. if err != nil {
  774. t.Errorf("unable to get user: %v", err)
  775. }
  776. }
  777. func TestDeleteNonExistentUser(t *testing.T) {
  778. _, err := httpd.RemoveUser(getTestUser(), http.StatusNotFound)
  779. if err != nil {
  780. t.Errorf("unable to remove user: %v", err)
  781. }
  782. }
  783. func TestAddDuplicateUser(t *testing.T) {
  784. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  785. if err != nil {
  786. t.Errorf("unable to add user: %v", err)
  787. }
  788. _, _, err = httpd.AddUser(getTestUser(), http.StatusInternalServerError)
  789. if err != nil {
  790. t.Errorf("unable to add second user: %v", err)
  791. }
  792. _, _, err = httpd.AddUser(getTestUser(), http.StatusOK)
  793. if err == nil {
  794. t.Errorf("adding a duplicate user must fail")
  795. }
  796. _, err = httpd.RemoveUser(user, http.StatusOK)
  797. if err != nil {
  798. t.Errorf("unable to remove user: %v", err)
  799. }
  800. }
  801. func TestGetUsers(t *testing.T) {
  802. user1, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  803. if err != nil {
  804. t.Errorf("unable to add user: %v", err)
  805. }
  806. u := getTestUser()
  807. u.Username = defaultUsername + "1"
  808. user2, _, err := httpd.AddUser(u, http.StatusOK)
  809. if err != nil {
  810. t.Errorf("unable to add second user: %v", err)
  811. }
  812. users, _, err := httpd.GetUsers(0, 0, "", http.StatusOK)
  813. if err != nil {
  814. t.Errorf("unable to get users: %v", err)
  815. }
  816. if len(users) < 2 {
  817. t.Errorf("at least 2 users are expected")
  818. }
  819. users, _, err = httpd.GetUsers(1, 0, "", http.StatusOK)
  820. if err != nil {
  821. t.Errorf("unable to get users: %v", err)
  822. }
  823. if len(users) != 1 {
  824. t.Errorf("1 user is expected")
  825. }
  826. users, _, err = httpd.GetUsers(1, 1, "", http.StatusOK)
  827. if err != nil {
  828. t.Errorf("unable to get users: %v", err)
  829. }
  830. if len(users) != 1 {
  831. t.Errorf("1 user is expected")
  832. }
  833. _, _, err = httpd.GetUsers(1, 1, "", http.StatusInternalServerError)
  834. if err == nil {
  835. t.Errorf("get users must succeed, we requested a fail for a good request")
  836. }
  837. _, err = httpd.RemoveUser(user1, http.StatusOK)
  838. if err != nil {
  839. t.Errorf("unable to remove user: %v", err)
  840. }
  841. _, err = httpd.RemoveUser(user2, http.StatusOK)
  842. if err != nil {
  843. t.Errorf("unable to remove user: %v", err)
  844. }
  845. }
  846. func TestGetQuotaScans(t *testing.T) {
  847. _, _, err := httpd.GetQuotaScans(http.StatusOK)
  848. if err != nil {
  849. t.Errorf("unable to get quota scans: %v", err)
  850. }
  851. _, _, err = httpd.GetQuotaScans(http.StatusInternalServerError)
  852. if err == nil {
  853. t.Errorf("quota scan request must succeed, we requested to check a wrong status code")
  854. }
  855. }
  856. func TestStartQuotaScan(t *testing.T) {
  857. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  858. if err != nil {
  859. t.Errorf("unable to add user: %v", err)
  860. }
  861. _, err = httpd.StartQuotaScan(user, http.StatusCreated)
  862. if err != nil {
  863. t.Errorf("unable to start quota scan: %v", err)
  864. }
  865. _, err = httpd.RemoveUser(user, http.StatusOK)
  866. if err != nil {
  867. t.Errorf("unable to remove user: %v", err)
  868. }
  869. }
  870. func TestGetVersion(t *testing.T) {
  871. _, _, err := httpd.GetVersion(http.StatusOK)
  872. if err != nil {
  873. t.Errorf("unable to get version: %v", err)
  874. }
  875. _, _, err = httpd.GetVersion(http.StatusInternalServerError)
  876. if err == nil {
  877. t.Errorf("get version request must succeed, we requested to check a wrong status code")
  878. }
  879. }
  880. func TestGetProviderStatus(t *testing.T) {
  881. _, _, err := httpd.GetProviderStatus(http.StatusOK)
  882. if err != nil {
  883. t.Errorf("unable to get provider status: %v", err)
  884. }
  885. _, _, err = httpd.GetProviderStatus(http.StatusBadRequest)
  886. if err == nil {
  887. t.Errorf("get provider status request must succeed, we requested to check a wrong status code")
  888. }
  889. }
  890. func TestGetConnections(t *testing.T) {
  891. _, _, err := httpd.GetConnections(http.StatusOK)
  892. if err != nil {
  893. t.Errorf("unable to get sftp connections: %v", err)
  894. }
  895. _, _, err = httpd.GetConnections(http.StatusInternalServerError)
  896. if err == nil {
  897. t.Errorf("get sftp connections request must succeed, we requested to check a wrong status code")
  898. }
  899. }
  900. func TestCloseActiveConnection(t *testing.T) {
  901. _, err := httpd.CloseConnection("non_existent_id", http.StatusNotFound)
  902. if err != nil {
  903. t.Errorf("unexpected error closing non existent sftp connection: %v", err)
  904. }
  905. }
  906. func TestUserBaseDir(t *testing.T) {
  907. dataProvider := dataprovider.GetProvider()
  908. dataprovider.Close(dataProvider)
  909. config.LoadConfig(configDir, "")
  910. providerConf := config.GetProviderConf()
  911. providerConf.UsersBaseDir = homeBasePath
  912. err := dataprovider.Initialize(providerConf, configDir)
  913. if err != nil {
  914. t.Errorf("error initializing data provider with users base dir")
  915. }
  916. httpd.SetDataProvider(dataprovider.GetProvider())
  917. u := getTestUser()
  918. u.HomeDir = ""
  919. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  920. if err != nil {
  921. t.Errorf("unable to add user: %v", err)
  922. }
  923. if user.HomeDir != filepath.Join(providerConf.UsersBaseDir, u.Username) {
  924. t.Errorf("invalid home dir: %v", user.HomeDir)
  925. }
  926. _, err = httpd.RemoveUser(user, http.StatusOK)
  927. if err != nil {
  928. t.Errorf("unable to remove: %v", err)
  929. }
  930. dataProvider = dataprovider.GetProvider()
  931. dataprovider.Close(dataProvider)
  932. config.LoadConfig(configDir, "")
  933. providerConf = config.GetProviderConf()
  934. providerConf.CredentialsPath = credentialsPath
  935. os.RemoveAll(credentialsPath)
  936. err = dataprovider.Initialize(providerConf, configDir)
  937. if err != nil {
  938. t.Errorf("error initializing data provider")
  939. }
  940. httpd.SetDataProvider(dataprovider.GetProvider())
  941. sftpd.SetDataProvider(dataprovider.GetProvider())
  942. }
  943. func TestProviderErrors(t *testing.T) {
  944. if providerDriverName == dataprovider.BoltDataProviderName {
  945. t.Skip("skipping test provider errors for bolt provider")
  946. }
  947. dataProvider := dataprovider.GetProvider()
  948. dataprovider.Close(dataProvider)
  949. _, _, err := httpd.GetUserByID(0, http.StatusInternalServerError)
  950. if err != nil {
  951. t.Errorf("get user with provider closed must fail: %v", err)
  952. }
  953. _, _, err = httpd.GetUsers(1, 0, defaultUsername, http.StatusInternalServerError)
  954. if err != nil {
  955. t.Errorf("get users with provider closed must fail: %v", err)
  956. }
  957. _, _, err = httpd.UpdateUser(dataprovider.User{}, http.StatusInternalServerError)
  958. if err != nil {
  959. t.Errorf("update user with provider closed must fail: %v", err)
  960. }
  961. _, err = httpd.RemoveUser(dataprovider.User{}, http.StatusInternalServerError)
  962. if err != nil {
  963. t.Errorf("delete user with provider closed must fail: %v", err)
  964. }
  965. _, _, err = httpd.GetProviderStatus(http.StatusInternalServerError)
  966. if err != nil {
  967. t.Errorf("get provider status with provider closed must fail: %v", err)
  968. }
  969. _, _, err = httpd.Dumpdata("backup.json", "", http.StatusInternalServerError)
  970. if err != nil {
  971. t.Errorf("get provider status with provider closed must fail: %v", err)
  972. }
  973. user := getTestUser()
  974. user.ID = 1
  975. backupData := dataprovider.BackupData{}
  976. backupData.Users = append(backupData.Users, user)
  977. backupContent, _ := json.Marshal(backupData)
  978. backupFilePath := filepath.Join(backupsPath, "backup.json")
  979. ioutil.WriteFile(backupFilePath, backupContent, 0666)
  980. _, _, err = httpd.Loaddata(backupFilePath, "", "", http.StatusInternalServerError)
  981. if err != nil {
  982. t.Errorf("get provider status with provider closed must fail: %v", err)
  983. }
  984. os.Remove(backupFilePath)
  985. config.LoadConfig(configDir, "")
  986. providerConf := config.GetProviderConf()
  987. providerConf.CredentialsPath = credentialsPath
  988. os.RemoveAll(credentialsPath)
  989. err = dataprovider.Initialize(providerConf, configDir)
  990. if err != nil {
  991. t.Errorf("error initializing data provider")
  992. }
  993. httpd.SetDataProvider(dataprovider.GetProvider())
  994. sftpd.SetDataProvider(dataprovider.GetProvider())
  995. }
  996. func TestDumpdata(t *testing.T) {
  997. dataProvider := dataprovider.GetProvider()
  998. dataprovider.Close(dataProvider)
  999. config.LoadConfig(configDir, "")
  1000. providerConf := config.GetProviderConf()
  1001. err := dataprovider.Initialize(providerConf, configDir)
  1002. if err != nil {
  1003. t.Errorf("error initializing data provider")
  1004. }
  1005. httpd.SetDataProvider(dataprovider.GetProvider())
  1006. sftpd.SetDataProvider(dataprovider.GetProvider())
  1007. _, _, err = httpd.Dumpdata("", "", http.StatusBadRequest)
  1008. if err != nil {
  1009. t.Errorf("unexpected error: %v", err)
  1010. }
  1011. _, _, err = httpd.Dumpdata(filepath.Join(backupsPath, "backup.json"), "", http.StatusBadRequest)
  1012. if err != nil {
  1013. t.Errorf("unexpected error: %v", err)
  1014. }
  1015. _, _, err = httpd.Dumpdata("../backup.json", "", http.StatusBadRequest)
  1016. if err != nil {
  1017. t.Errorf("unexpected error: %v", err)
  1018. }
  1019. _, _, err = httpd.Dumpdata("backup.json", "0", http.StatusOK)
  1020. if err != nil {
  1021. t.Errorf("unexpected error: %v", err)
  1022. }
  1023. _, _, err = httpd.Dumpdata("backup.json", "1", http.StatusOK)
  1024. if err != nil {
  1025. t.Errorf("unexpected error: %v", err)
  1026. }
  1027. os.Remove(filepath.Join(backupsPath, "backup.json"))
  1028. if runtime.GOOS != "windows" {
  1029. os.Chmod(backupsPath, 0001)
  1030. _, _, err = httpd.Dumpdata("bck.json", "", http.StatusInternalServerError)
  1031. if err != nil {
  1032. t.Errorf("unexpected error: %v", err)
  1033. }
  1034. os.Chmod(backupsPath, 0755)
  1035. }
  1036. providerConf = config.GetProviderConf()
  1037. providerConf.CredentialsPath = credentialsPath
  1038. os.RemoveAll(credentialsPath)
  1039. err = dataprovider.Initialize(providerConf, configDir)
  1040. if err != nil {
  1041. t.Errorf("error initializing data provider: %v", err)
  1042. }
  1043. httpd.SetDataProvider(dataprovider.GetProvider())
  1044. sftpd.SetDataProvider(dataprovider.GetProvider())
  1045. }
  1046. func TestLoaddata(t *testing.T) {
  1047. user := getTestUser()
  1048. user.ID = 1
  1049. user.Username = "test_user_restore"
  1050. backupData := dataprovider.BackupData{}
  1051. backupData.Users = append(backupData.Users, user)
  1052. backupContent, _ := json.Marshal(backupData)
  1053. backupFilePath := filepath.Join(backupsPath, "backup.json")
  1054. ioutil.WriteFile(backupFilePath, backupContent, 0666)
  1055. _, _, err := httpd.Loaddata(backupFilePath, "a", "", http.StatusBadRequest)
  1056. if err != nil {
  1057. t.Errorf("unexpected error: %v", err)
  1058. }
  1059. _, _, err = httpd.Loaddata(backupFilePath, "", "a", http.StatusBadRequest)
  1060. if err != nil {
  1061. t.Errorf("unexpected error: %v", err)
  1062. }
  1063. _, _, err = httpd.Loaddata("backup.json", "1", "", http.StatusBadRequest)
  1064. if err != nil {
  1065. t.Errorf("unexpected error: %v", err)
  1066. }
  1067. _, _, err = httpd.Loaddata(backupFilePath+"a", "1", "", http.StatusBadRequest)
  1068. if err != nil {
  1069. t.Errorf("unexpected error: %v", err)
  1070. }
  1071. if runtime.GOOS != "windows" {
  1072. os.Chmod(backupFilePath, 0111)
  1073. _, _, err = httpd.Loaddata(backupFilePath, "1", "", http.StatusInternalServerError)
  1074. if err != nil {
  1075. t.Errorf("unexpected error: %v", err)
  1076. }
  1077. os.Chmod(backupFilePath, 0644)
  1078. }
  1079. // add user from backup
  1080. _, _, err = httpd.Loaddata(backupFilePath, "1", "", http.StatusOK)
  1081. if err != nil {
  1082. t.Errorf("unexpected error: %v", err)
  1083. }
  1084. // update user from backup
  1085. _, _, err = httpd.Loaddata(backupFilePath, "2", "", http.StatusOK)
  1086. if err != nil {
  1087. t.Errorf("unexpected error: %v", err)
  1088. }
  1089. users, _, err := httpd.GetUsers(1, 0, user.Username, http.StatusOK)
  1090. if err != nil {
  1091. t.Errorf("unable to get users: %v", err)
  1092. }
  1093. if len(users) != 1 {
  1094. t.Error("Unable to get restored user")
  1095. }
  1096. user = users[0]
  1097. _, err = httpd.RemoveUser(user, http.StatusOK)
  1098. if err != nil {
  1099. t.Errorf("unable to remove user: %v", err)
  1100. }
  1101. os.Remove(backupFilePath)
  1102. createTestFile(backupFilePath, 10485761)
  1103. _, _, err = httpd.Loaddata(backupFilePath, "1", "0", http.StatusBadRequest)
  1104. if err != nil {
  1105. t.Errorf("unexpected error: %v", err)
  1106. }
  1107. os.Remove(backupFilePath)
  1108. createTestFile(backupFilePath, 65535)
  1109. _, _, err = httpd.Loaddata(backupFilePath, "1", "0", http.StatusBadRequest)
  1110. if err != nil {
  1111. t.Errorf("unexpected error: %v", err)
  1112. }
  1113. os.Remove(backupFilePath)
  1114. }
  1115. func TestLoaddataMode(t *testing.T) {
  1116. user := getTestUser()
  1117. user.ID = 1
  1118. user.Username = "test_user_restore"
  1119. backupData := dataprovider.BackupData{}
  1120. backupData.Users = append(backupData.Users, user)
  1121. backupContent, _ := json.Marshal(backupData)
  1122. backupFilePath := filepath.Join(backupsPath, "backup.json")
  1123. ioutil.WriteFile(backupFilePath, backupContent, 0666)
  1124. _, _, err := httpd.Loaddata(backupFilePath, "0", "0", http.StatusOK)
  1125. if err != nil {
  1126. t.Errorf("unexpected error: %v", err)
  1127. }
  1128. users, _, err := httpd.GetUsers(1, 0, user.Username, http.StatusOK)
  1129. if err != nil {
  1130. t.Errorf("unable to get users: %v", err)
  1131. }
  1132. if len(users) != 1 {
  1133. t.Error("Unable to get restored user")
  1134. }
  1135. user = users[0]
  1136. oldUploadBandwidth := user.UploadBandwidth
  1137. user.UploadBandwidth = oldUploadBandwidth + 128
  1138. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1139. if err != nil {
  1140. t.Errorf("unable to update user: %v", err)
  1141. }
  1142. _, _, err = httpd.Loaddata(backupFilePath, "0", "1", http.StatusOK)
  1143. if err != nil {
  1144. t.Errorf("unexpected error: %v", err)
  1145. }
  1146. users, _, err = httpd.GetUsers(1, 0, user.Username, http.StatusOK)
  1147. if err != nil {
  1148. t.Errorf("unable to get users: %v", err)
  1149. }
  1150. if len(users) != 1 {
  1151. t.Error("Unable to get restored user")
  1152. }
  1153. user = users[0]
  1154. if user.UploadBandwidth == oldUploadBandwidth {
  1155. t.Error("user must not be modified")
  1156. }
  1157. _, err = httpd.RemoveUser(user, http.StatusOK)
  1158. if err != nil {
  1159. t.Errorf("unable to remove user: %v", err)
  1160. }
  1161. os.Remove(backupFilePath)
  1162. }
  1163. func TestHTTPSConnection(t *testing.T) {
  1164. client := &http.Client{
  1165. Timeout: 5 * time.Second,
  1166. }
  1167. _, err := client.Get("https://localhost:8443" + metricsPath)
  1168. if err == nil || (!strings.Contains(err.Error(), "certificate is not valid") &&
  1169. !strings.Contains(err.Error(), "certificate signed by unknown authority")) {
  1170. t.Errorf("unexpected error: %v", err)
  1171. }
  1172. }
  1173. // test using mock http server
  1174. func TestBasicUserHandlingMock(t *testing.T) {
  1175. user := getTestUser()
  1176. userAsJSON := getUserAsJSON(t, user)
  1177. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1178. rr := executeRequest(req)
  1179. checkResponseCode(t, http.StatusOK, rr.Code)
  1180. err := render.DecodeJSON(rr.Body, &user)
  1181. if err != nil {
  1182. t.Errorf("Error get user: %v", err)
  1183. }
  1184. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1185. rr = executeRequest(req)
  1186. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  1187. user.MaxSessions = 10
  1188. user.UploadBandwidth = 128
  1189. user.Permissions["/"] = []string{dataprovider.PermAny, dataprovider.PermDelete, dataprovider.PermDownload}
  1190. userAsJSON = getUserAsJSON(t, user)
  1191. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  1192. rr = executeRequest(req)
  1193. checkResponseCode(t, http.StatusOK, rr.Code)
  1194. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1195. rr = executeRequest(req)
  1196. checkResponseCode(t, http.StatusOK, rr.Code)
  1197. var updatedUser dataprovider.User
  1198. err = render.DecodeJSON(rr.Body, &updatedUser)
  1199. if err != nil {
  1200. t.Errorf("Error decoding updated user: %v", err)
  1201. }
  1202. if user.MaxSessions != updatedUser.MaxSessions || user.UploadBandwidth != updatedUser.UploadBandwidth {
  1203. t.Errorf("Error modifying user actual: %v, %v", updatedUser.MaxSessions, updatedUser.UploadBandwidth)
  1204. }
  1205. if len(updatedUser.Permissions["/"]) != 1 {
  1206. t.Errorf("permissions other than any should be removed")
  1207. }
  1208. if !utils.IsStringInSlice(dataprovider.PermAny, updatedUser.Permissions["/"]) {
  1209. t.Errorf("permissions mismatch")
  1210. }
  1211. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1212. rr = executeRequest(req)
  1213. checkResponseCode(t, http.StatusOK, rr.Code)
  1214. }
  1215. func TestGetUserByIdInvalidParamsMock(t *testing.T) {
  1216. req, _ := http.NewRequest(http.MethodGet, userPath+"/0", nil)
  1217. rr := executeRequest(req)
  1218. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1219. req, _ = http.NewRequest(http.MethodGet, userPath+"/a", nil)
  1220. rr = executeRequest(req)
  1221. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1222. }
  1223. func TestAddUserNoUsernameMock(t *testing.T) {
  1224. user := getTestUser()
  1225. user.Username = ""
  1226. userAsJSON := getUserAsJSON(t, user)
  1227. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1228. rr := executeRequest(req)
  1229. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1230. }
  1231. func TestAddUserInvalidHomeDirMock(t *testing.T) {
  1232. user := getTestUser()
  1233. user.HomeDir = "relative_path"
  1234. userAsJSON := getUserAsJSON(t, user)
  1235. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1236. rr := executeRequest(req)
  1237. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1238. }
  1239. func TestAddUserInvalidPermsMock(t *testing.T) {
  1240. user := getTestUser()
  1241. user.Permissions["/"] = []string{}
  1242. userAsJSON := getUserAsJSON(t, user)
  1243. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1244. rr := executeRequest(req)
  1245. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1246. }
  1247. func TestAddUserInvalidJsonMock(t *testing.T) {
  1248. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer([]byte("invalid json")))
  1249. rr := executeRequest(req)
  1250. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1251. }
  1252. func TestUpdateUserMock(t *testing.T) {
  1253. user := getTestUser()
  1254. userAsJSON := getUserAsJSON(t, user)
  1255. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1256. rr := executeRequest(req)
  1257. checkResponseCode(t, http.StatusOK, rr.Code)
  1258. err := render.DecodeJSON(rr.Body, &user)
  1259. if err != nil {
  1260. t.Errorf("Error get user: %v", err)
  1261. }
  1262. // permissions should not change if empty or nil
  1263. permissions := user.Permissions
  1264. user.Permissions = make(map[string][]string)
  1265. userAsJSON = getUserAsJSON(t, user)
  1266. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  1267. rr = executeRequest(req)
  1268. checkResponseCode(t, http.StatusOK, rr.Code)
  1269. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1270. rr = executeRequest(req)
  1271. checkResponseCode(t, http.StatusOK, rr.Code)
  1272. var updatedUser dataprovider.User
  1273. err = render.DecodeJSON(rr.Body, &updatedUser)
  1274. if err != nil {
  1275. t.Errorf("Error decoding updated user: %v", err)
  1276. }
  1277. for dir, perms := range permissions {
  1278. if actualPerms, ok := updatedUser.Permissions[dir]; ok {
  1279. for _, v := range actualPerms {
  1280. if !utils.IsStringInSlice(v, perms) {
  1281. t.Error("Permissions contents mismatch")
  1282. }
  1283. }
  1284. } else {
  1285. t.Error("Permissions directories mismatch")
  1286. }
  1287. }
  1288. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1289. rr = executeRequest(req)
  1290. checkResponseCode(t, http.StatusOK, rr.Code)
  1291. }
  1292. func TestUserPermissionsMock(t *testing.T) {
  1293. user := getTestUser()
  1294. user.Permissions = make(map[string][]string)
  1295. user.Permissions["/somedir"] = []string{dataprovider.PermAny}
  1296. userAsJSON := getUserAsJSON(t, user)
  1297. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1298. rr := executeRequest(req)
  1299. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1300. user.Permissions = make(map[string][]string)
  1301. user.Permissions["/"] = []string{dataprovider.PermAny}
  1302. user.Permissions[".."] = []string{dataprovider.PermAny}
  1303. userAsJSON = getUserAsJSON(t, user)
  1304. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1305. rr = executeRequest(req)
  1306. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1307. user.Permissions = make(map[string][]string)
  1308. user.Permissions["/"] = []string{dataprovider.PermAny}
  1309. userAsJSON = getUserAsJSON(t, user)
  1310. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1311. rr = executeRequest(req)
  1312. checkResponseCode(t, http.StatusOK, rr.Code)
  1313. err := render.DecodeJSON(rr.Body, &user)
  1314. if err != nil {
  1315. t.Errorf("Error get user: %v", err)
  1316. }
  1317. user.Permissions["/somedir"] = []string{"invalid"}
  1318. userAsJSON = getUserAsJSON(t, user)
  1319. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  1320. rr = executeRequest(req)
  1321. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1322. delete(user.Permissions, "/somedir")
  1323. user.Permissions["/somedir/.."] = []string{dataprovider.PermAny}
  1324. userAsJSON = getUserAsJSON(t, user)
  1325. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  1326. rr = executeRequest(req)
  1327. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1328. delete(user.Permissions, "/somedir/..")
  1329. user.Permissions["not_abs_path"] = []string{dataprovider.PermAny}
  1330. userAsJSON = getUserAsJSON(t, user)
  1331. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  1332. rr = executeRequest(req)
  1333. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1334. delete(user.Permissions, "not_abs_path")
  1335. user.Permissions["/somedir/../otherdir/"] = []string{dataprovider.PermListItems}
  1336. userAsJSON = getUserAsJSON(t, user)
  1337. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  1338. rr = executeRequest(req)
  1339. checkResponseCode(t, http.StatusOK, rr.Code)
  1340. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1341. rr = executeRequest(req)
  1342. checkResponseCode(t, http.StatusOK, rr.Code)
  1343. var updatedUser dataprovider.User
  1344. err = render.DecodeJSON(rr.Body, &updatedUser)
  1345. if err != nil {
  1346. t.Errorf("Error decoding updated user: %v", err)
  1347. }
  1348. if val, ok := updatedUser.Permissions["/otherdir"]; ok {
  1349. if !utils.IsStringInSlice(dataprovider.PermListItems, val) {
  1350. t.Error("expected permission list not found")
  1351. }
  1352. if len(val) != 1 {
  1353. t.Errorf("Unexpected number of permissions, expected 1, actual: %v", len(val))
  1354. }
  1355. } else {
  1356. t.Errorf("expected dir not found in permissions")
  1357. }
  1358. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1359. rr = executeRequest(req)
  1360. checkResponseCode(t, http.StatusOK, rr.Code)
  1361. }
  1362. func TestUpdateUserInvalidJsonMock(t *testing.T) {
  1363. user := getTestUser()
  1364. userAsJSON := getUserAsJSON(t, user)
  1365. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1366. rr := executeRequest(req)
  1367. checkResponseCode(t, http.StatusOK, rr.Code)
  1368. err := render.DecodeJSON(rr.Body, &user)
  1369. if err != nil {
  1370. t.Errorf("Error get user: %v", err)
  1371. }
  1372. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer([]byte("Invalid json")))
  1373. rr = executeRequest(req)
  1374. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1375. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1376. rr = executeRequest(req)
  1377. checkResponseCode(t, http.StatusOK, rr.Code)
  1378. }
  1379. func TestUpdateUserInvalidParamsMock(t *testing.T) {
  1380. user := getTestUser()
  1381. userAsJSON := getUserAsJSON(t, user)
  1382. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1383. rr := executeRequest(req)
  1384. checkResponseCode(t, http.StatusOK, rr.Code)
  1385. err := render.DecodeJSON(rr.Body, &user)
  1386. if err != nil {
  1387. t.Errorf("Error get user: %v", err)
  1388. }
  1389. user.HomeDir = ""
  1390. userAsJSON = getUserAsJSON(t, user)
  1391. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  1392. rr = executeRequest(req)
  1393. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1394. userID := user.ID
  1395. user.ID = 0
  1396. userAsJSON = getUserAsJSON(t, user)
  1397. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(userID, 10), bytes.NewBuffer(userAsJSON))
  1398. rr = executeRequest(req)
  1399. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1400. user.ID = userID
  1401. req, _ = http.NewRequest(http.MethodPut, userPath+"/0", bytes.NewBuffer(userAsJSON))
  1402. rr = executeRequest(req)
  1403. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1404. req, _ = http.NewRequest(http.MethodPut, userPath+"/a", bytes.NewBuffer(userAsJSON))
  1405. rr = executeRequest(req)
  1406. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1407. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1408. rr = executeRequest(req)
  1409. checkResponseCode(t, http.StatusOK, rr.Code)
  1410. }
  1411. func TestGetUsersMock(t *testing.T) {
  1412. user := getTestUser()
  1413. userAsJSON := getUserAsJSON(t, user)
  1414. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1415. rr := executeRequest(req)
  1416. checkResponseCode(t, http.StatusOK, rr.Code)
  1417. err := render.DecodeJSON(rr.Body, &user)
  1418. if err != nil {
  1419. t.Errorf("Error get user: %v", err)
  1420. }
  1421. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=510&offset=0&order=ASC&username="+defaultUsername, nil)
  1422. rr = executeRequest(req)
  1423. checkResponseCode(t, http.StatusOK, rr.Code)
  1424. var users []dataprovider.User
  1425. err = render.DecodeJSON(rr.Body, &users)
  1426. if err != nil {
  1427. t.Errorf("Error decoding users: %v", err)
  1428. }
  1429. if len(users) != 1 {
  1430. t.Errorf("1 user is expected")
  1431. }
  1432. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=a&offset=0&order=ASC", nil)
  1433. rr = executeRequest(req)
  1434. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1435. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=a&order=ASC", nil)
  1436. rr = executeRequest(req)
  1437. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1438. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASCa", nil)
  1439. rr = executeRequest(req)
  1440. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1441. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1442. rr = executeRequest(req)
  1443. checkResponseCode(t, http.StatusOK, rr.Code)
  1444. }
  1445. func TestDeleteUserInvalidParamsMock(t *testing.T) {
  1446. req, _ := http.NewRequest(http.MethodDelete, userPath+"/0", nil)
  1447. rr := executeRequest(req)
  1448. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1449. req, _ = http.NewRequest(http.MethodDelete, userPath+"/a", nil)
  1450. rr = executeRequest(req)
  1451. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1452. }
  1453. func TestGetQuotaScansMock(t *testing.T) {
  1454. req, err := http.NewRequest("GET", quotaScanPath, nil)
  1455. if err != nil {
  1456. t.Errorf("error get quota scan: %v", err)
  1457. }
  1458. rr := executeRequest(req)
  1459. checkResponseCode(t, http.StatusOK, rr.Code)
  1460. }
  1461. func TestStartQuotaScanMock(t *testing.T) {
  1462. user := getTestUser()
  1463. userAsJSON := getUserAsJSON(t, user)
  1464. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1465. rr := executeRequest(req)
  1466. checkResponseCode(t, http.StatusOK, rr.Code)
  1467. err := render.DecodeJSON(rr.Body, &user)
  1468. if err != nil {
  1469. t.Errorf("Error get user: %v", err)
  1470. }
  1471. _, err = os.Stat(user.HomeDir)
  1472. if err == nil {
  1473. os.Remove(user.HomeDir)
  1474. }
  1475. // simulate a duplicate quota scan
  1476. userAsJSON = getUserAsJSON(t, user)
  1477. sftpd.AddQuotaScan(user.Username)
  1478. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  1479. rr = executeRequest(req)
  1480. checkResponseCode(t, http.StatusConflict, rr.Code)
  1481. sftpd.RemoveQuotaScan(user.Username)
  1482. userAsJSON = getUserAsJSON(t, user)
  1483. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  1484. rr = executeRequest(req)
  1485. checkResponseCode(t, http.StatusCreated, rr.Code)
  1486. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  1487. rr = executeRequest(req)
  1488. checkResponseCode(t, http.StatusOK, rr.Code)
  1489. var scans []sftpd.ActiveQuotaScan
  1490. err = render.DecodeJSON(rr.Body, &scans)
  1491. if err != nil {
  1492. t.Errorf("Error get active scans: %v", err)
  1493. }
  1494. for len(scans) > 0 {
  1495. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  1496. rr = executeRequest(req)
  1497. checkResponseCode(t, http.StatusOK, rr.Code)
  1498. err = render.DecodeJSON(rr.Body, &scans)
  1499. if err != nil {
  1500. t.Errorf("Error get active scans: %v", err)
  1501. break
  1502. }
  1503. time.Sleep(100 * time.Millisecond)
  1504. }
  1505. _, err = os.Stat(user.HomeDir)
  1506. if err != nil && os.IsNotExist(err) {
  1507. os.MkdirAll(user.HomeDir, 0777)
  1508. }
  1509. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  1510. rr = executeRequest(req)
  1511. checkResponseCode(t, http.StatusCreated, rr.Code)
  1512. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  1513. rr = executeRequest(req)
  1514. checkResponseCode(t, http.StatusOK, rr.Code)
  1515. err = render.DecodeJSON(rr.Body, &scans)
  1516. if err != nil {
  1517. t.Errorf("Error get active scans: %v", err)
  1518. }
  1519. for len(scans) > 0 {
  1520. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  1521. rr = executeRequest(req)
  1522. checkResponseCode(t, http.StatusOK, rr.Code)
  1523. err = render.DecodeJSON(rr.Body, &scans)
  1524. if err != nil {
  1525. t.Errorf("Error get active scans: %v", err)
  1526. break
  1527. }
  1528. time.Sleep(100 * time.Millisecond)
  1529. }
  1530. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1531. rr = executeRequest(req)
  1532. checkResponseCode(t, http.StatusOK, rr.Code)
  1533. os.RemoveAll(user.GetHomeDir())
  1534. }
  1535. func TestStartQuotaScanBadUserMock(t *testing.T) {
  1536. user := getTestUser()
  1537. userAsJSON := getUserAsJSON(t, user)
  1538. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  1539. rr := executeRequest(req)
  1540. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1541. }
  1542. func TestStartQuotaScanNonExistentUserMock(t *testing.T) {
  1543. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer([]byte("invalid json")))
  1544. rr := executeRequest(req)
  1545. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1546. }
  1547. func TestGetVersionMock(t *testing.T) {
  1548. req, _ := http.NewRequest(http.MethodGet, versionPath, nil)
  1549. rr := executeRequest(req)
  1550. checkResponseCode(t, http.StatusOK, rr.Code)
  1551. }
  1552. func TestGetConnectionsMock(t *testing.T) {
  1553. req, _ := http.NewRequest(http.MethodGet, activeConnectionsPath, nil)
  1554. rr := executeRequest(req)
  1555. checkResponseCode(t, http.StatusOK, rr.Code)
  1556. }
  1557. func TestDeleteActiveConnectionMock(t *testing.T) {
  1558. req, _ := http.NewRequest(http.MethodDelete, activeConnectionsPath+"/connectionID", nil)
  1559. rr := executeRequest(req)
  1560. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1561. }
  1562. func TestNotFoundMock(t *testing.T) {
  1563. req, _ := http.NewRequest(http.MethodGet, "/non/existing/path", nil)
  1564. rr := executeRequest(req)
  1565. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1566. }
  1567. func TestMethodNotAllowedMock(t *testing.T) {
  1568. req, _ := http.NewRequest(http.MethodPost, activeConnectionsPath, nil)
  1569. rr := executeRequest(req)
  1570. checkResponseCode(t, http.StatusMethodNotAllowed, rr.Code)
  1571. }
  1572. func TestMetricsMock(t *testing.T) {
  1573. req, _ := http.NewRequest(http.MethodGet, metricsPath, nil)
  1574. rr := executeRequest(req)
  1575. checkResponseCode(t, http.StatusOK, rr.Code)
  1576. }
  1577. func TestGetWebRootMock(t *testing.T) {
  1578. req, _ := http.NewRequest(http.MethodGet, "/", nil)
  1579. rr := executeRequest(req)
  1580. checkResponseCode(t, http.StatusMovedPermanently, rr.Code)
  1581. req, _ = http.NewRequest(http.MethodGet, webBasePath, nil)
  1582. rr = executeRequest(req)
  1583. checkResponseCode(t, http.StatusMovedPermanently, rr.Code)
  1584. }
  1585. func TestBasicWebUsersMock(t *testing.T) {
  1586. user := getTestUser()
  1587. userAsJSON := getUserAsJSON(t, user)
  1588. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1589. rr := executeRequest(req)
  1590. checkResponseCode(t, http.StatusOK, rr.Code)
  1591. err := render.DecodeJSON(rr.Body, &user)
  1592. if err != nil {
  1593. t.Errorf("Error get user: %v", err)
  1594. }
  1595. user1 := getTestUser()
  1596. user1.Username += "1"
  1597. user1AsJSON := getUserAsJSON(t, user1)
  1598. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(user1AsJSON))
  1599. rr = executeRequest(req)
  1600. checkResponseCode(t, http.StatusOK, rr.Code)
  1601. err = render.DecodeJSON(rr.Body, &user1)
  1602. if err != nil {
  1603. t.Errorf("Error get user1: %v", err)
  1604. }
  1605. req, _ = http.NewRequest(http.MethodGet, webUsersPath, nil)
  1606. rr = executeRequest(req)
  1607. checkResponseCode(t, http.StatusOK, rr.Code)
  1608. req, _ = http.NewRequest(http.MethodGet, webUsersPath+"?qlimit=a", nil)
  1609. rr = executeRequest(req)
  1610. checkResponseCode(t, http.StatusOK, rr.Code)
  1611. req, _ = http.NewRequest(http.MethodGet, webUsersPath+"?qlimit=1", nil)
  1612. rr = executeRequest(req)
  1613. checkResponseCode(t, http.StatusOK, rr.Code)
  1614. req, _ = http.NewRequest(http.MethodGet, webUserPath, nil)
  1615. rr = executeRequest(req)
  1616. checkResponseCode(t, http.StatusOK, rr.Code)
  1617. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1618. rr = executeRequest(req)
  1619. checkResponseCode(t, http.StatusOK, rr.Code)
  1620. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/0", nil)
  1621. rr = executeRequest(req)
  1622. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1623. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/a", nil)
  1624. rr = executeRequest(req)
  1625. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1626. form := make(url.Values)
  1627. form.Set("username", user.Username)
  1628. b, contentType, _ := getMultipartFormData(form, "", "")
  1629. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1630. req.Header.Set("Content-Type", contentType)
  1631. rr = executeRequest(req)
  1632. checkResponseCode(t, http.StatusOK, rr.Code)
  1633. b, contentType, _ = getMultipartFormData(form, "", "")
  1634. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  1635. req.Header.Set("Content-Type", contentType)
  1636. rr = executeRequest(req)
  1637. checkResponseCode(t, http.StatusOK, rr.Code)
  1638. b, contentType, _ = getMultipartFormData(form, "", "")
  1639. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/0", &b)
  1640. req.Header.Set("Content-Type", contentType)
  1641. rr = executeRequest(req)
  1642. checkResponseCode(t, http.StatusNotFound, rr.Code)
  1643. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/a", &b)
  1644. req.Header.Set("Content-Type", contentType)
  1645. rr = executeRequest(req)
  1646. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  1647. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1648. rr = executeRequest(req)
  1649. checkResponseCode(t, http.StatusOK, rr.Code)
  1650. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user1.ID, 10), nil)
  1651. rr = executeRequest(req)
  1652. checkResponseCode(t, http.StatusOK, rr.Code)
  1653. }
  1654. func TestWebUserAddMock(t *testing.T) {
  1655. user := getTestUser()
  1656. user.UploadBandwidth = 32
  1657. user.DownloadBandwidth = 64
  1658. user.UID = 1000
  1659. mappedDir := filepath.Join(os.TempDir(), "mapped")
  1660. form := make(url.Values)
  1661. form.Set("username", user.Username)
  1662. form.Set("home_dir", user.HomeDir)
  1663. form.Set("password", user.Password)
  1664. form.Set("status", strconv.Itoa(user.Status))
  1665. form.Set("expiration_date", "")
  1666. form.Set("permissions", "*")
  1667. form.Set("sub_dirs_permissions", " /subdir::list ,download ")
  1668. form.Set("virtual_folders", fmt.Sprintf(" /vdir:: %v ", mappedDir))
  1669. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  1670. form.Set("denied_extensions", "/dir1::.zip")
  1671. b, contentType, _ := getMultipartFormData(form, "", "")
  1672. // test invalid url escape
  1673. req, _ := http.NewRequest(http.MethodPost, webUserPath+"?a=%2", &b)
  1674. req.Header.Set("Content-Type", contentType)
  1675. rr := executeRequest(req)
  1676. checkResponseCode(t, http.StatusOK, rr.Code)
  1677. form.Set("public_keys", testPubKey)
  1678. form.Set("uid", strconv.FormatInt(int64(user.UID), 10))
  1679. form.Set("gid", "a")
  1680. b, contentType, _ = getMultipartFormData(form, "", "")
  1681. // test invalid gid
  1682. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1683. req.Header.Set("Content-Type", contentType)
  1684. rr = executeRequest(req)
  1685. checkResponseCode(t, http.StatusOK, rr.Code)
  1686. form.Set("gid", "0")
  1687. form.Set("max_sessions", "a")
  1688. b, contentType, _ = getMultipartFormData(form, "", "")
  1689. // test invalid max sessions
  1690. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1691. req.Header.Set("Content-Type", contentType)
  1692. rr = executeRequest(req)
  1693. checkResponseCode(t, http.StatusOK, rr.Code)
  1694. form.Set("max_sessions", "0")
  1695. form.Set("quota_size", "a")
  1696. b, contentType, _ = getMultipartFormData(form, "", "")
  1697. // test invalid quota size
  1698. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1699. req.Header.Set("Content-Type", contentType)
  1700. rr = executeRequest(req)
  1701. checkResponseCode(t, http.StatusOK, rr.Code)
  1702. form.Set("quota_size", "0")
  1703. form.Set("quota_files", "a")
  1704. b, contentType, _ = getMultipartFormData(form, "", "")
  1705. // test invalid quota files
  1706. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1707. req.Header.Set("Content-Type", contentType)
  1708. rr = executeRequest(req)
  1709. checkResponseCode(t, http.StatusOK, rr.Code)
  1710. form.Set("quota_files", "0")
  1711. form.Set("upload_bandwidth", "a")
  1712. b, contentType, _ = getMultipartFormData(form, "", "")
  1713. // test invalid upload bandwidth
  1714. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1715. req.Header.Set("Content-Type", contentType)
  1716. rr = executeRequest(req)
  1717. checkResponseCode(t, http.StatusOK, rr.Code)
  1718. form.Set("upload_bandwidth", strconv.FormatInt(user.UploadBandwidth, 10))
  1719. form.Set("download_bandwidth", "a")
  1720. b, contentType, _ = getMultipartFormData(form, "", "")
  1721. // test invalid download bandwidth
  1722. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1723. req.Header.Set("Content-Type", contentType)
  1724. rr = executeRequest(req)
  1725. checkResponseCode(t, http.StatusOK, rr.Code)
  1726. form.Set("download_bandwidth", strconv.FormatInt(user.DownloadBandwidth, 10))
  1727. form.Set("status", "a")
  1728. b, contentType, _ = getMultipartFormData(form, "", "")
  1729. // test invalid status
  1730. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1731. req.Header.Set("Content-Type", contentType)
  1732. rr = executeRequest(req)
  1733. checkResponseCode(t, http.StatusOK, rr.Code)
  1734. form.Set("status", strconv.Itoa(user.Status))
  1735. form.Set("expiration_date", "123")
  1736. b, contentType, _ = getMultipartFormData(form, "", "")
  1737. // test invalid expiration date
  1738. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1739. req.Header.Set("Content-Type", contentType)
  1740. rr = executeRequest(req)
  1741. checkResponseCode(t, http.StatusOK, rr.Code)
  1742. form.Set("expiration_date", "")
  1743. form.Set("allowed_ip", "invalid,ip")
  1744. b, contentType, _ = getMultipartFormData(form, "", "")
  1745. // test invalid allowed_ip
  1746. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1747. req.Header.Set("Content-Type", contentType)
  1748. rr = executeRequest(req)
  1749. checkResponseCode(t, http.StatusOK, rr.Code)
  1750. form.Set("allowed_ip", "")
  1751. form.Set("denied_ip", "192.168.1.2") // it should be 192.168.1.2/32
  1752. b, contentType, _ = getMultipartFormData(form, "", "")
  1753. // test invalid denied_ip
  1754. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1755. req.Header.Set("Content-Type", contentType)
  1756. rr = executeRequest(req)
  1757. checkResponseCode(t, http.StatusOK, rr.Code)
  1758. form.Set("denied_ip", "")
  1759. b, contentType, _ = getMultipartFormData(form, "", "")
  1760. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1761. req.Header.Set("Content-Type", contentType)
  1762. rr = executeRequest(req)
  1763. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  1764. // the user already exists, was created with the above request
  1765. b, contentType, _ = getMultipartFormData(form, "", "")
  1766. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  1767. req.Header.Set("Content-Type", contentType)
  1768. rr = executeRequest(req)
  1769. checkResponseCode(t, http.StatusOK, rr.Code)
  1770. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  1771. rr = executeRequest(req)
  1772. checkResponseCode(t, http.StatusOK, rr.Code)
  1773. var users []dataprovider.User
  1774. err := render.DecodeJSON(rr.Body, &users)
  1775. if err != nil {
  1776. t.Errorf("Error decoding users: %v", err)
  1777. }
  1778. if len(users) != 1 {
  1779. t.Errorf("1 user is expected, actual: %v", len(users))
  1780. }
  1781. newUser := users[0]
  1782. if newUser.UID != user.UID {
  1783. t.Errorf("uid does not match")
  1784. }
  1785. if newUser.UploadBandwidth != user.UploadBandwidth {
  1786. t.Errorf("upload_bandwidth does not match")
  1787. }
  1788. if newUser.DownloadBandwidth != user.DownloadBandwidth {
  1789. t.Errorf("download_bandwidth does not match")
  1790. }
  1791. if !utils.IsStringInSlice(testPubKey, newUser.PublicKeys) {
  1792. t.Errorf("public_keys does not match")
  1793. }
  1794. if val, ok := newUser.Permissions["/subdir"]; ok {
  1795. if !utils.IsStringInSlice(dataprovider.PermListItems, val) || !utils.IsStringInSlice(dataprovider.PermDownload, val) {
  1796. t.Error("permssions for /subdir does not match")
  1797. }
  1798. } else {
  1799. t.Errorf("user permissions must contain /somedir, actual: %v", newUser.Permissions)
  1800. }
  1801. vfolderFoumd := false
  1802. for _, v := range newUser.VirtualFolders {
  1803. if v.VirtualPath == "/vdir" && v.MappedPath == mappedDir {
  1804. vfolderFoumd = true
  1805. }
  1806. }
  1807. if !vfolderFoumd {
  1808. t.Errorf("virtual folders must contain /vdir, actual: %+v", newUser.VirtualFolders)
  1809. }
  1810. extFilters := newUser.Filters.FileExtensions[0]
  1811. if !utils.IsStringInSlice(".zip", extFilters.DeniedExtensions) {
  1812. t.Errorf("unexpected denied extensions: %v", extFilters.DeniedExtensions)
  1813. }
  1814. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(newUser.ID, 10), nil)
  1815. rr = executeRequest(req)
  1816. checkResponseCode(t, http.StatusOK, rr.Code)
  1817. }
  1818. func TestWebUserUpdateMock(t *testing.T) {
  1819. user := getTestUser()
  1820. userAsJSON := getUserAsJSON(t, user)
  1821. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1822. rr := executeRequest(req)
  1823. checkResponseCode(t, http.StatusOK, rr.Code)
  1824. err := render.DecodeJSON(rr.Body, &user)
  1825. if err != nil {
  1826. t.Errorf("Error get user: %v", err)
  1827. }
  1828. user.MaxSessions = 1
  1829. user.QuotaFiles = 2
  1830. user.QuotaSize = 3
  1831. user.GID = 1000
  1832. form := make(url.Values)
  1833. form.Set("username", user.Username)
  1834. form.Set("home_dir", user.HomeDir)
  1835. form.Set("uid", "0")
  1836. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  1837. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  1838. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  1839. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  1840. form.Set("upload_bandwidth", "0")
  1841. form.Set("download_bandwidth", "0")
  1842. form.Set("permissions", "*")
  1843. form.Set("sub_dirs_permissions", "/otherdir :: list ,upload ")
  1844. form.Set("status", strconv.Itoa(user.Status))
  1845. form.Set("expiration_date", "2020-01-01 00:00:00")
  1846. form.Set("allowed_ip", " 192.168.1.3/32, 192.168.2.0/24 ")
  1847. form.Set("denied_ip", " 10.0.0.2/32 ")
  1848. form.Set("denied_extensions", "/dir1::.zip")
  1849. form.Set("ssh_login_methods", dataprovider.SSHLoginMethodKeyboardInteractive)
  1850. b, contentType, _ := getMultipartFormData(form, "", "")
  1851. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  1852. req.Header.Set("Content-Type", contentType)
  1853. rr = executeRequest(req)
  1854. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  1855. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  1856. rr = executeRequest(req)
  1857. checkResponseCode(t, http.StatusOK, rr.Code)
  1858. var users []dataprovider.User
  1859. render.DecodeJSON(rr.Body, &users)
  1860. if len(users) != 1 {
  1861. t.Errorf("1 user is expected")
  1862. }
  1863. updateUser := users[0]
  1864. if user.HomeDir != updateUser.HomeDir {
  1865. t.Errorf("home dir does not match")
  1866. }
  1867. if user.MaxSessions != updateUser.MaxSessions {
  1868. t.Errorf("max_sessions does not match")
  1869. }
  1870. if user.QuotaFiles != updateUser.QuotaFiles {
  1871. t.Errorf("quota_files does not match")
  1872. }
  1873. if user.QuotaSize != updateUser.QuotaSize {
  1874. t.Errorf("quota_size does not match")
  1875. }
  1876. if user.GID != updateUser.GID {
  1877. t.Errorf("gid does not match")
  1878. }
  1879. if val, ok := updateUser.Permissions["/otherdir"]; ok {
  1880. if !utils.IsStringInSlice(dataprovider.PermListItems, val) || !utils.IsStringInSlice(dataprovider.PermUpload, val) {
  1881. t.Error("permssions for /otherdir does not match")
  1882. }
  1883. } else {
  1884. t.Errorf("user permissions must contains /otherdir, actual: %v", updateUser.Permissions)
  1885. }
  1886. if !utils.IsStringInSlice("192.168.1.3/32", updateUser.Filters.AllowedIP) {
  1887. t.Errorf("Allowed IP/Mask does not match: %v", updateUser.Filters.AllowedIP)
  1888. }
  1889. if !utils.IsStringInSlice("10.0.0.2/32", updateUser.Filters.DeniedIP) {
  1890. t.Errorf("Denied IP/Mask does not match: %v", updateUser.Filters.DeniedIP)
  1891. }
  1892. if !utils.IsStringInSlice(dataprovider.SSHLoginMethodKeyboardInteractive, updateUser.Filters.DeniedLoginMethods) {
  1893. t.Errorf("Denied login methods does not match: %v", updateUser.Filters.DeniedLoginMethods)
  1894. }
  1895. if !utils.IsStringInSlice(".zip", updateUser.Filters.FileExtensions[0].DeniedExtensions) {
  1896. t.Errorf("unexpected extensions filter: %+v", updateUser.Filters.FileExtensions)
  1897. }
  1898. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1899. rr = executeRequest(req)
  1900. checkResponseCode(t, http.StatusOK, rr.Code)
  1901. }
  1902. func TestWebUserS3Mock(t *testing.T) {
  1903. user := getTestUser()
  1904. userAsJSON := getUserAsJSON(t, user)
  1905. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  1906. rr := executeRequest(req)
  1907. checkResponseCode(t, http.StatusOK, rr.Code)
  1908. err := render.DecodeJSON(rr.Body, &user)
  1909. if err != nil {
  1910. t.Errorf("Error get user: %v", err)
  1911. }
  1912. user.FsConfig.Provider = 1
  1913. user.FsConfig.S3Config.Bucket = "test"
  1914. user.FsConfig.S3Config.Region = "eu-west-1"
  1915. user.FsConfig.S3Config.AccessKey = "access-key"
  1916. user.FsConfig.S3Config.AccessSecret = "access-secret"
  1917. user.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/path?a=b"
  1918. user.FsConfig.S3Config.StorageClass = "Standard"
  1919. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir/"
  1920. form := make(url.Values)
  1921. form.Set("username", user.Username)
  1922. form.Set("home_dir", user.HomeDir)
  1923. form.Set("uid", "0")
  1924. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  1925. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  1926. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  1927. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  1928. form.Set("upload_bandwidth", "0")
  1929. form.Set("download_bandwidth", "0")
  1930. form.Set("permissions", "*")
  1931. form.Set("sub_dirs_permissions", "")
  1932. form.Set("status", strconv.Itoa(user.Status))
  1933. form.Set("expiration_date", "2020-01-01 00:00:00")
  1934. form.Set("allowed_ip", "")
  1935. form.Set("denied_ip", "")
  1936. form.Set("fs_provider", "1")
  1937. form.Set("s3_bucket", user.FsConfig.S3Config.Bucket)
  1938. form.Set("s3_region", user.FsConfig.S3Config.Region)
  1939. form.Set("s3_access_key", user.FsConfig.S3Config.AccessKey)
  1940. form.Set("s3_access_secret", user.FsConfig.S3Config.AccessSecret)
  1941. form.Set("s3_storage_class", user.FsConfig.S3Config.StorageClass)
  1942. form.Set("s3_endpoint", user.FsConfig.S3Config.Endpoint)
  1943. form.Set("s3_key_prefix", user.FsConfig.S3Config.KeyPrefix)
  1944. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  1945. form.Set("denied_extensions", "/dir2::.zip")
  1946. b, contentType, _ := getMultipartFormData(form, "", "")
  1947. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  1948. req.Header.Set("Content-Type", contentType)
  1949. rr = executeRequest(req)
  1950. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  1951. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  1952. rr = executeRequest(req)
  1953. checkResponseCode(t, http.StatusOK, rr.Code)
  1954. var users []dataprovider.User
  1955. err = render.DecodeJSON(rr.Body, &users)
  1956. if err != nil {
  1957. t.Errorf("Error decoding users: %v", err)
  1958. }
  1959. if len(users) != 1 {
  1960. t.Errorf("1 user is expected")
  1961. }
  1962. updateUser := users[0]
  1963. if updateUser.ExpirationDate != 1577836800000 {
  1964. t.Errorf("invalid expiration date: %v", updateUser.ExpirationDate)
  1965. }
  1966. if updateUser.FsConfig.Provider != user.FsConfig.Provider {
  1967. t.Error("fs provider mismatch")
  1968. }
  1969. if updateUser.FsConfig.S3Config.Bucket != user.FsConfig.S3Config.Bucket {
  1970. t.Error("s3 bucket mismatch")
  1971. }
  1972. if updateUser.FsConfig.S3Config.Region != user.FsConfig.S3Config.Region {
  1973. t.Error("s3 region mismatch")
  1974. }
  1975. if updateUser.FsConfig.S3Config.AccessKey != user.FsConfig.S3Config.AccessKey {
  1976. t.Error("s3 access key mismatch")
  1977. }
  1978. if !strings.HasPrefix(updateUser.FsConfig.S3Config.AccessSecret, "$aes$") {
  1979. t.Error("s3 access secret is not encrypted")
  1980. }
  1981. if updateUser.FsConfig.S3Config.StorageClass != user.FsConfig.S3Config.StorageClass {
  1982. t.Error("s3 storage class mismatch")
  1983. }
  1984. if updateUser.FsConfig.S3Config.Endpoint != user.FsConfig.S3Config.Endpoint {
  1985. t.Error("s3 endpoint mismatch")
  1986. }
  1987. if updateUser.FsConfig.S3Config.KeyPrefix != user.FsConfig.S3Config.KeyPrefix {
  1988. t.Error("s3 key prefix mismatch")
  1989. }
  1990. if len(updateUser.Filters.FileExtensions) != 2 {
  1991. t.Errorf("unexpected extensions filter: %+v", updateUser.Filters.FileExtensions)
  1992. }
  1993. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  1994. rr = executeRequest(req)
  1995. checkResponseCode(t, http.StatusOK, rr.Code)
  1996. }
  1997. func TestWebUserGCSMock(t *testing.T) {
  1998. user := getTestUser()
  1999. userAsJSON := getUserAsJSON(t, user)
  2000. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2001. rr := executeRequest(req)
  2002. checkResponseCode(t, http.StatusOK, rr.Code)
  2003. err := render.DecodeJSON(rr.Body, &user)
  2004. if err != nil {
  2005. t.Errorf("Error get user: %v", err)
  2006. }
  2007. credentialsFilePath := filepath.Join(os.TempDir(), "gcs.json")
  2008. err = createTestFile(credentialsFilePath, 0)
  2009. if err != nil {
  2010. t.Errorf("unable to create credential test file: %v", err)
  2011. }
  2012. user.FsConfig.Provider = 2
  2013. user.FsConfig.GCSConfig.Bucket = "test"
  2014. user.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir/"
  2015. user.FsConfig.GCSConfig.StorageClass = "standard"
  2016. form := make(url.Values)
  2017. form.Set("username", user.Username)
  2018. form.Set("home_dir", user.HomeDir)
  2019. form.Set("uid", "0")
  2020. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  2021. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  2022. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  2023. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  2024. form.Set("upload_bandwidth", "0")
  2025. form.Set("download_bandwidth", "0")
  2026. form.Set("permissions", "*")
  2027. form.Set("sub_dirs_permissions", "")
  2028. form.Set("status", strconv.Itoa(user.Status))
  2029. form.Set("expiration_date", "2020-01-01 00:00:00")
  2030. form.Set("allowed_ip", "")
  2031. form.Set("denied_ip", "")
  2032. form.Set("fs_provider", "2")
  2033. form.Set("gcs_bucket", user.FsConfig.GCSConfig.Bucket)
  2034. form.Set("gcs_storage_class", user.FsConfig.GCSConfig.StorageClass)
  2035. form.Set("gcs_key_prefix", user.FsConfig.GCSConfig.KeyPrefix)
  2036. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  2037. b, contentType, _ := getMultipartFormData(form, "", "")
  2038. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  2039. req.Header.Set("Content-Type", contentType)
  2040. rr = executeRequest(req)
  2041. checkResponseCode(t, http.StatusOK, rr.Code)
  2042. b, contentType, _ = getMultipartFormData(form, "gcs_credential_file", credentialsFilePath)
  2043. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  2044. req.Header.Set("Content-Type", contentType)
  2045. rr = executeRequest(req)
  2046. checkResponseCode(t, http.StatusOK, rr.Code)
  2047. err = createTestFile(credentialsFilePath, 4096)
  2048. if err != nil {
  2049. t.Errorf("unable to create credential test file: %v", err)
  2050. }
  2051. b, contentType, _ = getMultipartFormData(form, "gcs_credential_file", credentialsFilePath)
  2052. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  2053. req.Header.Set("Content-Type", contentType)
  2054. rr = executeRequest(req)
  2055. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  2056. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  2057. rr = executeRequest(req)
  2058. checkResponseCode(t, http.StatusOK, rr.Code)
  2059. var users []dataprovider.User
  2060. render.DecodeJSON(rr.Body, &users)
  2061. if len(users) != 1 {
  2062. t.Errorf("1 user is expected")
  2063. }
  2064. updateUser := users[0]
  2065. if updateUser.ExpirationDate != 1577836800000 {
  2066. t.Errorf("invalid expiration date: %v", updateUser.ExpirationDate)
  2067. }
  2068. if updateUser.FsConfig.Provider != user.FsConfig.Provider {
  2069. t.Error("fs provider mismatch")
  2070. }
  2071. if updateUser.FsConfig.GCSConfig.Bucket != user.FsConfig.GCSConfig.Bucket {
  2072. t.Error("GCS bucket mismatch")
  2073. }
  2074. if updateUser.FsConfig.GCSConfig.StorageClass != user.FsConfig.GCSConfig.StorageClass {
  2075. t.Error("GCS storage class mismatch")
  2076. }
  2077. if updateUser.FsConfig.GCSConfig.KeyPrefix != user.FsConfig.GCSConfig.KeyPrefix {
  2078. t.Error("GCS key prefix mismatch")
  2079. }
  2080. if updateUser.Filters.FileExtensions[0].Path != "/dir1" {
  2081. t.Errorf("unexpected extensions filter: %+v", updateUser.Filters.FileExtensions)
  2082. }
  2083. form.Set("gcs_auto_credentials", "on")
  2084. b, contentType, _ = getMultipartFormData(form, "", "")
  2085. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  2086. req.Header.Set("Content-Type", contentType)
  2087. rr = executeRequest(req)
  2088. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  2089. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  2090. rr = executeRequest(req)
  2091. checkResponseCode(t, http.StatusOK, rr.Code)
  2092. err = render.DecodeJSON(rr.Body, &users)
  2093. if err != nil {
  2094. t.Errorf("Error decoding users: %v", err)
  2095. }
  2096. if len(users) != 1 {
  2097. t.Errorf("1 user is expected")
  2098. }
  2099. updateUser = users[0]
  2100. if updateUser.FsConfig.GCSConfig.AutomaticCredentials != 1 {
  2101. t.Error("GCS automatic credentials mismatch")
  2102. }
  2103. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2104. rr = executeRequest(req)
  2105. checkResponseCode(t, http.StatusOK, rr.Code)
  2106. os.Remove(credentialsFilePath)
  2107. }
  2108. func TestProviderClosedMock(t *testing.T) {
  2109. if providerDriverName == dataprovider.BoltDataProviderName {
  2110. t.Skip("skipping test provider errors for bolt provider")
  2111. }
  2112. dataProvider := dataprovider.GetProvider()
  2113. dataprovider.Close(dataProvider)
  2114. req, _ := http.NewRequest(http.MethodGet, webUsersPath, nil)
  2115. rr := executeRequest(req)
  2116. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  2117. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/0", nil)
  2118. rr = executeRequest(req)
  2119. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  2120. form := make(url.Values)
  2121. form.Set("username", "test")
  2122. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/0", strings.NewReader(form.Encode()))
  2123. rr = executeRequest(req)
  2124. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  2125. config.LoadConfig(configDir, "")
  2126. providerConf := config.GetProviderConf()
  2127. providerConf.CredentialsPath = credentialsPath
  2128. os.RemoveAll(credentialsPath)
  2129. err := dataprovider.Initialize(providerConf, configDir)
  2130. if err != nil {
  2131. t.Errorf("error initializing data provider")
  2132. }
  2133. httpd.SetDataProvider(dataprovider.GetProvider())
  2134. sftpd.SetDataProvider(dataprovider.GetProvider())
  2135. }
  2136. func TestGetWebConnectionsMock(t *testing.T) {
  2137. req, _ := http.NewRequest(http.MethodGet, webConnectionsPath, nil)
  2138. rr := executeRequest(req)
  2139. checkResponseCode(t, http.StatusOK, rr.Code)
  2140. }
  2141. func TestStaticFilesMock(t *testing.T) {
  2142. req, _ := http.NewRequest(http.MethodGet, "/static/favicon.ico", nil)
  2143. rr := executeRequest(req)
  2144. checkResponseCode(t, http.StatusOK, rr.Code)
  2145. }
  2146. func waitTCPListening(address string) {
  2147. for {
  2148. conn, err := net.Dial("tcp", address)
  2149. if err != nil {
  2150. logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
  2151. time.Sleep(100 * time.Millisecond)
  2152. continue
  2153. }
  2154. logger.InfoToConsole("tcp server %v now listening\n", address)
  2155. defer conn.Close()
  2156. break
  2157. }
  2158. }
  2159. func getTestUser() dataprovider.User {
  2160. user := dataprovider.User{
  2161. Username: defaultUsername,
  2162. Password: defaultPassword,
  2163. HomeDir: filepath.Join(homeBasePath, defaultUsername),
  2164. Status: 1,
  2165. }
  2166. user.Permissions = make(map[string][]string)
  2167. user.Permissions["/"] = defaultPerms
  2168. return user
  2169. }
  2170. func getUserAsJSON(t *testing.T, user dataprovider.User) []byte {
  2171. json, err := json.Marshal(user)
  2172. if err != nil {
  2173. t.Errorf("error get user as json: %v", err)
  2174. return []byte("{}")
  2175. }
  2176. return json
  2177. }
  2178. func executeRequest(req *http.Request) *httptest.ResponseRecorder {
  2179. rr := httptest.NewRecorder()
  2180. testServer.Config.Handler.ServeHTTP(rr, req)
  2181. return rr
  2182. }
  2183. func checkResponseCode(t *testing.T, expected, actual int) {
  2184. if expected != actual {
  2185. t.Errorf("Expected response code %d. Got %d", expected, actual)
  2186. }
  2187. }
  2188. func createTestFile(path string, size int64) error {
  2189. baseDir := filepath.Dir(path)
  2190. if _, err := os.Stat(baseDir); os.IsNotExist(err) {
  2191. os.MkdirAll(baseDir, 0777)
  2192. }
  2193. content := make([]byte, size)
  2194. if size > 0 {
  2195. _, err := rand.Read(content)
  2196. if err != nil {
  2197. return err
  2198. }
  2199. }
  2200. return ioutil.WriteFile(path, content, 0666)
  2201. }
  2202. func getMultipartFormData(values url.Values, fileFieldName, filePath string) (bytes.Buffer, string, error) {
  2203. var b bytes.Buffer
  2204. w := multipart.NewWriter(&b)
  2205. for k, v := range values {
  2206. for _, s := range v {
  2207. if err := w.WriteField(k, s); err != nil {
  2208. return b, "", err
  2209. }
  2210. }
  2211. }
  2212. if len(fileFieldName) > 0 && len(filePath) > 0 {
  2213. fw, err := w.CreateFormFile(fileFieldName, filepath.Base(filePath))
  2214. if err != nil {
  2215. return b, "", err
  2216. }
  2217. f, err := os.Open(filePath)
  2218. if err != nil {
  2219. return b, "", err
  2220. }
  2221. if _, err = io.Copy(fw, f); err != nil {
  2222. return b, "", err
  2223. }
  2224. }
  2225. err := w.Close()
  2226. return b, w.FormDataContentType(), err
  2227. }