httpd_test.go 162 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085
  1. package httpd_test
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/json"
  6. "fmt"
  7. "io"
  8. "io/ioutil"
  9. "mime/multipart"
  10. "net"
  11. "net/http"
  12. "net/http/httptest"
  13. "net/url"
  14. "os"
  15. "path/filepath"
  16. "runtime"
  17. "strconv"
  18. "strings"
  19. "testing"
  20. "time"
  21. "github.com/go-chi/render"
  22. _ "github.com/go-sql-driver/mysql"
  23. _ "github.com/lib/pq"
  24. _ "github.com/mattn/go-sqlite3"
  25. "github.com/rs/zerolog"
  26. "github.com/stretchr/testify/assert"
  27. "github.com/stretchr/testify/require"
  28. "github.com/drakkan/sftpgo/common"
  29. "github.com/drakkan/sftpgo/config"
  30. "github.com/drakkan/sftpgo/dataprovider"
  31. "github.com/drakkan/sftpgo/httpd"
  32. "github.com/drakkan/sftpgo/kms"
  33. "github.com/drakkan/sftpgo/logger"
  34. "github.com/drakkan/sftpgo/utils"
  35. "github.com/drakkan/sftpgo/vfs"
  36. )
  37. const (
  38. defaultUsername = "test_user"
  39. defaultPassword = "test_password"
  40. testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  41. userPath = "/api/v1/user"
  42. folderPath = "/api/v1/folder"
  43. activeConnectionsPath = "/api/v1/connection"
  44. serverStatusPath = "/api/v1/status"
  45. quotaScanPath = "/api/v1/quota_scan"
  46. quotaScanVFolderPath = "/api/v1/folder_quota_scan"
  47. updateUsedQuotaPath = "/api/v1/quota_update"
  48. updateFolderUsedQuotaPath = "/api/v1/folder_quota_update"
  49. versionPath = "/api/v1/version"
  50. metricsPath = "/metrics"
  51. pprofPath = "/debug/pprof/"
  52. webBasePath = "/web"
  53. webUsersPath = "/web/users"
  54. webUserPath = "/web/user"
  55. webFoldersPath = "/web/folders"
  56. webFolderPath = "/web/folder"
  57. webConnectionsPath = "/web/connections"
  58. webStatusPath = "/web/status"
  59. configDir = ".."
  60. httpsCert = `-----BEGIN CERTIFICATE-----
  61. MIICHTCCAaKgAwIBAgIUHnqw7QnB1Bj9oUsNpdb+ZkFPOxMwCgYIKoZIzj0EAwIw
  62. RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
  63. dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDAyMDQwOTUzMDRaFw0zMDAyMDEw
  64. OTUzMDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
  65. VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
  66. IgNiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVqWvrJ51t5OxV0v25NsOgR82CA
  67. NXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIVCzgWkxiz7XE4lgUwX44FCXZM
  68. 3+JeUbKjUzBRMB0GA1UdDgQWBBRhLw+/o3+Z02MI/d4tmaMui9W16jAfBgNVHSME
  69. GDAWgBRhLw+/o3+Z02MI/d4tmaMui9W16jAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
  70. SM49BAMCA2kAMGYCMQDqLt2lm8mE+tGgtjDmtFgdOcI72HSbRQ74D5rYTzgST1rY
  71. /8wTi5xl8TiFUyLMUsICMQC5ViVxdXbhuG7gX6yEqSkMKZICHpO8hqFwOD/uaFVI
  72. dV4vKmHUzwK/eIx+8Ay3neE=
  73. -----END CERTIFICATE-----`
  74. httpsKey = `-----BEGIN EC PARAMETERS-----
  75. BgUrgQQAIg==
  76. -----END EC PARAMETERS-----
  77. -----BEGIN EC PRIVATE KEY-----
  78. MIGkAgEBBDCfMNsN6miEE3rVyUPwElfiJSWaR5huPCzUenZOfJT04GAcQdWvEju3
  79. UM2lmBLIXpGgBwYFK4EEACKhZANiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVq
  80. WvrJ51t5OxV0v25NsOgR82CANXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIV
  81. CzgWkxiz7XE4lgUwX44FCXZM3+JeUbI=
  82. -----END EC PRIVATE KEY-----`
  83. sftpPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
  84. b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
  85. QyNTUxOQAAACB+RB4yNTZz9mHOkawwUibNdemijVV3ErMeLxWUBlCN/gAAAJA7DjpfOw46
  86. XwAAAAtzc2gtZWQyNTUxOQAAACB+RB4yNTZz9mHOkawwUibNdemijVV3ErMeLxWUBlCN/g
  87. AAAEA0E24gi8ab/XRSvJ85TGZJMe6HVmwxSG4ExPfTMwwe2n5EHjI1NnP2Yc6RrDBSJs11
  88. 6aKNVXcSsx4vFZQGUI3+AAAACW5pY29sYUBwMQECAwQ=
  89. -----END OPENSSH PRIVATE KEY-----`
  90. sftpPkeyFingerprint = "SHA256:QVQ06XHZZbYZzqfrsZcf3Yozy2WTnqQPeLOkcJCdbP0"
  91. )
  92. var (
  93. defaultPerms = []string{dataprovider.PermAny}
  94. homeBasePath string
  95. backupsPath string
  96. credentialsPath string
  97. testServer *httptest.Server
  98. providerDriverName string
  99. )
  100. type fakeConnection struct {
  101. *common.BaseConnection
  102. command string
  103. }
  104. func (c *fakeConnection) Disconnect() error {
  105. common.Connections.Remove(c.GetID())
  106. return nil
  107. }
  108. func (c *fakeConnection) GetClientVersion() string {
  109. return ""
  110. }
  111. func (c *fakeConnection) GetCommand() string {
  112. return c.command
  113. }
  114. func (c *fakeConnection) GetRemoteAddress() string {
  115. return ""
  116. }
  117. func TestMain(m *testing.M) {
  118. homeBasePath = os.TempDir()
  119. logfilePath := filepath.Join(configDir, "sftpgo_api_test.log")
  120. logger.InitLogger(logfilePath, 5, 1, 28, false, zerolog.DebugLevel)
  121. err := config.LoadConfig(configDir, "")
  122. if err != nil {
  123. logger.WarnToConsole("error loading configuration: %v", err)
  124. os.Exit(1)
  125. }
  126. providerConf := config.GetProviderConf()
  127. credentialsPath = filepath.Join(os.TempDir(), "test_credentials")
  128. providerConf.CredentialsPath = credentialsPath
  129. providerDriverName = providerConf.Driver
  130. os.RemoveAll(credentialsPath) //nolint:errcheck
  131. logger.InfoToConsole("Starting HTTPD tests, provider: %v", providerConf.Driver)
  132. common.Initialize(config.GetCommonConfig())
  133. err = dataprovider.Initialize(providerConf, configDir)
  134. if err != nil {
  135. logger.WarnToConsole("error initializing data provider: %v", err)
  136. os.Exit(1)
  137. }
  138. httpConfig := config.GetHTTPConfig()
  139. httpConfig.Initialize(configDir)
  140. kmsConfig := config.GetKMSConfig()
  141. err = kmsConfig.Initialize()
  142. if err != nil {
  143. logger.ErrorToConsole("error initializing kms: %v", err)
  144. os.Exit(1)
  145. }
  146. httpdConf := config.GetHTTPDConfig()
  147. httpdConf.BindPort = 8081
  148. httpd.SetBaseURLAndCredentials("http://127.0.0.1:8081", "", "")
  149. backupsPath = filepath.Join(os.TempDir(), "test_backups")
  150. httpdConf.BackupsPath = backupsPath
  151. err = os.MkdirAll(backupsPath, os.ModePerm)
  152. if err != nil {
  153. logger.ErrorToConsole("error creating backups path: %v", err)
  154. os.Exit(1)
  155. }
  156. go func() {
  157. if err := httpdConf.Initialize(configDir, true); err != nil {
  158. logger.ErrorToConsole("could not start HTTP server: %v", err)
  159. os.Exit(1)
  160. }
  161. }()
  162. waitTCPListening(fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort))
  163. // now start an https server
  164. certPath := filepath.Join(os.TempDir(), "test.crt")
  165. keyPath := filepath.Join(os.TempDir(), "test.key")
  166. err = ioutil.WriteFile(certPath, []byte(httpsCert), os.ModePerm)
  167. if err != nil {
  168. logger.ErrorToConsole("error writing HTTPS certificate: %v", err)
  169. os.Exit(1)
  170. }
  171. err = ioutil.WriteFile(keyPath, []byte(httpsKey), os.ModePerm)
  172. if err != nil {
  173. logger.ErrorToConsole("error writing HTTPS private key: %v", err)
  174. os.Exit(1)
  175. }
  176. httpdConf.BindPort = 8443
  177. httpdConf.CertificateFile = certPath
  178. httpdConf.CertificateKeyFile = keyPath
  179. go func() {
  180. if err := httpdConf.Initialize(configDir, true); err != nil {
  181. logger.ErrorToConsole("could not start HTTPS server: %v", err)
  182. os.Exit(1)
  183. }
  184. }()
  185. waitTCPListening(fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort))
  186. httpd.ReloadTLSCertificate() //nolint:errcheck
  187. testServer = httptest.NewServer(httpd.GetHTTPRouter())
  188. defer testServer.Close()
  189. exitCode := m.Run()
  190. os.Remove(logfilePath) //nolint:errcheck
  191. os.RemoveAll(backupsPath) //nolint:errcheck
  192. os.RemoveAll(credentialsPath) //nolint:errcheck
  193. os.Remove(certPath) //nolint:errcheck
  194. os.Remove(keyPath) //nolint:errcheck
  195. os.Exit(exitCode) //nolint:errcheck
  196. }
  197. func TestInitialization(t *testing.T) {
  198. err := config.LoadConfig(configDir, "")
  199. assert.NoError(t, err)
  200. invalidFile := "invalid file"
  201. httpdConf := config.GetHTTPDConfig()
  202. httpdConf.BackupsPath = "test_backups"
  203. httpdConf.AuthUserFile = invalidFile
  204. err = httpdConf.Initialize(configDir, true)
  205. assert.Error(t, err)
  206. httpdConf.BackupsPath = backupsPath
  207. httpdConf.AuthUserFile = ""
  208. httpdConf.CertificateFile = invalidFile
  209. httpdConf.CertificateKeyFile = invalidFile
  210. err = httpdConf.Initialize(configDir, true)
  211. assert.Error(t, err)
  212. httpdConf.CertificateFile = ""
  213. httpdConf.CertificateKeyFile = ""
  214. httpdConf.TemplatesPath = "."
  215. err = httpdConf.Initialize(configDir, true)
  216. assert.Error(t, err)
  217. err = httpd.ReloadTLSCertificate()
  218. assert.NoError(t, err, "reloading TLS Certificate must return nil error if no certificate is configured")
  219. httpdConf = config.GetHTTPDConfig()
  220. httpdConf.BackupsPath = ".."
  221. err = httpdConf.Initialize(configDir, true)
  222. assert.Error(t, err)
  223. httpdConf.BackupsPath = backupsPath
  224. httpdConf.CertificateFile = invalidFile
  225. httpdConf.CertificateKeyFile = invalidFile
  226. httpdConf.StaticFilesPath = ""
  227. httpdConf.TemplatesPath = ""
  228. err = httpdConf.Initialize(configDir, true)
  229. assert.Error(t, err)
  230. }
  231. func TestBasicUserHandling(t *testing.T) {
  232. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  233. assert.NoError(t, err)
  234. user.MaxSessions = 10
  235. user.QuotaSize = 4096
  236. user.QuotaFiles = 2
  237. user.UploadBandwidth = 128
  238. user.DownloadBandwidth = 64
  239. user.ExpirationDate = utils.GetTimeAsMsSinceEpoch(time.Now())
  240. user.AdditionalInfo = "some free text"
  241. originalUser := user
  242. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  243. assert.NoError(t, err)
  244. assert.Equal(t, originalUser.ID, user.ID)
  245. users, _, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  246. assert.NoError(t, err)
  247. assert.Equal(t, 1, len(users))
  248. _, err = httpd.RemoveUser(user, http.StatusOK)
  249. assert.NoError(t, err)
  250. }
  251. func TestUserStatus(t *testing.T) {
  252. u := getTestUser()
  253. u.Status = 3
  254. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  255. assert.NoError(t, err)
  256. u.Status = 0
  257. user, _, err := httpd.AddUser(u, http.StatusOK)
  258. assert.NoError(t, err)
  259. user.Status = 2
  260. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest, "")
  261. assert.NoError(t, err)
  262. user.Status = 1
  263. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  264. assert.NoError(t, err)
  265. _, err = httpd.RemoveUser(user, http.StatusOK)
  266. assert.NoError(t, err)
  267. }
  268. func TestAddUserNoCredentials(t *testing.T) {
  269. u := getTestUser()
  270. u.Password = ""
  271. u.PublicKeys = []string{}
  272. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  273. assert.NoError(t, err)
  274. }
  275. func TestAddUserNoUsername(t *testing.T) {
  276. u := getTestUser()
  277. u.Username = ""
  278. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  279. assert.NoError(t, err)
  280. }
  281. func TestAddUserNoHomeDir(t *testing.T) {
  282. u := getTestUser()
  283. u.HomeDir = ""
  284. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  285. assert.NoError(t, err)
  286. }
  287. func TestAddUserInvalidHomeDir(t *testing.T) {
  288. u := getTestUser()
  289. u.HomeDir = "relative_path" //nolint:goconst
  290. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  291. assert.NoError(t, err)
  292. }
  293. func TestAddUserNoPerms(t *testing.T) {
  294. u := getTestUser()
  295. u.Permissions = make(map[string][]string)
  296. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  297. assert.NoError(t, err)
  298. u.Permissions["/"] = []string{}
  299. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  300. assert.NoError(t, err)
  301. }
  302. func TestAddUserInvalidPerms(t *testing.T) {
  303. u := getTestUser()
  304. u.Permissions["/"] = []string{"invalidPerm"}
  305. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  306. assert.NoError(t, err)
  307. // permissions for root dir are mandatory
  308. u.Permissions["/"] = []string{}
  309. u.Permissions["/somedir"] = []string{dataprovider.PermAny}
  310. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  311. assert.NoError(t, err)
  312. u.Permissions["/"] = []string{dataprovider.PermAny}
  313. u.Permissions["/subdir/.."] = []string{dataprovider.PermAny}
  314. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  315. assert.NoError(t, err)
  316. }
  317. func TestAddUserInvalidFilters(t *testing.T) {
  318. u := getTestUser()
  319. u.Filters.AllowedIP = []string{"192.168.1.0/24", "192.168.2.0"}
  320. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  321. assert.NoError(t, err)
  322. u.Filters.AllowedIP = []string{}
  323. u.Filters.DeniedIP = []string{"192.168.3.0/16", "invalid"}
  324. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  325. assert.NoError(t, err)
  326. u.Filters.DeniedIP = []string{}
  327. u.Filters.DeniedLoginMethods = []string{"invalid"}
  328. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  329. assert.NoError(t, err)
  330. u.Filters.DeniedLoginMethods = dataprovider.ValidSSHLoginMethods
  331. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  332. assert.NoError(t, err)
  333. u.Filters.DeniedLoginMethods = []string{}
  334. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  335. {
  336. Path: "relative",
  337. AllowedExtensions: []string{},
  338. DeniedExtensions: []string{},
  339. },
  340. }
  341. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  342. assert.NoError(t, err)
  343. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  344. {
  345. Path: "/",
  346. AllowedExtensions: []string{},
  347. DeniedExtensions: []string{},
  348. },
  349. }
  350. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  351. assert.NoError(t, err)
  352. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  353. {
  354. Path: "/subdir",
  355. AllowedExtensions: []string{".zip"},
  356. DeniedExtensions: []string{},
  357. },
  358. {
  359. Path: "/subdir",
  360. AllowedExtensions: []string{".rar"},
  361. DeniedExtensions: []string{".jpg"},
  362. },
  363. }
  364. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  365. assert.NoError(t, err)
  366. u.Filters.FileExtensions = nil
  367. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  368. {
  369. Path: "relative",
  370. AllowedPatterns: []string{},
  371. DeniedPatterns: []string{},
  372. },
  373. }
  374. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  375. assert.NoError(t, err)
  376. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  377. {
  378. Path: "/",
  379. AllowedPatterns: []string{},
  380. DeniedPatterns: []string{},
  381. },
  382. }
  383. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  384. assert.NoError(t, err)
  385. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  386. {
  387. Path: "/subdir",
  388. AllowedPatterns: []string{"*.zip"},
  389. },
  390. {
  391. Path: "/subdir",
  392. AllowedPatterns: []string{"*.rar"},
  393. DeniedPatterns: []string{"*.jpg"},
  394. },
  395. }
  396. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  397. assert.NoError(t, err)
  398. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  399. {
  400. Path: "/subdir",
  401. AllowedPatterns: []string{"a\\"},
  402. },
  403. }
  404. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  405. assert.NoError(t, err)
  406. u.Filters.DeniedProtocols = []string{"invalid"}
  407. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  408. assert.NoError(t, err)
  409. u.Filters.DeniedProtocols = dataprovider.ValidProtocols
  410. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  411. assert.NoError(t, err)
  412. }
  413. func TestAddUserInvalidFsConfig(t *testing.T) {
  414. u := getTestUser()
  415. u.FsConfig.Provider = dataprovider.S3FilesystemProvider
  416. u.FsConfig.S3Config.Bucket = ""
  417. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  418. assert.NoError(t, err)
  419. err = os.RemoveAll(credentialsPath)
  420. assert.NoError(t, err)
  421. err = os.MkdirAll(credentialsPath, 0700)
  422. assert.NoError(t, err)
  423. u.FsConfig.S3Config.Bucket = "testbucket"
  424. u.FsConfig.S3Config.Region = "eu-west-1"
  425. u.FsConfig.S3Config.AccessKey = "access-key"
  426. u.FsConfig.S3Config.AccessSecret = kms.NewSecret(kms.SecretStatusRedacted, "access-secret", "", "")
  427. u.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/path?a=b"
  428. u.FsConfig.S3Config.StorageClass = "Standard" //nolint:goconst
  429. u.FsConfig.S3Config.KeyPrefix = "/adir/subdir/"
  430. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  431. assert.NoError(t, err)
  432. u.FsConfig.S3Config.AccessSecret.SetStatus(kms.SecretStatusPlain)
  433. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  434. assert.NoError(t, err)
  435. u.FsConfig.S3Config.KeyPrefix = ""
  436. u.FsConfig.S3Config.UploadPartSize = 3
  437. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  438. assert.NoError(t, err)
  439. u.FsConfig.S3Config.UploadPartSize = 5001
  440. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  441. assert.NoError(t, err)
  442. u.FsConfig.S3Config.UploadPartSize = 0
  443. u.FsConfig.S3Config.UploadConcurrency = -1
  444. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  445. assert.NoError(t, err)
  446. u = getTestUser()
  447. u.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  448. u.FsConfig.GCSConfig.Bucket = ""
  449. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  450. assert.NoError(t, err)
  451. u.FsConfig.GCSConfig.Bucket = "abucket"
  452. u.FsConfig.GCSConfig.StorageClass = "Standard"
  453. u.FsConfig.GCSConfig.KeyPrefix = "/somedir/subdir/"
  454. u.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusRedacted, "test", "", "") //nolint:goconst
  455. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  456. assert.NoError(t, err)
  457. u.FsConfig.GCSConfig.Credentials.SetStatus(kms.SecretStatusPlain)
  458. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  459. assert.NoError(t, err)
  460. u.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir/" //nolint:goconst
  461. u.FsConfig.GCSConfig.Credentials = kms.NewEmptySecret()
  462. u.FsConfig.GCSConfig.AutomaticCredentials = 0
  463. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  464. assert.NoError(t, err)
  465. u.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusSecretBox, "invalid", "", "")
  466. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  467. assert.NoError(t, err)
  468. u = getTestUser()
  469. u.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  470. u.FsConfig.AzBlobConfig.SASURL = "http://foo\x7f.com/"
  471. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  472. assert.NoError(t, err)
  473. u.FsConfig.AzBlobConfig.SASURL = ""
  474. u.FsConfig.AzBlobConfig.AccountName = "name"
  475. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  476. assert.NoError(t, err)
  477. u.FsConfig.AzBlobConfig.Container = "container"
  478. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  479. assert.NoError(t, err)
  480. u.FsConfig.AzBlobConfig.AccountKey = kms.NewSecret(kms.SecretStatusRedacted, "key", "", "")
  481. u.FsConfig.AzBlobConfig.KeyPrefix = "/amedir/subdir/"
  482. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  483. assert.NoError(t, err)
  484. u.FsConfig.AzBlobConfig.AccountKey.SetStatus(kms.SecretStatusPlain)
  485. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  486. assert.NoError(t, err)
  487. u.FsConfig.AzBlobConfig.KeyPrefix = "amedir/subdir/"
  488. u.FsConfig.AzBlobConfig.UploadPartSize = -1
  489. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  490. assert.NoError(t, err)
  491. u.FsConfig.AzBlobConfig.UploadPartSize = 101
  492. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  493. assert.NoError(t, err)
  494. u = getTestUser()
  495. u.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  496. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  497. assert.NoError(t, err)
  498. u.FsConfig.CryptConfig.Passphrase = kms.NewSecret(kms.SecretStatusRedacted, "akey", "", "")
  499. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  500. assert.NoError(t, err)
  501. u = getTestUser()
  502. u.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  503. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  504. assert.NoError(t, err)
  505. u.FsConfig.SFTPConfig.Password = kms.NewSecret(kms.SecretStatusRedacted, "randompkey", "", "")
  506. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  507. assert.NoError(t, err)
  508. u.FsConfig.SFTPConfig.Password = kms.NewEmptySecret()
  509. u.FsConfig.SFTPConfig.PrivateKey = kms.NewSecret(kms.SecretStatusRedacted, "keyforpkey", "", "")
  510. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  511. assert.NoError(t, err)
  512. }
  513. func TestAddUserInvalidVirtualFolders(t *testing.T) {
  514. u := getTestUser()
  515. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  516. BaseVirtualFolder: vfs.BaseVirtualFolder{
  517. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  518. },
  519. VirtualPath: "vdir",
  520. })
  521. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  522. assert.NoError(t, err)
  523. u.VirtualFolders = nil
  524. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  525. BaseVirtualFolder: vfs.BaseVirtualFolder{
  526. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  527. },
  528. VirtualPath: "/",
  529. })
  530. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  531. assert.NoError(t, err)
  532. u.VirtualFolders = nil
  533. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  534. BaseVirtualFolder: vfs.BaseVirtualFolder{
  535. MappedPath: filepath.Join(u.GetHomeDir(), "mapped_dir"),
  536. },
  537. VirtualPath: "/vdir",
  538. })
  539. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  540. assert.NoError(t, err)
  541. u.VirtualFolders = nil
  542. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  543. BaseVirtualFolder: vfs.BaseVirtualFolder{
  544. MappedPath: u.GetHomeDir(),
  545. },
  546. VirtualPath: "/vdir",
  547. })
  548. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  549. assert.NoError(t, err)
  550. u.VirtualFolders = nil
  551. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  552. BaseVirtualFolder: vfs.BaseVirtualFolder{
  553. MappedPath: filepath.Join(u.GetHomeDir(), ".."),
  554. },
  555. VirtualPath: "/vdir",
  556. })
  557. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  558. assert.NoError(t, err)
  559. u.VirtualFolders = nil
  560. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  561. BaseVirtualFolder: vfs.BaseVirtualFolder{
  562. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  563. },
  564. VirtualPath: "/vdir",
  565. })
  566. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  567. BaseVirtualFolder: vfs.BaseVirtualFolder{
  568. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  569. },
  570. VirtualPath: "/vdir",
  571. })
  572. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  573. assert.NoError(t, err)
  574. u.VirtualFolders = nil
  575. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  576. BaseVirtualFolder: vfs.BaseVirtualFolder{
  577. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  578. },
  579. VirtualPath: "/vdir1",
  580. })
  581. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  582. BaseVirtualFolder: vfs.BaseVirtualFolder{
  583. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  584. },
  585. VirtualPath: "/vdir2",
  586. })
  587. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  588. assert.NoError(t, err)
  589. u.VirtualFolders = nil
  590. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  591. BaseVirtualFolder: vfs.BaseVirtualFolder{
  592. MappedPath: filepath.Join(os.TempDir(), "mapped_dir", "subdir"),
  593. },
  594. VirtualPath: "/vdir1",
  595. })
  596. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  597. BaseVirtualFolder: vfs.BaseVirtualFolder{
  598. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  599. },
  600. VirtualPath: "/vdir2",
  601. })
  602. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  603. assert.NoError(t, err)
  604. u.VirtualFolders = nil
  605. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  606. BaseVirtualFolder: vfs.BaseVirtualFolder{
  607. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  608. },
  609. VirtualPath: "/vdir1",
  610. })
  611. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  612. BaseVirtualFolder: vfs.BaseVirtualFolder{
  613. MappedPath: filepath.Join(os.TempDir(), "mapped_dir", "subdir"),
  614. },
  615. VirtualPath: "/vdir2",
  616. })
  617. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  618. assert.NoError(t, err)
  619. u.VirtualFolders = nil
  620. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  621. BaseVirtualFolder: vfs.BaseVirtualFolder{
  622. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  623. },
  624. VirtualPath: "/vdir1/subdir",
  625. })
  626. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  627. BaseVirtualFolder: vfs.BaseVirtualFolder{
  628. MappedPath: filepath.Join(os.TempDir(), "mapped_dir2"),
  629. },
  630. VirtualPath: "/vdir1/../vdir1",
  631. })
  632. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  633. assert.NoError(t, err)
  634. u.VirtualFolders = nil
  635. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  636. BaseVirtualFolder: vfs.BaseVirtualFolder{
  637. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  638. },
  639. VirtualPath: "/vdir1/",
  640. })
  641. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  642. BaseVirtualFolder: vfs.BaseVirtualFolder{
  643. MappedPath: filepath.Join(os.TempDir(), "mapped_dir2"),
  644. },
  645. VirtualPath: "/vdir1/subdir",
  646. })
  647. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  648. assert.NoError(t, err)
  649. u.VirtualFolders = nil
  650. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  651. BaseVirtualFolder: vfs.BaseVirtualFolder{
  652. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  653. },
  654. VirtualPath: "/vdir1/",
  655. QuotaSize: -1,
  656. QuotaFiles: 1,
  657. })
  658. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  659. assert.NoError(t, err)
  660. u.VirtualFolders = nil
  661. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  662. BaseVirtualFolder: vfs.BaseVirtualFolder{
  663. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  664. },
  665. VirtualPath: "/vdir1/",
  666. QuotaSize: 1,
  667. QuotaFiles: -1,
  668. })
  669. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  670. assert.NoError(t, err)
  671. u.VirtualFolders = nil
  672. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  673. BaseVirtualFolder: vfs.BaseVirtualFolder{
  674. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  675. },
  676. VirtualPath: "/vdir1/",
  677. QuotaSize: -2,
  678. QuotaFiles: 0,
  679. })
  680. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  681. assert.NoError(t, err)
  682. u.VirtualFolders = nil
  683. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  684. BaseVirtualFolder: vfs.BaseVirtualFolder{
  685. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  686. },
  687. VirtualPath: "/vdir1/",
  688. QuotaSize: 0,
  689. QuotaFiles: -2,
  690. })
  691. _, _, err = httpd.AddUser(u, http.StatusBadRequest)
  692. assert.NoError(t, err)
  693. }
  694. func TestUserPublicKey(t *testing.T) {
  695. u := getTestUser()
  696. invalidPubKey := "invalid"
  697. validPubKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  698. u.PublicKeys = []string{invalidPubKey}
  699. _, _, err := httpd.AddUser(u, http.StatusBadRequest)
  700. assert.NoError(t, err)
  701. u.PublicKeys = []string{validPubKey}
  702. user, _, err := httpd.AddUser(u, http.StatusOK)
  703. assert.NoError(t, err)
  704. user.PublicKeys = []string{validPubKey, invalidPubKey}
  705. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest, "")
  706. assert.NoError(t, err)
  707. user.PublicKeys = []string{validPubKey, validPubKey, validPubKey}
  708. _, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  709. assert.NoError(t, err)
  710. _, err = httpd.RemoveUser(user, http.StatusOK)
  711. assert.NoError(t, err)
  712. }
  713. func TestUpdateUser(t *testing.T) {
  714. u := getTestUser()
  715. u.UsedQuotaFiles = 1
  716. u.UsedQuotaSize = 2
  717. user, _, err := httpd.AddUser(u, http.StatusOK)
  718. assert.NoError(t, err)
  719. assert.Equal(t, 0, user.UsedQuotaFiles)
  720. assert.Equal(t, int64(0), user.UsedQuotaSize)
  721. user.HomeDir = filepath.Join(homeBasePath, "testmod")
  722. user.UID = 33
  723. user.GID = 101
  724. user.MaxSessions = 10
  725. user.QuotaSize = 4096
  726. user.QuotaFiles = 2
  727. user.Permissions["/"] = []string{dataprovider.PermCreateDirs, dataprovider.PermDelete, dataprovider.PermDownload}
  728. user.Permissions["/subdir"] = []string{dataprovider.PermListItems, dataprovider.PermUpload}
  729. user.Filters.AllowedIP = []string{"192.168.1.0/24", "192.168.2.0/24"}
  730. user.Filters.DeniedIP = []string{"192.168.3.0/24", "192.168.4.0/24"}
  731. user.Filters.DeniedLoginMethods = []string{dataprovider.LoginMethodPassword}
  732. user.Filters.DeniedProtocols = []string{common.ProtocolWebDAV}
  733. user.Filters.FileExtensions = append(user.Filters.FileExtensions, dataprovider.ExtensionsFilter{
  734. Path: "/subdir",
  735. AllowedExtensions: []string{".zip", ".rar"},
  736. DeniedExtensions: []string{".jpg", ".png"},
  737. })
  738. user.Filters.FilePatterns = append(user.Filters.FilePatterns, dataprovider.PatternsFilter{
  739. Path: "/subdir",
  740. AllowedPatterns: []string{"*.zip", "*.rar"},
  741. DeniedPatterns: []string{"*.jpg", "*.png"},
  742. })
  743. user.Filters.MaxUploadFileSize = 4096
  744. user.UploadBandwidth = 1024
  745. user.DownloadBandwidth = 512
  746. user.VirtualFolders = nil
  747. mappedPath1 := filepath.Join(os.TempDir(), "mapped_dir1")
  748. mappedPath2 := filepath.Join(os.TempDir(), "mapped_dir2")
  749. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  750. BaseVirtualFolder: vfs.BaseVirtualFolder{
  751. MappedPath: mappedPath1,
  752. },
  753. VirtualPath: "/vdir1",
  754. })
  755. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  756. BaseVirtualFolder: vfs.BaseVirtualFolder{
  757. MappedPath: mappedPath2,
  758. },
  759. VirtualPath: "/vdir12/subdir",
  760. QuotaSize: 123,
  761. QuotaFiles: 2,
  762. })
  763. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  764. assert.NoError(t, err)
  765. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest, "invalid")
  766. assert.NoError(t, err)
  767. user, _, err = httpd.UpdateUser(user, http.StatusOK, "0")
  768. assert.NoError(t, err)
  769. user, _, err = httpd.UpdateUser(user, http.StatusOK, "1")
  770. assert.NoError(t, err)
  771. user.Permissions["/subdir"] = []string{}
  772. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  773. assert.NoError(t, err)
  774. assert.Len(t, user.Permissions["/subdir"], 0)
  775. assert.Len(t, user.VirtualFolders, 2)
  776. for _, folder := range user.VirtualFolders {
  777. assert.Greater(t, folder.ID, int64(0))
  778. if folder.VirtualPath == "/vdir12/subdir" {
  779. assert.Equal(t, int64(123), folder.QuotaSize)
  780. assert.Equal(t, 2, folder.QuotaFiles)
  781. }
  782. }
  783. folder, _, err := httpd.GetFolders(0, 0, mappedPath1, http.StatusOK)
  784. assert.NoError(t, err)
  785. if assert.Len(t, folder, 1) {
  786. f := folder[0]
  787. assert.Len(t, f.Users, 1)
  788. assert.Contains(t, f.Users, user.Username)
  789. }
  790. _, err = httpd.RemoveUser(user, http.StatusOK)
  791. assert.NoError(t, err)
  792. // removing the user must remove folder mapping
  793. folder, _, err = httpd.GetFolders(0, 0, mappedPath1, http.StatusOK)
  794. assert.NoError(t, err)
  795. if assert.Len(t, folder, 1) {
  796. f := folder[0]
  797. assert.Len(t, f.Users, 0)
  798. _, err = httpd.RemoveFolder(f, http.StatusOK)
  799. assert.NoError(t, err)
  800. }
  801. folder, _, err = httpd.GetFolders(0, 0, mappedPath2, http.StatusOK)
  802. assert.NoError(t, err)
  803. if assert.Len(t, folder, 1) {
  804. f := folder[0]
  805. assert.Len(t, f.Users, 0)
  806. _, err = httpd.RemoveFolder(f, http.StatusOK)
  807. assert.NoError(t, err)
  808. }
  809. }
  810. func TestUpdateUserQuotaUsage(t *testing.T) {
  811. u := getTestUser()
  812. usedQuotaFiles := 1
  813. usedQuotaSize := int64(65535)
  814. u.UsedQuotaFiles = usedQuotaFiles
  815. u.UsedQuotaSize = usedQuotaSize
  816. user, _, err := httpd.AddUser(u, http.StatusOK)
  817. assert.NoError(t, err)
  818. _, err = httpd.UpdateQuotaUsage(u, "invalid_mode", http.StatusBadRequest)
  819. assert.NoError(t, err)
  820. _, err = httpd.UpdateQuotaUsage(u, "", http.StatusOK)
  821. assert.NoError(t, err)
  822. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  823. assert.NoError(t, err)
  824. assert.Equal(t, usedQuotaFiles, user.UsedQuotaFiles)
  825. assert.Equal(t, usedQuotaSize, user.UsedQuotaSize)
  826. _, err = httpd.UpdateQuotaUsage(u, "add", http.StatusBadRequest)
  827. assert.NoError(t, err, "user has no quota restrictions add mode should fail")
  828. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  829. assert.NoError(t, err)
  830. assert.Equal(t, usedQuotaFiles, user.UsedQuotaFiles)
  831. assert.Equal(t, usedQuotaSize, user.UsedQuotaSize)
  832. user.QuotaFiles = 100
  833. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  834. assert.NoError(t, err)
  835. _, err = httpd.UpdateQuotaUsage(u, "add", http.StatusOK)
  836. assert.NoError(t, err)
  837. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  838. assert.NoError(t, err)
  839. assert.Equal(t, 2*usedQuotaFiles, user.UsedQuotaFiles)
  840. assert.Equal(t, 2*usedQuotaSize, user.UsedQuotaSize)
  841. u.UsedQuotaFiles = -1
  842. _, err = httpd.UpdateQuotaUsage(u, "", http.StatusBadRequest)
  843. assert.NoError(t, err)
  844. u.UsedQuotaFiles = usedQuotaFiles
  845. u.Username = u.Username + "1"
  846. _, err = httpd.UpdateQuotaUsage(u, "", http.StatusNotFound)
  847. assert.NoError(t, err)
  848. _, err = httpd.RemoveUser(user, http.StatusOK)
  849. assert.NoError(t, err)
  850. }
  851. func TestUserFolderMapping(t *testing.T) {
  852. mappedPath1 := filepath.Join(os.TempDir(), "mapped_dir1")
  853. mappedPath2 := filepath.Join(os.TempDir(), "mapped_dir2")
  854. u1 := getTestUser()
  855. u1.VirtualFolders = append(u1.VirtualFolders, vfs.VirtualFolder{
  856. BaseVirtualFolder: vfs.BaseVirtualFolder{
  857. MappedPath: mappedPath1,
  858. UsedQuotaFiles: 2,
  859. UsedQuotaSize: 123,
  860. },
  861. VirtualPath: "/vdir",
  862. QuotaSize: -1,
  863. QuotaFiles: -1,
  864. })
  865. user1, _, err := httpd.AddUser(u1, http.StatusOK)
  866. assert.NoError(t, err)
  867. // virtual folder must be auto created
  868. folders, _, err := httpd.GetFolders(0, 0, mappedPath1, http.StatusOK)
  869. assert.NoError(t, err)
  870. if assert.Len(t, folders, 1) {
  871. folder := folders[0]
  872. assert.Len(t, folder.Users, 1)
  873. assert.Contains(t, folder.Users, user1.Username)
  874. assert.Equal(t, 0, folder.UsedQuotaFiles)
  875. assert.Equal(t, int64(0), folder.UsedQuotaSize)
  876. }
  877. u2 := getTestUser()
  878. u2.Username = defaultUsername + "2"
  879. u2.VirtualFolders = append(u2.VirtualFolders, vfs.VirtualFolder{
  880. BaseVirtualFolder: vfs.BaseVirtualFolder{
  881. MappedPath: mappedPath1,
  882. },
  883. VirtualPath: "/vdir1",
  884. QuotaSize: 0,
  885. QuotaFiles: 0,
  886. })
  887. u2.VirtualFolders = append(u2.VirtualFolders, vfs.VirtualFolder{
  888. BaseVirtualFolder: vfs.BaseVirtualFolder{
  889. MappedPath: mappedPath2,
  890. },
  891. VirtualPath: "/vdir2",
  892. QuotaSize: -1,
  893. QuotaFiles: -1,
  894. })
  895. user2, _, err := httpd.AddUser(u2, http.StatusOK)
  896. assert.NoError(t, err)
  897. folders, _, err = httpd.GetFolders(0, 0, mappedPath2, http.StatusOK)
  898. assert.NoError(t, err)
  899. if assert.Len(t, folders, 1) {
  900. folder := folders[0]
  901. assert.Len(t, folder.Users, 1)
  902. assert.Contains(t, folder.Users, user2.Username)
  903. }
  904. folders, _, err = httpd.GetFolders(0, 0, mappedPath1, http.StatusOK)
  905. assert.NoError(t, err)
  906. if assert.Len(t, folders, 1) {
  907. folder := folders[0]
  908. assert.Len(t, folder.Users, 2)
  909. assert.Contains(t, folder.Users, user1.Username)
  910. assert.Contains(t, folder.Users, user2.Username)
  911. }
  912. // now update user2 removing mappedPath1
  913. user2.VirtualFolders = nil
  914. user2.VirtualFolders = append(user2.VirtualFolders, vfs.VirtualFolder{
  915. BaseVirtualFolder: vfs.BaseVirtualFolder{
  916. MappedPath: mappedPath2,
  917. UsedQuotaFiles: 2,
  918. UsedQuotaSize: 123,
  919. },
  920. VirtualPath: "/vdir",
  921. QuotaSize: 0,
  922. QuotaFiles: 0,
  923. })
  924. user2, _, err = httpd.UpdateUser(user2, http.StatusOK, "")
  925. assert.NoError(t, err)
  926. folders, _, err = httpd.GetFolders(0, 0, mappedPath2, http.StatusOK)
  927. assert.NoError(t, err)
  928. if assert.Len(t, folders, 1) {
  929. folder := folders[0]
  930. assert.Len(t, folder.Users, 1)
  931. assert.Contains(t, folder.Users, user2.Username)
  932. assert.Equal(t, 0, folder.UsedQuotaFiles)
  933. assert.Equal(t, int64(0), folder.UsedQuotaSize)
  934. }
  935. folders, _, err = httpd.GetFolders(0, 0, mappedPath1, http.StatusOK)
  936. assert.NoError(t, err)
  937. if assert.Len(t, folders, 1) {
  938. folder := folders[0]
  939. assert.Len(t, folder.Users, 1)
  940. assert.Contains(t, folder.Users, user1.Username)
  941. }
  942. // add mappedPath1 again to user2
  943. user2.VirtualFolders = append(user2.VirtualFolders, vfs.VirtualFolder{
  944. BaseVirtualFolder: vfs.BaseVirtualFolder{
  945. MappedPath: mappedPath1,
  946. },
  947. VirtualPath: "/vdir1",
  948. })
  949. user2, _, err = httpd.UpdateUser(user2, http.StatusOK, "")
  950. assert.NoError(t, err)
  951. folders, _, err = httpd.GetFolders(0, 0, mappedPath2, http.StatusOK)
  952. assert.NoError(t, err)
  953. if assert.Len(t, folders, 1) {
  954. folder := folders[0]
  955. assert.Len(t, folder.Users, 1)
  956. assert.Contains(t, folder.Users, user2.Username)
  957. }
  958. // removing virtual folders should clear relations on both side
  959. _, err = httpd.RemoveFolder(vfs.BaseVirtualFolder{MappedPath: mappedPath2}, http.StatusOK)
  960. assert.NoError(t, err)
  961. user2, _, err = httpd.GetUserByID(user2.ID, http.StatusOK)
  962. assert.NoError(t, err)
  963. if assert.Len(t, user2.VirtualFolders, 1) {
  964. folder := user2.VirtualFolders[0]
  965. assert.Equal(t, mappedPath1, folder.MappedPath)
  966. }
  967. user1, _, err = httpd.GetUserByID(user1.ID, http.StatusOK)
  968. assert.NoError(t, err)
  969. if assert.Len(t, user2.VirtualFolders, 1) {
  970. folder := user2.VirtualFolders[0]
  971. assert.Equal(t, mappedPath1, folder.MappedPath)
  972. }
  973. folders, _, err = httpd.GetFolders(0, 0, mappedPath1, http.StatusOK)
  974. assert.NoError(t, err)
  975. if assert.Len(t, folders, 1) {
  976. folder := folders[0]
  977. assert.Len(t, folder.Users, 2)
  978. }
  979. // removing a user should clear virtual folder mapping
  980. _, err = httpd.RemoveUser(user1, http.StatusOK)
  981. assert.NoError(t, err)
  982. folders, _, err = httpd.GetFolders(0, 0, mappedPath1, http.StatusOK)
  983. assert.NoError(t, err)
  984. if assert.Len(t, folders, 1) {
  985. folder := folders[0]
  986. assert.Len(t, folder.Users, 1)
  987. assert.Contains(t, folder.Users, user2.Username)
  988. }
  989. // removing a folder should clear mapping on the user side too
  990. _, err = httpd.RemoveFolder(vfs.BaseVirtualFolder{MappedPath: mappedPath1}, http.StatusOK)
  991. assert.NoError(t, err)
  992. user2, _, err = httpd.GetUserByID(user2.ID, http.StatusOK)
  993. assert.NoError(t, err)
  994. assert.Len(t, user2.VirtualFolders, 0)
  995. _, err = httpd.RemoveUser(user2, http.StatusOK)
  996. assert.NoError(t, err)
  997. }
  998. func TestUserS3Config(t *testing.T) {
  999. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1000. assert.NoError(t, err)
  1001. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1002. user.FsConfig.S3Config.Bucket = "test" //nolint:goconst
  1003. user.FsConfig.S3Config.Region = "us-east-1" //nolint:goconst
  1004. user.FsConfig.S3Config.AccessKey = "Server-Access-Key"
  1005. user.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("Server-Access-Secret")
  1006. user.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000"
  1007. user.FsConfig.S3Config.UploadPartSize = 8
  1008. user, body, err := httpd.UpdateUser(user, http.StatusOK, "")
  1009. assert.NoError(t, err, string(body))
  1010. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.S3Config.AccessSecret.GetStatus())
  1011. assert.NotEmpty(t, user.FsConfig.S3Config.AccessSecret.GetPayload())
  1012. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1013. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetKey())
  1014. _, err = httpd.RemoveUser(user, http.StatusOK)
  1015. assert.NoError(t, err)
  1016. user.Password = defaultPassword
  1017. user.ID = 0
  1018. secret := kms.NewSecret(kms.SecretStatusSecretBox, "Server-Access-Secret", "", "")
  1019. user.FsConfig.S3Config.AccessSecret = secret
  1020. _, _, err = httpd.AddUser(user, http.StatusOK)
  1021. assert.Error(t, err)
  1022. user.FsConfig.S3Config.AccessSecret.SetStatus(kms.SecretStatusPlain)
  1023. user, _, err = httpd.AddUser(user, http.StatusOK)
  1024. assert.NoError(t, err)
  1025. initialSecretPayload := user.FsConfig.S3Config.AccessSecret.GetPayload()
  1026. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.S3Config.AccessSecret.GetStatus())
  1027. assert.NotEmpty(t, initialSecretPayload)
  1028. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1029. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetKey())
  1030. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1031. user.FsConfig.S3Config.Bucket = "test-bucket"
  1032. user.FsConfig.S3Config.Region = "us-east-1" //nolint:goconst
  1033. user.FsConfig.S3Config.AccessKey = "Server-Access-Key1"
  1034. user.FsConfig.S3Config.Endpoint = "http://localhost:9000"
  1035. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir" //nolint:goconst
  1036. user.FsConfig.S3Config.UploadConcurrency = 5
  1037. user, bb, err := httpd.UpdateUser(user, http.StatusOK, "")
  1038. assert.NoError(t, err, string(bb))
  1039. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.S3Config.AccessSecret.GetStatus())
  1040. assert.Equal(t, initialSecretPayload, user.FsConfig.S3Config.AccessSecret.GetPayload())
  1041. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1042. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetKey())
  1043. // test user without access key and access secret (shared config state)
  1044. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1045. user.FsConfig.S3Config.Bucket = "testbucket"
  1046. user.FsConfig.S3Config.Region = "us-east-1"
  1047. user.FsConfig.S3Config.AccessKey = ""
  1048. user.FsConfig.S3Config.AccessSecret = kms.NewEmptySecret()
  1049. user.FsConfig.S3Config.Endpoint = ""
  1050. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  1051. user.FsConfig.S3Config.UploadPartSize = 6
  1052. user.FsConfig.S3Config.UploadConcurrency = 4
  1053. user, body, err = httpd.UpdateUser(user, http.StatusOK, "")
  1054. assert.NoError(t, err, string(body))
  1055. assert.True(t, user.FsConfig.S3Config.AccessSecret.IsEmpty())
  1056. _, err = httpd.RemoveUser(user, http.StatusOK)
  1057. assert.NoError(t, err)
  1058. user.Password = defaultPassword
  1059. user.ID = 0
  1060. // shared credential test for add instead of update
  1061. user, _, err = httpd.AddUser(user, http.StatusOK)
  1062. assert.NoError(t, err)
  1063. assert.True(t, user.FsConfig.S3Config.AccessSecret.IsEmpty())
  1064. _, err = httpd.RemoveUser(user, http.StatusOK)
  1065. assert.NoError(t, err)
  1066. }
  1067. func TestUserGCSConfig(t *testing.T) {
  1068. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1069. assert.NoError(t, err)
  1070. err = os.RemoveAll(credentialsPath)
  1071. assert.NoError(t, err)
  1072. err = os.MkdirAll(credentialsPath, 0700)
  1073. assert.NoError(t, err)
  1074. user.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  1075. user.FsConfig.GCSConfig.Bucket = "test"
  1076. user.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("fake credentials") //nolint:goconst
  1077. user, bb, err := httpd.UpdateUser(user, http.StatusOK, "")
  1078. assert.NoError(t, err, string(bb))
  1079. credentialFile := filepath.Join(credentialsPath, fmt.Sprintf("%v_gcs_credentials.json", user.Username))
  1080. assert.FileExists(t, credentialFile)
  1081. creds, err := ioutil.ReadFile(credentialFile)
  1082. assert.NoError(t, err)
  1083. secret := kms.NewEmptySecret()
  1084. err = json.Unmarshal(creds, secret)
  1085. assert.NoError(t, err)
  1086. err = secret.Decrypt()
  1087. assert.NoError(t, err)
  1088. assert.Equal(t, "fake credentials", secret.GetPayload())
  1089. user.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusSecretBox, "fake encrypted credentials", "", "")
  1090. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1091. assert.NoError(t, err)
  1092. assert.FileExists(t, credentialFile)
  1093. creds, err = ioutil.ReadFile(credentialFile)
  1094. assert.NoError(t, err)
  1095. secret = kms.NewEmptySecret()
  1096. err = json.Unmarshal(creds, secret)
  1097. assert.NoError(t, err)
  1098. err = secret.Decrypt()
  1099. assert.NoError(t, err)
  1100. assert.Equal(t, "fake credentials", secret.GetPayload())
  1101. _, err = httpd.RemoveUser(user, http.StatusOK)
  1102. assert.NoError(t, err)
  1103. user.Password = defaultPassword
  1104. user.ID = 0
  1105. user.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusSecretBox, "fake credentials", "", "")
  1106. _, _, err = httpd.AddUser(user, http.StatusOK)
  1107. assert.Error(t, err)
  1108. user.FsConfig.GCSConfig.Credentials.SetStatus(kms.SecretStatusPlain)
  1109. user, body, err := httpd.AddUser(user, http.StatusOK)
  1110. assert.NoError(t, err, string(body))
  1111. err = os.RemoveAll(credentialsPath)
  1112. assert.NoError(t, err)
  1113. err = os.MkdirAll(credentialsPath, 0700)
  1114. assert.NoError(t, err)
  1115. user.FsConfig.GCSConfig.Credentials = kms.NewEmptySecret()
  1116. user.FsConfig.GCSConfig.AutomaticCredentials = 1
  1117. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1118. assert.NoError(t, err)
  1119. assert.NoFileExists(t, credentialFile)
  1120. user.FsConfig.GCSConfig = vfs.GCSFsConfig{}
  1121. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1122. user.FsConfig.S3Config.Bucket = "test1"
  1123. user.FsConfig.S3Config.Region = "us-east-1"
  1124. user.FsConfig.S3Config.AccessKey = "Server-Access-Key1"
  1125. user.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("secret")
  1126. user.FsConfig.S3Config.Endpoint = "http://localhost:9000"
  1127. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  1128. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1129. assert.NoError(t, err)
  1130. user.FsConfig.S3Config = vfs.S3FsConfig{}
  1131. user.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  1132. user.FsConfig.GCSConfig.Bucket = "test1"
  1133. user.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("fake credentials")
  1134. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1135. assert.NoError(t, err)
  1136. _, err = httpd.RemoveUser(user, http.StatusOK)
  1137. assert.NoError(t, err)
  1138. }
  1139. func TestUserAzureBlobConfig(t *testing.T) {
  1140. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1141. assert.NoError(t, err)
  1142. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1143. user.FsConfig.AzBlobConfig.Container = "test"
  1144. user.FsConfig.AzBlobConfig.AccountName = "Server-Account-Name"
  1145. user.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("Server-Account-Key")
  1146. user.FsConfig.AzBlobConfig.Endpoint = "http://127.0.0.1:9000"
  1147. user.FsConfig.AzBlobConfig.UploadPartSize = 8
  1148. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1149. assert.NoError(t, err)
  1150. initialPayload := user.FsConfig.AzBlobConfig.AccountKey.GetPayload()
  1151. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1152. assert.NotEmpty(t, initialPayload)
  1153. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1154. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1155. user.FsConfig.AzBlobConfig.AccountKey.SetStatus(kms.SecretStatusSecretBox)
  1156. user.FsConfig.AzBlobConfig.AccountKey.SetAdditionalData("data")
  1157. user.FsConfig.AzBlobConfig.AccountKey.SetKey("fake key")
  1158. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1159. assert.NoError(t, err)
  1160. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1161. assert.Equal(t, initialPayload, user.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1162. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1163. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1164. _, err = httpd.RemoveUser(user, http.StatusOK)
  1165. assert.NoError(t, err)
  1166. user.Password = defaultPassword
  1167. user.ID = 0
  1168. secret := kms.NewSecret(kms.SecretStatusSecretBox, "Server-Account-Key", "", "")
  1169. user.FsConfig.AzBlobConfig.AccountKey = secret
  1170. _, _, err = httpd.AddUser(user, http.StatusOK)
  1171. assert.Error(t, err)
  1172. user.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("Server-Account-Key-Test")
  1173. user, _, err = httpd.AddUser(user, http.StatusOK)
  1174. assert.NoError(t, err)
  1175. initialPayload = user.FsConfig.AzBlobConfig.AccountKey.GetPayload()
  1176. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1177. assert.NotEmpty(t, initialPayload)
  1178. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1179. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1180. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1181. user.FsConfig.AzBlobConfig.Container = "test-container"
  1182. user.FsConfig.AzBlobConfig.Endpoint = "http://localhost:9001"
  1183. user.FsConfig.AzBlobConfig.KeyPrefix = "somedir/subdir"
  1184. user.FsConfig.AzBlobConfig.UploadConcurrency = 5
  1185. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1186. assert.NoError(t, err)
  1187. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1188. assert.NotEmpty(t, initialPayload)
  1189. assert.Equal(t, initialPayload, user.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1190. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1191. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1192. // test user without access key and access secret (sas)
  1193. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1194. user.FsConfig.AzBlobConfig.SASURL = "https://myaccount.blob.core.windows.net/pictures/profile.jpg?sv=2012-02-12&st=2009-02-09&se=2009-02-10&sr=c&sp=r&si=YWJjZGVmZw%3d%3d&sig=dD80ihBh5jfNpymO5Hg1IdiJIEvHcJpCMiCMnN%2fRnbI%3d"
  1195. user.FsConfig.AzBlobConfig.KeyPrefix = "somedir/subdir"
  1196. user.FsConfig.AzBlobConfig.AccountName = ""
  1197. user.FsConfig.AzBlobConfig.AccountKey = kms.NewEmptySecret()
  1198. user.FsConfig.AzBlobConfig.UploadPartSize = 6
  1199. user.FsConfig.AzBlobConfig.UploadConcurrency = 4
  1200. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1201. assert.NoError(t, err)
  1202. assert.True(t, user.FsConfig.AzBlobConfig.AccountKey.IsEmpty())
  1203. _, err = httpd.RemoveUser(user, http.StatusOK)
  1204. assert.NoError(t, err)
  1205. user.Password = defaultPassword
  1206. user.ID = 0
  1207. // sas test for add instead of update
  1208. user, _, err = httpd.AddUser(user, http.StatusOK)
  1209. assert.NoError(t, err)
  1210. assert.True(t, user.FsConfig.AzBlobConfig.AccountKey.IsEmpty())
  1211. _, err = httpd.RemoveUser(user, http.StatusOK)
  1212. assert.NoError(t, err)
  1213. }
  1214. func TestUserCryptFs(t *testing.T) {
  1215. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1216. assert.NoError(t, err)
  1217. user.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  1218. user.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("crypt passphrase")
  1219. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1220. assert.NoError(t, err)
  1221. initialPayload := user.FsConfig.CryptConfig.Passphrase.GetPayload()
  1222. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1223. assert.NotEmpty(t, initialPayload)
  1224. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1225. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1226. user.FsConfig.CryptConfig.Passphrase.SetStatus(kms.SecretStatusSecretBox)
  1227. user.FsConfig.CryptConfig.Passphrase.SetAdditionalData("data")
  1228. user.FsConfig.CryptConfig.Passphrase.SetKey("fake pass key")
  1229. user, bb, err := httpd.UpdateUser(user, http.StatusOK, "")
  1230. assert.NoError(t, err, string(bb))
  1231. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1232. assert.Equal(t, initialPayload, user.FsConfig.CryptConfig.Passphrase.GetPayload())
  1233. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1234. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1235. _, err = httpd.RemoveUser(user, http.StatusOK)
  1236. assert.NoError(t, err)
  1237. user.Password = defaultPassword
  1238. user.ID = 0
  1239. secret := kms.NewSecret(kms.SecretStatusSecretBox, "invalid encrypted payload", "", "")
  1240. user.FsConfig.CryptConfig.Passphrase = secret
  1241. _, _, err = httpd.AddUser(user, http.StatusOK)
  1242. assert.Error(t, err)
  1243. user.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("passphrase test")
  1244. user, _, err = httpd.AddUser(user, http.StatusOK)
  1245. assert.NoError(t, err)
  1246. initialPayload = user.FsConfig.CryptConfig.Passphrase.GetPayload()
  1247. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1248. assert.NotEmpty(t, initialPayload)
  1249. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1250. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1251. user.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  1252. user.FsConfig.CryptConfig.Passphrase.SetKey("pass")
  1253. user, bb, err = httpd.UpdateUser(user, http.StatusOK, "")
  1254. assert.NoError(t, err, string(bb))
  1255. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1256. assert.NotEmpty(t, initialPayload)
  1257. assert.Equal(t, initialPayload, user.FsConfig.CryptConfig.Passphrase.GetPayload())
  1258. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1259. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1260. _, err = httpd.RemoveUser(user, http.StatusOK)
  1261. assert.NoError(t, err)
  1262. }
  1263. func TestUserSFTPFs(t *testing.T) {
  1264. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1265. assert.NoError(t, err)
  1266. user.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  1267. user.FsConfig.SFTPConfig.Endpoint = "127.0.0.1:2022"
  1268. user.FsConfig.SFTPConfig.Username = "sftp_user"
  1269. user.FsConfig.SFTPConfig.Password = kms.NewPlainSecret("sftp_pwd")
  1270. user.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  1271. user.FsConfig.SFTPConfig.Fingerprints = []string{sftpPkeyFingerprint}
  1272. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1273. assert.NoError(t, err)
  1274. assert.Equal(t, "/", user.FsConfig.SFTPConfig.Prefix)
  1275. initialPwdPayload := user.FsConfig.SFTPConfig.Password.GetPayload()
  1276. initialPkeyPayload := user.FsConfig.SFTPConfig.PrivateKey.GetPayload()
  1277. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.Password.GetStatus())
  1278. assert.NotEmpty(t, initialPwdPayload)
  1279. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1280. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetKey())
  1281. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1282. assert.NotEmpty(t, initialPkeyPayload)
  1283. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1284. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1285. user.FsConfig.SFTPConfig.Password.SetStatus(kms.SecretStatusSecretBox)
  1286. user.FsConfig.SFTPConfig.Password.SetAdditionalData("adata")
  1287. user.FsConfig.SFTPConfig.Password.SetKey("fake pwd key")
  1288. user.FsConfig.SFTPConfig.PrivateKey.SetStatus(kms.SecretStatusSecretBox)
  1289. user.FsConfig.SFTPConfig.PrivateKey.SetAdditionalData("adata")
  1290. user.FsConfig.SFTPConfig.PrivateKey.SetKey("fake key")
  1291. user, bb, err := httpd.UpdateUser(user, http.StatusOK, "")
  1292. assert.NoError(t, err, string(bb))
  1293. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.Password.GetStatus())
  1294. assert.Equal(t, initialPwdPayload, user.FsConfig.SFTPConfig.Password.GetPayload())
  1295. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1296. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetKey())
  1297. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1298. assert.Equal(t, initialPkeyPayload, user.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1299. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1300. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1301. _, err = httpd.RemoveUser(user, http.StatusOK)
  1302. assert.NoError(t, err)
  1303. user.Password = defaultPassword
  1304. user.ID = 0
  1305. secret := kms.NewSecret(kms.SecretStatusSecretBox, "invalid encrypted payload", "", "")
  1306. user.FsConfig.SFTPConfig.Password = secret
  1307. _, _, err = httpd.AddUser(user, http.StatusOK)
  1308. assert.Error(t, err)
  1309. user.FsConfig.SFTPConfig.Password = kms.NewEmptySecret()
  1310. user.FsConfig.SFTPConfig.PrivateKey = secret
  1311. _, _, err = httpd.AddUser(user, http.StatusOK)
  1312. assert.Error(t, err)
  1313. user.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  1314. user, _, err = httpd.AddUser(user, http.StatusOK)
  1315. assert.NoError(t, err)
  1316. initialPkeyPayload = user.FsConfig.SFTPConfig.PrivateKey.GetPayload()
  1317. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetStatus())
  1318. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1319. assert.NotEmpty(t, initialPkeyPayload)
  1320. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1321. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1322. user.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  1323. user.FsConfig.SFTPConfig.PrivateKey.SetKey("k")
  1324. user, bb, err = httpd.UpdateUser(user, http.StatusOK, "")
  1325. assert.NoError(t, err, string(bb))
  1326. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1327. assert.NotEmpty(t, initialPkeyPayload)
  1328. assert.Equal(t, initialPkeyPayload, user.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1329. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1330. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1331. _, err = httpd.RemoveUser(user, http.StatusOK)
  1332. assert.NoError(t, err)
  1333. }
  1334. func TestUserHiddenFields(t *testing.T) {
  1335. err := dataprovider.Close()
  1336. assert.NoError(t, err)
  1337. err = config.LoadConfig(configDir, "")
  1338. assert.NoError(t, err)
  1339. providerConf := config.GetProviderConf()
  1340. providerConf.PreferDatabaseCredentials = true
  1341. err = dataprovider.Initialize(providerConf, configDir)
  1342. assert.NoError(t, err)
  1343. // sensitive data must be hidden but not deleted from the dataprovider
  1344. usernames := []string{"user1", "user2", "user3", "user4", "user5"}
  1345. u1 := getTestUser()
  1346. u1.Username = usernames[0]
  1347. u1.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1348. u1.FsConfig.S3Config.Bucket = "test"
  1349. u1.FsConfig.S3Config.Region = "us-east-1"
  1350. u1.FsConfig.S3Config.AccessKey = "S3-Access-Key"
  1351. u1.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("S3-Access-Secret")
  1352. user1, _, err := httpd.AddUser(u1, http.StatusOK)
  1353. assert.NoError(t, err)
  1354. u2 := getTestUser()
  1355. u2.Username = usernames[1]
  1356. u2.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  1357. u2.FsConfig.GCSConfig.Bucket = "test"
  1358. u2.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("fake credentials")
  1359. user2, _, err := httpd.AddUser(u2, http.StatusOK)
  1360. assert.NoError(t, err)
  1361. u3 := getTestUser()
  1362. u3.Username = usernames[2]
  1363. u3.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1364. u3.FsConfig.AzBlobConfig.Container = "test"
  1365. u3.FsConfig.AzBlobConfig.AccountName = "Server-Account-Name"
  1366. u3.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("Server-Account-Key")
  1367. user3, _, err := httpd.AddUser(u3, http.StatusOK)
  1368. assert.NoError(t, err)
  1369. u4 := getTestUser()
  1370. u4.Username = usernames[3]
  1371. u4.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  1372. u4.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("test passphrase")
  1373. user4, _, err := httpd.AddUser(u4, http.StatusOK)
  1374. assert.NoError(t, err)
  1375. u5 := getTestUser()
  1376. u5.Username = usernames[4]
  1377. u5.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  1378. u5.FsConfig.SFTPConfig.Endpoint = "127.0.0.1:2022"
  1379. u5.FsConfig.SFTPConfig.Username = "sftp_user"
  1380. u5.FsConfig.SFTPConfig.Password = kms.NewPlainSecret("apassword")
  1381. u5.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  1382. u5.FsConfig.SFTPConfig.Fingerprints = []string{sftpPkeyFingerprint}
  1383. u5.FsConfig.SFTPConfig.Prefix = "/prefix"
  1384. user5, _, err := httpd.AddUser(u5, http.StatusOK)
  1385. assert.NoError(t, err)
  1386. users, _, err := httpd.GetUsers(0, 0, "", http.StatusOK)
  1387. assert.NoError(t, err)
  1388. assert.GreaterOrEqual(t, len(users), 5)
  1389. for _, username := range usernames {
  1390. users, _, err = httpd.GetUsers(0, 0, username, http.StatusOK)
  1391. assert.NoError(t, err)
  1392. if assert.Len(t, users, 1) {
  1393. user := users[0]
  1394. assert.Empty(t, user.Password)
  1395. }
  1396. }
  1397. user1, _, err = httpd.GetUserByID(user1.ID, http.StatusOK)
  1398. assert.NoError(t, err)
  1399. assert.Empty(t, user1.Password)
  1400. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetKey())
  1401. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1402. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetStatus())
  1403. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetPayload())
  1404. user2, _, err = httpd.GetUserByID(user2.ID, http.StatusOK)
  1405. assert.NoError(t, err)
  1406. assert.Empty(t, user2.Password)
  1407. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetKey())
  1408. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetAdditionalData())
  1409. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetStatus())
  1410. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetPayload())
  1411. user3, _, err = httpd.GetUserByID(user3.ID, http.StatusOK)
  1412. assert.NoError(t, err)
  1413. assert.Empty(t, user3.Password)
  1414. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1415. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1416. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1417. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1418. user4, _, err = httpd.GetUserByID(user4.ID, http.StatusOK)
  1419. assert.NoError(t, err)
  1420. assert.Empty(t, user4.Password)
  1421. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetKey())
  1422. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1423. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetStatus())
  1424. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetPayload())
  1425. user5, _, err = httpd.GetUserByID(user5.ID, http.StatusOK)
  1426. assert.NoError(t, err)
  1427. assert.Empty(t, user5.Password)
  1428. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetKey())
  1429. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1430. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetStatus())
  1431. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetPayload())
  1432. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1433. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1434. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1435. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1436. assert.Equal(t, "/prefix", user5.FsConfig.SFTPConfig.Prefix)
  1437. // finally check that we have all the data inside the data provider
  1438. user1, err = dataprovider.GetUserByID(user1.ID)
  1439. assert.NoError(t, err)
  1440. assert.NotEmpty(t, user1.Password)
  1441. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetKey())
  1442. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1443. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetStatus())
  1444. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetPayload())
  1445. err = user1.FsConfig.S3Config.AccessSecret.Decrypt()
  1446. assert.NoError(t, err)
  1447. assert.Equal(t, kms.SecretStatusPlain, user1.FsConfig.S3Config.AccessSecret.GetStatus())
  1448. assert.Equal(t, u1.FsConfig.S3Config.AccessSecret.GetPayload(), user1.FsConfig.S3Config.AccessSecret.GetPayload())
  1449. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetKey())
  1450. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1451. user2, err = dataprovider.GetUserByID(user2.ID)
  1452. assert.NoError(t, err)
  1453. assert.NotEmpty(t, user2.Password)
  1454. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetKey())
  1455. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetAdditionalData())
  1456. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetStatus())
  1457. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetPayload())
  1458. err = user2.FsConfig.GCSConfig.Credentials.Decrypt()
  1459. assert.NoError(t, err)
  1460. assert.Equal(t, kms.SecretStatusPlain, user2.FsConfig.GCSConfig.Credentials.GetStatus())
  1461. assert.Equal(t, u2.FsConfig.GCSConfig.Credentials.GetPayload(), user2.FsConfig.GCSConfig.Credentials.GetPayload())
  1462. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetKey())
  1463. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetAdditionalData())
  1464. user3, err = dataprovider.GetUserByID(user3.ID)
  1465. assert.NoError(t, err)
  1466. assert.NotEmpty(t, user3.Password)
  1467. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1468. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1469. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1470. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1471. err = user3.FsConfig.AzBlobConfig.AccountKey.Decrypt()
  1472. assert.NoError(t, err)
  1473. assert.Equal(t, kms.SecretStatusPlain, user3.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1474. assert.Equal(t, u3.FsConfig.AzBlobConfig.AccountKey.GetPayload(), user3.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1475. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1476. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1477. user4, err = dataprovider.GetUserByID(user4.ID)
  1478. assert.NoError(t, err)
  1479. assert.NotEmpty(t, user4.Password)
  1480. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetKey())
  1481. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1482. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetStatus())
  1483. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetPayload())
  1484. err = user4.FsConfig.CryptConfig.Passphrase.Decrypt()
  1485. assert.NoError(t, err)
  1486. assert.Equal(t, kms.SecretStatusPlain, user4.FsConfig.CryptConfig.Passphrase.GetStatus())
  1487. assert.Equal(t, u4.FsConfig.CryptConfig.Passphrase.GetPayload(), user4.FsConfig.CryptConfig.Passphrase.GetPayload())
  1488. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetKey())
  1489. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1490. user5, err = dataprovider.GetUserByID(user5.ID)
  1491. assert.NoError(t, err)
  1492. assert.NotEmpty(t, user5.Password)
  1493. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetKey())
  1494. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1495. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetStatus())
  1496. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetPayload())
  1497. err = user5.FsConfig.SFTPConfig.Password.Decrypt()
  1498. assert.NoError(t, err)
  1499. assert.Equal(t, kms.SecretStatusPlain, user5.FsConfig.SFTPConfig.Password.GetStatus())
  1500. assert.Equal(t, u5.FsConfig.SFTPConfig.Password.GetPayload(), user5.FsConfig.SFTPConfig.Password.GetPayload())
  1501. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetKey())
  1502. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1503. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1504. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1505. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1506. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1507. err = user5.FsConfig.SFTPConfig.PrivateKey.Decrypt()
  1508. assert.NoError(t, err)
  1509. assert.Equal(t, kms.SecretStatusPlain, user5.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1510. assert.Equal(t, u5.FsConfig.SFTPConfig.PrivateKey.GetPayload(), user5.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1511. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1512. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1513. _, err = httpd.RemoveUser(user1, http.StatusOK)
  1514. assert.NoError(t, err)
  1515. _, err = httpd.RemoveUser(user2, http.StatusOK)
  1516. assert.NoError(t, err)
  1517. _, err = httpd.RemoveUser(user3, http.StatusOK)
  1518. assert.NoError(t, err)
  1519. _, err = httpd.RemoveUser(user4, http.StatusOK)
  1520. assert.NoError(t, err)
  1521. _, err = httpd.RemoveUser(user5, http.StatusOK)
  1522. assert.NoError(t, err)
  1523. err = dataprovider.Close()
  1524. assert.NoError(t, err)
  1525. err = config.LoadConfig(configDir, "")
  1526. assert.NoError(t, err)
  1527. providerConf = config.GetProviderConf()
  1528. providerConf.CredentialsPath = credentialsPath
  1529. err = os.RemoveAll(credentialsPath)
  1530. assert.NoError(t, err)
  1531. err = dataprovider.Initialize(providerConf, configDir)
  1532. assert.NoError(t, err)
  1533. }
  1534. func TestSecretObject(t *testing.T) {
  1535. s := kms.NewPlainSecret("test data")
  1536. s.SetAdditionalData("username")
  1537. require.True(t, s.IsValid())
  1538. err := s.Encrypt()
  1539. require.NoError(t, err)
  1540. require.Equal(t, kms.SecretStatusSecretBox, s.GetStatus())
  1541. require.NotEmpty(t, s.GetPayload())
  1542. require.NotEmpty(t, s.GetKey())
  1543. require.True(t, s.IsValid())
  1544. err = s.Decrypt()
  1545. require.NoError(t, err)
  1546. require.Equal(t, kms.SecretStatusPlain, s.GetStatus())
  1547. require.Equal(t, "test data", s.GetPayload())
  1548. require.Empty(t, s.GetKey())
  1549. oldFormat := "$aes$5b97e3a3324a2f53e2357483383367c0$0ed3132b584742ab217866219da633266782b69b13e50ebc6ddfb7c4fbf2f2a414c6d5f813"
  1550. s, err = kms.GetSecretFromCompatString(oldFormat)
  1551. require.NoError(t, err)
  1552. require.True(t, s.IsValid())
  1553. require.Equal(t, kms.SecretStatusPlain, s.GetStatus())
  1554. require.Equal(t, "test data", s.GetPayload())
  1555. require.Empty(t, s.GetKey())
  1556. }
  1557. func TestSecretObjectCompatibility(t *testing.T) {
  1558. // this is manually tested against vault too
  1559. testPayload := "test payload"
  1560. s := kms.NewPlainSecret(testPayload)
  1561. require.True(t, s.IsValid())
  1562. err := s.Encrypt()
  1563. require.NoError(t, err)
  1564. localAsJSON, err := json.Marshal(s)
  1565. assert.NoError(t, err)
  1566. for _, secretStatus := range []string{kms.SecretStatusSecretBox} {
  1567. kmsConfig := config.GetKMSConfig()
  1568. assert.Empty(t, kmsConfig.Secrets.MasterKeyPath)
  1569. if secretStatus == kms.SecretStatusVaultTransit {
  1570. os.Setenv("VAULT_SERVER_URL", "http://127.0.0.1:8200")
  1571. os.Setenv("VAULT_SERVER_TOKEN", "s.9lYGq83MbgG5KR5kfebXVyhJ")
  1572. kmsConfig.Secrets.URL = "hashivault://mykey"
  1573. }
  1574. err := kmsConfig.Initialize()
  1575. assert.NoError(t, err)
  1576. // encrypt without a master key
  1577. secret := kms.NewPlainSecret(testPayload)
  1578. secret.SetAdditionalData("add data")
  1579. err = secret.Encrypt()
  1580. assert.NoError(t, err)
  1581. assert.Equal(t, 0, secret.GetMode())
  1582. secretClone := secret.Clone()
  1583. err = secretClone.Decrypt()
  1584. assert.NoError(t, err)
  1585. assert.Equal(t, testPayload, secretClone.GetPayload())
  1586. if secretStatus == kms.SecretStatusVaultTransit {
  1587. // decrypt the local secret now that the provider is vault
  1588. secretLocal := kms.NewEmptySecret()
  1589. err = json.Unmarshal(localAsJSON, secretLocal)
  1590. assert.NoError(t, err)
  1591. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1592. assert.Equal(t, 0, secretLocal.GetMode())
  1593. err = secretLocal.Decrypt()
  1594. assert.NoError(t, err)
  1595. assert.Equal(t, testPayload, secretLocal.GetPayload())
  1596. assert.Equal(t, kms.SecretStatusPlain, secretLocal.GetStatus())
  1597. err = secretLocal.Encrypt()
  1598. assert.NoError(t, err)
  1599. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1600. assert.Equal(t, 0, secretLocal.GetMode())
  1601. }
  1602. asJSON, err := json.Marshal(secret)
  1603. assert.NoError(t, err)
  1604. masterKeyPath := filepath.Join(os.TempDir(), "mkey")
  1605. err = ioutil.WriteFile(masterKeyPath, []byte("test key"), os.ModePerm)
  1606. assert.NoError(t, err)
  1607. config := kms.Configuration{
  1608. Secrets: kms.Secrets{
  1609. MasterKeyPath: masterKeyPath,
  1610. },
  1611. }
  1612. if secretStatus == kms.SecretStatusVaultTransit {
  1613. config.Secrets.URL = "hashivault://mykey"
  1614. }
  1615. err = config.Initialize()
  1616. assert.NoError(t, err)
  1617. // now build the secret from JSON
  1618. secret = kms.NewEmptySecret()
  1619. err = json.Unmarshal(asJSON, secret)
  1620. assert.NoError(t, err)
  1621. assert.Equal(t, 0, secret.GetMode())
  1622. err = secret.Decrypt()
  1623. assert.NoError(t, err)
  1624. assert.Equal(t, testPayload, secret.GetPayload())
  1625. err = secret.Encrypt()
  1626. assert.NoError(t, err)
  1627. assert.Equal(t, 1, secret.GetMode())
  1628. err = secret.Decrypt()
  1629. assert.NoError(t, err)
  1630. assert.Equal(t, testPayload, secret.GetPayload())
  1631. if secretStatus == kms.SecretStatusVaultTransit {
  1632. // decrypt the local secret encryped without a master key now that
  1633. // the provider is vault and a master key is set.
  1634. // The provider will not change, the master key will be used
  1635. secretLocal := kms.NewEmptySecret()
  1636. err = json.Unmarshal(localAsJSON, secretLocal)
  1637. assert.NoError(t, err)
  1638. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1639. assert.Equal(t, 0, secretLocal.GetMode())
  1640. err = secretLocal.Decrypt()
  1641. assert.NoError(t, err)
  1642. assert.Equal(t, testPayload, secretLocal.GetPayload())
  1643. assert.Equal(t, kms.SecretStatusPlain, secretLocal.GetStatus())
  1644. err = secretLocal.Encrypt()
  1645. assert.NoError(t, err)
  1646. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1647. assert.Equal(t, 1, secretLocal.GetMode())
  1648. }
  1649. err = kmsConfig.Initialize()
  1650. assert.NoError(t, err)
  1651. err = os.Remove(masterKeyPath)
  1652. assert.NoError(t, err)
  1653. if secretStatus == kms.SecretStatusVaultTransit {
  1654. os.Unsetenv("VAULT_SERVER_URL")
  1655. os.Unsetenv("VAULT_SERVER_TOKEN")
  1656. }
  1657. }
  1658. }
  1659. func TestUpdateUserNoCredentials(t *testing.T) {
  1660. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1661. assert.NoError(t, err)
  1662. user.Password = ""
  1663. user.PublicKeys = []string{}
  1664. // password and public key will be omitted from json serialization if empty and so they will remain unchanged
  1665. // and no validation error will be raised
  1666. _, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  1667. assert.NoError(t, err)
  1668. _, err = httpd.RemoveUser(user, http.StatusOK)
  1669. assert.NoError(t, err)
  1670. }
  1671. func TestUpdateUserEmptyHomeDir(t *testing.T) {
  1672. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1673. assert.NoError(t, err)
  1674. user.HomeDir = ""
  1675. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest, "")
  1676. assert.NoError(t, err)
  1677. _, err = httpd.RemoveUser(user, http.StatusOK)
  1678. assert.NoError(t, err)
  1679. }
  1680. func TestUpdateUserInvalidHomeDir(t *testing.T) {
  1681. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1682. assert.NoError(t, err)
  1683. user.HomeDir = "relative_path"
  1684. _, _, err = httpd.UpdateUser(user, http.StatusBadRequest, "")
  1685. assert.NoError(t, err)
  1686. _, err = httpd.RemoveUser(user, http.StatusOK)
  1687. assert.NoError(t, err)
  1688. }
  1689. func TestUpdateNonExistentUser(t *testing.T) {
  1690. _, _, err := httpd.UpdateUser(getTestUser(), http.StatusNotFound, "")
  1691. assert.NoError(t, err)
  1692. }
  1693. func TestGetNonExistentUser(t *testing.T) {
  1694. _, _, err := httpd.GetUserByID(0, http.StatusNotFound)
  1695. assert.NoError(t, err)
  1696. }
  1697. func TestDeleteNonExistentUser(t *testing.T) {
  1698. _, err := httpd.RemoveUser(getTestUser(), http.StatusNotFound)
  1699. assert.NoError(t, err)
  1700. }
  1701. func TestAddDuplicateUser(t *testing.T) {
  1702. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1703. assert.NoError(t, err)
  1704. _, _, err = httpd.AddUser(getTestUser(), http.StatusInternalServerError)
  1705. assert.NoError(t, err)
  1706. _, _, err = httpd.AddUser(getTestUser(), http.StatusOK)
  1707. assert.Error(t, err, "adding a duplicate user must fail")
  1708. _, err = httpd.RemoveUser(user, http.StatusOK)
  1709. assert.NoError(t, err)
  1710. }
  1711. func TestGetUsers(t *testing.T) {
  1712. user1, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1713. assert.NoError(t, err)
  1714. u := getTestUser()
  1715. u.Username = defaultUsername + "1"
  1716. user2, _, err := httpd.AddUser(u, http.StatusOK)
  1717. assert.NoError(t, err)
  1718. users, _, err := httpd.GetUsers(0, 0, "", http.StatusOK)
  1719. assert.NoError(t, err)
  1720. assert.GreaterOrEqual(t, len(users), 2)
  1721. users, _, err = httpd.GetUsers(1, 0, "", http.StatusOK)
  1722. assert.NoError(t, err)
  1723. assert.Equal(t, 1, len(users))
  1724. users, _, err = httpd.GetUsers(1, 1, "", http.StatusOK)
  1725. assert.NoError(t, err)
  1726. assert.Equal(t, 1, len(users))
  1727. _, _, err = httpd.GetUsers(1, 1, "", http.StatusInternalServerError)
  1728. assert.Error(t, err)
  1729. _, err = httpd.RemoveUser(user1, http.StatusOK)
  1730. assert.NoError(t, err)
  1731. _, err = httpd.RemoveUser(user2, http.StatusOK)
  1732. assert.NoError(t, err)
  1733. }
  1734. func TestGetQuotaScans(t *testing.T) {
  1735. _, _, err := httpd.GetQuotaScans(http.StatusOK)
  1736. assert.NoError(t, err)
  1737. _, _, err = httpd.GetQuotaScans(http.StatusInternalServerError)
  1738. assert.Error(t, err)
  1739. _, _, err = httpd.GetFoldersQuotaScans(http.StatusOK)
  1740. assert.NoError(t, err)
  1741. _, _, err = httpd.GetFoldersQuotaScans(http.StatusInternalServerError)
  1742. assert.Error(t, err)
  1743. }
  1744. func TestStartQuotaScan(t *testing.T) {
  1745. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1746. assert.NoError(t, err)
  1747. _, err = httpd.StartQuotaScan(user, http.StatusAccepted)
  1748. assert.NoError(t, err)
  1749. _, err = httpd.RemoveUser(user, http.StatusOK)
  1750. assert.NoError(t, err)
  1751. folder := vfs.BaseVirtualFolder{
  1752. MappedPath: filepath.Join(os.TempDir(), "folder"),
  1753. }
  1754. _, _, err = httpd.AddFolder(folder, http.StatusOK)
  1755. assert.NoError(t, err)
  1756. _, err = httpd.StartFolderQuotaScan(folder, http.StatusAccepted)
  1757. assert.NoError(t, err)
  1758. for {
  1759. quotaScan, _, err := httpd.GetFoldersQuotaScans(http.StatusOK)
  1760. if !assert.NoError(t, err, "Error getting active scans") {
  1761. break
  1762. }
  1763. if len(quotaScan) == 0 {
  1764. break
  1765. }
  1766. time.Sleep(100 * time.Millisecond)
  1767. }
  1768. _, err = httpd.RemoveFolder(folder, http.StatusOK)
  1769. assert.NoError(t, err)
  1770. }
  1771. func TestUpdateFolderQuotaUsage(t *testing.T) {
  1772. f := vfs.BaseVirtualFolder{
  1773. MappedPath: filepath.Join(os.TempDir(), "folder"),
  1774. }
  1775. usedQuotaFiles := 1
  1776. usedQuotaSize := int64(65535)
  1777. f.UsedQuotaFiles = usedQuotaFiles
  1778. f.UsedQuotaSize = usedQuotaSize
  1779. folder, _, err := httpd.AddFolder(f, http.StatusOK)
  1780. if assert.NoError(t, err) {
  1781. assert.Equal(t, usedQuotaFiles, folder.UsedQuotaFiles)
  1782. assert.Equal(t, usedQuotaSize, folder.UsedQuotaSize)
  1783. }
  1784. _, err = httpd.UpdateFolderQuotaUsage(folder, "invalid mode", http.StatusBadRequest)
  1785. assert.NoError(t, err)
  1786. _, err = httpd.UpdateFolderQuotaUsage(f, "reset", http.StatusOK)
  1787. assert.NoError(t, err)
  1788. folders, _, err := httpd.GetFolders(0, 0, f.MappedPath, http.StatusOK)
  1789. assert.NoError(t, err)
  1790. if assert.Len(t, folders, 1) {
  1791. folder = folders[0]
  1792. assert.Equal(t, usedQuotaFiles, folder.UsedQuotaFiles)
  1793. assert.Equal(t, usedQuotaSize, folder.UsedQuotaSize)
  1794. }
  1795. _, err = httpd.UpdateFolderQuotaUsage(f, "add", http.StatusOK)
  1796. assert.NoError(t, err)
  1797. folders, _, err = httpd.GetFolders(0, 0, f.MappedPath, http.StatusOK)
  1798. assert.NoError(t, err)
  1799. if assert.Len(t, folders, 1) {
  1800. folder = folders[0]
  1801. assert.Equal(t, 2*usedQuotaFiles, folder.UsedQuotaFiles)
  1802. assert.Equal(t, 2*usedQuotaSize, folder.UsedQuotaSize)
  1803. }
  1804. f.UsedQuotaSize = -1
  1805. _, err = httpd.UpdateFolderQuotaUsage(f, "", http.StatusBadRequest)
  1806. assert.NoError(t, err)
  1807. f.UsedQuotaSize = usedQuotaSize
  1808. f.MappedPath = f.MappedPath + "1"
  1809. _, err = httpd.UpdateFolderQuotaUsage(f, "", http.StatusNotFound)
  1810. assert.NoError(t, err)
  1811. _, err = httpd.RemoveFolder(folder, http.StatusOK)
  1812. assert.NoError(t, err)
  1813. }
  1814. func TestGetVersion(t *testing.T) {
  1815. _, _, err := httpd.GetVersion(http.StatusOK)
  1816. assert.NoError(t, err)
  1817. _, _, err = httpd.GetVersion(http.StatusInternalServerError)
  1818. assert.Error(t, err, "get version request must succeed, we requested to check a wrong status code")
  1819. }
  1820. func TestGetStatus(t *testing.T) {
  1821. _, _, err := httpd.GetStatus(http.StatusOK)
  1822. assert.NoError(t, err)
  1823. _, _, err = httpd.GetStatus(http.StatusBadRequest)
  1824. assert.Error(t, err, "get provider status request must succeed, we requested to check a wrong status code")
  1825. }
  1826. func TestGetConnections(t *testing.T) {
  1827. _, _, err := httpd.GetConnections(http.StatusOK)
  1828. assert.NoError(t, err)
  1829. _, _, err = httpd.GetConnections(http.StatusInternalServerError)
  1830. assert.Error(t, err, "get sftp connections request must succeed, we requested to check a wrong status code")
  1831. }
  1832. func TestCloseActiveConnection(t *testing.T) {
  1833. _, err := httpd.CloseConnection("non_existent_id", http.StatusNotFound)
  1834. assert.NoError(t, err)
  1835. user := getTestUser()
  1836. c := common.NewBaseConnection("connID", common.ProtocolSFTP, user, nil)
  1837. fakeConn := &fakeConnection{
  1838. BaseConnection: c,
  1839. }
  1840. common.Connections.Add(fakeConn)
  1841. _, err = httpd.CloseConnection(c.GetID(), http.StatusOK)
  1842. assert.NoError(t, err)
  1843. assert.Len(t, common.Connections.GetStats(), 0)
  1844. }
  1845. func TestCloseConnectionAfterUserUpdateDelete(t *testing.T) {
  1846. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1847. assert.NoError(t, err)
  1848. c := common.NewBaseConnection("connID", common.ProtocolFTP, user, nil)
  1849. fakeConn := &fakeConnection{
  1850. BaseConnection: c,
  1851. }
  1852. common.Connections.Add(fakeConn)
  1853. c1 := common.NewBaseConnection("connID1", common.ProtocolSFTP, user, nil)
  1854. fakeConn1 := &fakeConnection{
  1855. BaseConnection: c1,
  1856. }
  1857. common.Connections.Add(fakeConn1)
  1858. user, _, err = httpd.UpdateUser(user, http.StatusOK, "0")
  1859. assert.NoError(t, err)
  1860. assert.Len(t, common.Connections.GetStats(), 2)
  1861. user, _, err = httpd.UpdateUser(user, http.StatusOK, "1")
  1862. assert.NoError(t, err)
  1863. assert.Len(t, common.Connections.GetStats(), 0)
  1864. common.Connections.Add(fakeConn)
  1865. common.Connections.Add(fakeConn1)
  1866. assert.Len(t, common.Connections.GetStats(), 2)
  1867. _, err = httpd.RemoveUser(user, http.StatusOK)
  1868. assert.NoError(t, err)
  1869. assert.Len(t, common.Connections.GetStats(), 0)
  1870. }
  1871. func TestUserBaseDir(t *testing.T) {
  1872. err := dataprovider.Close()
  1873. assert.NoError(t, err)
  1874. err = config.LoadConfig(configDir, "")
  1875. assert.NoError(t, err)
  1876. providerConf := config.GetProviderConf()
  1877. providerConf.UsersBaseDir = homeBasePath
  1878. err = dataprovider.Initialize(providerConf, configDir)
  1879. assert.NoError(t, err)
  1880. u := getTestUser()
  1881. u.HomeDir = ""
  1882. user, _, err := httpd.AddUser(u, http.StatusOK)
  1883. if assert.Error(t, err) {
  1884. assert.EqualError(t, err, "HomeDir mismatch")
  1885. }
  1886. assert.Equal(t, filepath.Join(providerConf.UsersBaseDir, u.Username), user.HomeDir)
  1887. _, err = httpd.RemoveUser(user, http.StatusOK)
  1888. assert.NoError(t, err)
  1889. err = dataprovider.Close()
  1890. assert.NoError(t, err)
  1891. err = config.LoadConfig(configDir, "")
  1892. assert.NoError(t, err)
  1893. providerConf = config.GetProviderConf()
  1894. providerConf.CredentialsPath = credentialsPath
  1895. err = os.RemoveAll(credentialsPath)
  1896. assert.NoError(t, err)
  1897. err = dataprovider.Initialize(providerConf, configDir)
  1898. assert.NoError(t, err)
  1899. }
  1900. func TestQuotaTrackingDisabled(t *testing.T) {
  1901. err := dataprovider.Close()
  1902. assert.NoError(t, err)
  1903. err = config.LoadConfig(configDir, "")
  1904. assert.NoError(t, err)
  1905. providerConf := config.GetProviderConf()
  1906. providerConf.TrackQuota = 0
  1907. err = dataprovider.Initialize(providerConf, configDir)
  1908. assert.NoError(t, err)
  1909. // user quota scan must fail
  1910. user, _, err := httpd.AddUser(getTestUser(), http.StatusOK)
  1911. assert.NoError(t, err)
  1912. _, err = httpd.StartQuotaScan(user, http.StatusForbidden)
  1913. assert.NoError(t, err)
  1914. _, err = httpd.UpdateQuotaUsage(user, "", http.StatusForbidden)
  1915. assert.NoError(t, err)
  1916. _, err = httpd.RemoveUser(user, http.StatusOK)
  1917. assert.NoError(t, err)
  1918. // folder quota scan must fail
  1919. folder := vfs.BaseVirtualFolder{
  1920. MappedPath: filepath.Clean(os.TempDir()),
  1921. }
  1922. folder, _, err = httpd.AddFolder(folder, http.StatusOK)
  1923. assert.NoError(t, err)
  1924. _, err = httpd.StartFolderQuotaScan(folder, http.StatusForbidden)
  1925. assert.NoError(t, err)
  1926. _, err = httpd.UpdateFolderQuotaUsage(folder, "", http.StatusForbidden)
  1927. assert.NoError(t, err)
  1928. _, err = httpd.RemoveFolder(folder, http.StatusOK)
  1929. assert.NoError(t, err)
  1930. err = dataprovider.Close()
  1931. assert.NoError(t, err)
  1932. err = config.LoadConfig(configDir, "")
  1933. assert.NoError(t, err)
  1934. providerConf = config.GetProviderConf()
  1935. providerConf.CredentialsPath = credentialsPath
  1936. err = os.RemoveAll(credentialsPath)
  1937. assert.NoError(t, err)
  1938. err = dataprovider.Initialize(providerConf, configDir)
  1939. assert.NoError(t, err)
  1940. }
  1941. func TestProviderErrors(t *testing.T) {
  1942. err := dataprovider.Close()
  1943. assert.NoError(t, err)
  1944. _, _, err = httpd.GetUserByID(0, http.StatusInternalServerError)
  1945. assert.NoError(t, err)
  1946. _, _, err = httpd.GetUsers(1, 0, defaultUsername, http.StatusInternalServerError)
  1947. assert.NoError(t, err)
  1948. _, _, err = httpd.UpdateUser(dataprovider.User{}, http.StatusInternalServerError, "")
  1949. assert.NoError(t, err)
  1950. _, err = httpd.RemoveUser(dataprovider.User{}, http.StatusInternalServerError)
  1951. assert.NoError(t, err)
  1952. _, err = httpd.RemoveFolder(vfs.BaseVirtualFolder{MappedPath: "apath"}, http.StatusInternalServerError)
  1953. assert.NoError(t, err)
  1954. status, _, err := httpd.GetStatus(http.StatusOK)
  1955. if assert.NoError(t, err) {
  1956. assert.False(t, status.DataProvider.IsActive)
  1957. }
  1958. _, _, err = httpd.Dumpdata("backup.json", "", http.StatusInternalServerError)
  1959. assert.NoError(t, err)
  1960. _, _, err = httpd.GetFolders(0, 0, "", http.StatusInternalServerError)
  1961. assert.NoError(t, err)
  1962. user := getTestUser()
  1963. user.ID = 1
  1964. backupData := dataprovider.BackupData{}
  1965. backupData.Users = append(backupData.Users, user)
  1966. backupContent, err := json.Marshal(backupData)
  1967. assert.NoError(t, err)
  1968. backupFilePath := filepath.Join(backupsPath, "backup.json")
  1969. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  1970. assert.NoError(t, err)
  1971. _, _, err = httpd.Loaddata(backupFilePath, "", "", http.StatusInternalServerError)
  1972. assert.NoError(t, err)
  1973. backupData.Folders = append(backupData.Folders, vfs.BaseVirtualFolder{MappedPath: os.TempDir()})
  1974. backupContent, err = json.Marshal(backupData)
  1975. assert.NoError(t, err)
  1976. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  1977. assert.NoError(t, err)
  1978. _, _, err = httpd.Loaddata(backupFilePath, "", "", http.StatusInternalServerError)
  1979. assert.NoError(t, err)
  1980. err = os.Remove(backupFilePath)
  1981. assert.NoError(t, err)
  1982. err = config.LoadConfig(configDir, "")
  1983. assert.NoError(t, err)
  1984. providerConf := config.GetProviderConf()
  1985. providerConf.CredentialsPath = credentialsPath
  1986. err = os.RemoveAll(credentialsPath)
  1987. assert.NoError(t, err)
  1988. err = dataprovider.Initialize(providerConf, configDir)
  1989. assert.NoError(t, err)
  1990. }
  1991. func TestFolders(t *testing.T) {
  1992. folder := vfs.BaseVirtualFolder{
  1993. MappedPath: "relative path",
  1994. }
  1995. _, _, err := httpd.AddFolder(folder, http.StatusBadRequest)
  1996. assert.NoError(t, err)
  1997. folder.MappedPath = filepath.Clean(os.TempDir())
  1998. folder1, _, err := httpd.AddFolder(folder, http.StatusOK)
  1999. assert.NoError(t, err)
  2000. assert.Equal(t, folder.MappedPath, folder1.MappedPath)
  2001. assert.Equal(t, 0, folder1.UsedQuotaFiles)
  2002. assert.Equal(t, int64(0), folder1.UsedQuotaSize)
  2003. assert.Equal(t, int64(0), folder1.LastQuotaUpdate)
  2004. // adding a duplicate folder must fail
  2005. _, _, err = httpd.AddFolder(folder, http.StatusOK)
  2006. assert.Error(t, err)
  2007. folder.MappedPath = filepath.Join(os.TempDir(), "vfolder")
  2008. folder.UsedQuotaFiles = 1
  2009. folder.UsedQuotaSize = 345
  2010. folder.LastQuotaUpdate = 10
  2011. folder2, _, err := httpd.AddFolder(folder, http.StatusOK)
  2012. assert.NoError(t, err)
  2013. assert.Equal(t, 1, folder2.UsedQuotaFiles)
  2014. assert.Equal(t, int64(345), folder2.UsedQuotaSize)
  2015. assert.Equal(t, int64(10), folder2.LastQuotaUpdate)
  2016. folders, _, err := httpd.GetFolders(0, 0, "", http.StatusOK)
  2017. assert.NoError(t, err)
  2018. numResults := len(folders)
  2019. assert.GreaterOrEqual(t, numResults, 2)
  2020. folders, _, err = httpd.GetFolders(0, 1, "", http.StatusOK)
  2021. assert.NoError(t, err)
  2022. assert.Len(t, folders, numResults-1)
  2023. folders, _, err = httpd.GetFolders(1, 0, "", http.StatusOK)
  2024. assert.NoError(t, err)
  2025. assert.Len(t, folders, 1)
  2026. folders, _, err = httpd.GetFolders(0, 0, folder1.MappedPath, http.StatusOK)
  2027. assert.NoError(t, err)
  2028. if assert.Len(t, folders, 1) {
  2029. f := folders[0]
  2030. assert.Equal(t, folder1.MappedPath, f.MappedPath)
  2031. }
  2032. folders, _, err = httpd.GetFolders(0, 0, folder2.MappedPath, http.StatusOK)
  2033. assert.NoError(t, err)
  2034. if assert.Len(t, folders, 1) {
  2035. f := folders[0]
  2036. assert.Equal(t, folder2.MappedPath, f.MappedPath)
  2037. }
  2038. _, err = httpd.RemoveFolder(vfs.BaseVirtualFolder{}, http.StatusBadRequest)
  2039. assert.NoError(t, err)
  2040. _, err = httpd.RemoveFolder(vfs.BaseVirtualFolder{
  2041. MappedPath: "invalid",
  2042. }, http.StatusNotFound)
  2043. assert.NoError(t, err)
  2044. _, err = httpd.RemoveFolder(folder1, http.StatusOK)
  2045. assert.NoError(t, err)
  2046. _, err = httpd.RemoveFolder(folder2, http.StatusOK)
  2047. assert.NoError(t, err)
  2048. }
  2049. func TestDumpdata(t *testing.T) {
  2050. err := dataprovider.Close()
  2051. assert.NoError(t, err)
  2052. err = config.LoadConfig(configDir, "")
  2053. assert.NoError(t, err)
  2054. providerConf := config.GetProviderConf()
  2055. err = dataprovider.Initialize(providerConf, configDir)
  2056. assert.NoError(t, err)
  2057. _, _, err = httpd.Dumpdata("", "", http.StatusBadRequest)
  2058. assert.NoError(t, err)
  2059. _, _, err = httpd.Dumpdata(filepath.Join(backupsPath, "backup.json"), "", http.StatusBadRequest)
  2060. assert.NoError(t, err)
  2061. _, _, err = httpd.Dumpdata("../backup.json", "", http.StatusBadRequest)
  2062. assert.NoError(t, err)
  2063. _, _, err = httpd.Dumpdata("backup.json", "0", http.StatusOK)
  2064. assert.NoError(t, err)
  2065. _, _, err = httpd.Dumpdata("backup.json", "1", http.StatusOK)
  2066. assert.NoError(t, err)
  2067. err = os.Remove(filepath.Join(backupsPath, "backup.json"))
  2068. assert.NoError(t, err)
  2069. if runtime.GOOS != "windows" {
  2070. err = os.Chmod(backupsPath, 0001)
  2071. assert.NoError(t, err)
  2072. _, _, err = httpd.Dumpdata("bck.json", "", http.StatusInternalServerError)
  2073. assert.NoError(t, err)
  2074. // subdir cannot be created
  2075. _, _, err = httpd.Dumpdata(filepath.Join("subdir", "bck.json"), "", http.StatusInternalServerError)
  2076. assert.NoError(t, err)
  2077. err = os.Chmod(backupsPath, 0755)
  2078. assert.NoError(t, err)
  2079. }
  2080. err = dataprovider.Close()
  2081. assert.NoError(t, err)
  2082. err = config.LoadConfig(configDir, "")
  2083. assert.NoError(t, err)
  2084. providerConf = config.GetProviderConf()
  2085. providerConf.CredentialsPath = credentialsPath
  2086. err = os.RemoveAll(credentialsPath)
  2087. assert.NoError(t, err)
  2088. err = dataprovider.Initialize(providerConf, configDir)
  2089. assert.NoError(t, err)
  2090. }
  2091. func TestLoaddata(t *testing.T) {
  2092. mappedPath := filepath.Join(os.TempDir(), "restored_folder")
  2093. user := getTestUser()
  2094. user.ID = 1
  2095. user.Username = "test_user_restore"
  2096. backupData := dataprovider.BackupData{}
  2097. backupData.Users = append(backupData.Users, user)
  2098. backupData.Folders = []vfs.BaseVirtualFolder{
  2099. {
  2100. MappedPath: mappedPath,
  2101. UsedQuotaSize: 123,
  2102. UsedQuotaFiles: 456,
  2103. LastQuotaUpdate: 789,
  2104. Users: []string{"user"},
  2105. },
  2106. {
  2107. MappedPath: mappedPath,
  2108. },
  2109. }
  2110. backupContent, err := json.Marshal(backupData)
  2111. assert.NoError(t, err)
  2112. backupFilePath := filepath.Join(backupsPath, "backup.json")
  2113. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  2114. assert.NoError(t, err)
  2115. _, _, err = httpd.Loaddata(backupFilePath, "a", "", http.StatusBadRequest)
  2116. assert.NoError(t, err)
  2117. _, _, err = httpd.Loaddata(backupFilePath, "", "a", http.StatusBadRequest)
  2118. assert.NoError(t, err)
  2119. _, _, err = httpd.Loaddata("backup.json", "1", "", http.StatusBadRequest)
  2120. assert.NoError(t, err)
  2121. _, _, err = httpd.Loaddata(backupFilePath+"a", "1", "", http.StatusBadRequest)
  2122. assert.NoError(t, err)
  2123. if runtime.GOOS != "windows" {
  2124. err = os.Chmod(backupFilePath, 0111)
  2125. assert.NoError(t, err)
  2126. _, _, err = httpd.Loaddata(backupFilePath, "1", "", http.StatusInternalServerError)
  2127. assert.NoError(t, err)
  2128. err = os.Chmod(backupFilePath, 0644)
  2129. assert.NoError(t, err)
  2130. }
  2131. // add user and folder from backup
  2132. _, _, err = httpd.Loaddata(backupFilePath, "1", "", http.StatusOK)
  2133. assert.NoError(t, err)
  2134. // update user from backup
  2135. _, _, err = httpd.Loaddata(backupFilePath, "2", "", http.StatusOK)
  2136. assert.NoError(t, err)
  2137. users, _, err := httpd.GetUsers(1, 0, user.Username, http.StatusOK)
  2138. assert.NoError(t, err)
  2139. if assert.Len(t, users, 1) {
  2140. user = users[0]
  2141. _, err = httpd.RemoveUser(user, http.StatusOK)
  2142. assert.NoError(t, err)
  2143. }
  2144. folders, _, err := httpd.GetFolders(1, 0, mappedPath, http.StatusOK)
  2145. assert.NoError(t, err)
  2146. if assert.Len(t, folders, 1) {
  2147. folder := folders[0]
  2148. assert.Equal(t, mappedPath, folder.MappedPath)
  2149. assert.Equal(t, int64(123), folder.UsedQuotaSize)
  2150. assert.Equal(t, 456, folder.UsedQuotaFiles)
  2151. assert.Equal(t, int64(789), folder.LastQuotaUpdate)
  2152. assert.Len(t, folder.Users, 0)
  2153. _, err = httpd.RemoveFolder(folder, http.StatusOK)
  2154. assert.NoError(t, err)
  2155. }
  2156. err = os.Remove(backupFilePath)
  2157. assert.NoError(t, err)
  2158. err = createTestFile(backupFilePath, 10485761)
  2159. assert.NoError(t, err)
  2160. _, _, err = httpd.Loaddata(backupFilePath, "1", "0", http.StatusBadRequest)
  2161. assert.NoError(t, err)
  2162. err = os.Remove(backupFilePath)
  2163. assert.NoError(t, err)
  2164. err = createTestFile(backupFilePath, 65535)
  2165. assert.NoError(t, err)
  2166. _, _, err = httpd.Loaddata(backupFilePath, "1", "0", http.StatusBadRequest)
  2167. assert.NoError(t, err)
  2168. err = os.Remove(backupFilePath)
  2169. assert.NoError(t, err)
  2170. }
  2171. func TestLoaddataMode(t *testing.T) {
  2172. user := getTestUser()
  2173. user.ID = 1
  2174. user.Username = "test_user_restore"
  2175. backupData := dataprovider.BackupData{}
  2176. backupData.Users = append(backupData.Users, user)
  2177. backupContent, _ := json.Marshal(backupData)
  2178. backupFilePath := filepath.Join(backupsPath, "backup.json")
  2179. err := ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  2180. assert.NoError(t, err)
  2181. _, _, err = httpd.Loaddata(backupFilePath, "0", "0", http.StatusOK)
  2182. assert.NoError(t, err)
  2183. users, _, err := httpd.GetUsers(1, 0, user.Username, http.StatusOK)
  2184. assert.NoError(t, err)
  2185. assert.Equal(t, 1, len(users))
  2186. user = users[0]
  2187. oldUploadBandwidth := user.UploadBandwidth
  2188. user.UploadBandwidth = oldUploadBandwidth + 128
  2189. user, _, err = httpd.UpdateUser(user, http.StatusOK, "")
  2190. assert.NoError(t, err)
  2191. _, _, err = httpd.Loaddata(backupFilePath, "0", "1", http.StatusOK)
  2192. assert.NoError(t, err)
  2193. c := common.NewBaseConnection("connID", common.ProtocolFTP, user, nil)
  2194. fakeConn := &fakeConnection{
  2195. BaseConnection: c,
  2196. }
  2197. common.Connections.Add(fakeConn)
  2198. assert.Len(t, common.Connections.GetStats(), 1)
  2199. users, _, err = httpd.GetUsers(1, 0, user.Username, http.StatusOK)
  2200. assert.NoError(t, err)
  2201. assert.Equal(t, 1, len(users))
  2202. user = users[0]
  2203. assert.NotEqual(t, oldUploadBandwidth, user.UploadBandwidth)
  2204. _, _, err = httpd.Loaddata(backupFilePath, "0", "2", http.StatusOK)
  2205. assert.NoError(t, err)
  2206. // mode 2 will update the user and close the previous connection
  2207. assert.Len(t, common.Connections.GetStats(), 0)
  2208. users, _, err = httpd.GetUsers(1, 0, user.Username, http.StatusOK)
  2209. assert.NoError(t, err)
  2210. assert.Equal(t, 1, len(users))
  2211. user = users[0]
  2212. assert.Equal(t, oldUploadBandwidth, user.UploadBandwidth)
  2213. _, err = httpd.RemoveUser(user, http.StatusOK)
  2214. assert.NoError(t, err)
  2215. err = os.Remove(backupFilePath)
  2216. assert.NoError(t, err)
  2217. }
  2218. func TestHTTPSConnection(t *testing.T) {
  2219. client := &http.Client{
  2220. Timeout: 5 * time.Second,
  2221. }
  2222. resp, err := client.Get("https://localhost:8443" + metricsPath)
  2223. if assert.Error(t, err) {
  2224. if !strings.Contains(err.Error(), "certificate is not valid") &&
  2225. !strings.Contains(err.Error(), "certificate signed by unknown authority") {
  2226. assert.Fail(t, err.Error())
  2227. }
  2228. } else {
  2229. resp.Body.Close()
  2230. }
  2231. }
  2232. // test using mock http server
  2233. func TestBasicUserHandlingMock(t *testing.T) {
  2234. user := getTestUser()
  2235. userAsJSON := getUserAsJSON(t, user)
  2236. req, err := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2237. assert.NoError(t, err)
  2238. rr := executeRequest(req)
  2239. checkResponseCode(t, http.StatusOK, rr.Code)
  2240. err = render.DecodeJSON(rr.Body, &user)
  2241. assert.NoError(t, err)
  2242. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2243. rr = executeRequest(req)
  2244. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  2245. user.MaxSessions = 10
  2246. user.UploadBandwidth = 128
  2247. user.Permissions["/"] = []string{dataprovider.PermAny, dataprovider.PermDelete, dataprovider.PermDownload}
  2248. userAsJSON = getUserAsJSON(t, user)
  2249. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  2250. rr = executeRequest(req)
  2251. checkResponseCode(t, http.StatusOK, rr.Code)
  2252. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2253. rr = executeRequest(req)
  2254. checkResponseCode(t, http.StatusOK, rr.Code)
  2255. var updatedUser dataprovider.User
  2256. err = render.DecodeJSON(rr.Body, &updatedUser)
  2257. assert.NoError(t, err)
  2258. assert.Equal(t, user.MaxSessions, updatedUser.MaxSessions)
  2259. assert.Equal(t, user.UploadBandwidth, updatedUser.UploadBandwidth)
  2260. assert.Equal(t, 1, len(updatedUser.Permissions["/"]))
  2261. assert.True(t, utils.IsStringInSlice(dataprovider.PermAny, updatedUser.Permissions["/"]))
  2262. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2263. rr = executeRequest(req)
  2264. checkResponseCode(t, http.StatusOK, rr.Code)
  2265. }
  2266. func TestGetUserByIdInvalidParamsMock(t *testing.T) {
  2267. req, _ := http.NewRequest(http.MethodGet, userPath+"/0", nil)
  2268. rr := executeRequest(req)
  2269. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2270. req, _ = http.NewRequest(http.MethodGet, userPath+"/a", nil)
  2271. rr = executeRequest(req)
  2272. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2273. }
  2274. func TestAddUserNoUsernameMock(t *testing.T) {
  2275. user := getTestUser()
  2276. user.Username = ""
  2277. userAsJSON := getUserAsJSON(t, user)
  2278. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2279. rr := executeRequest(req)
  2280. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2281. }
  2282. func TestAddUserInvalidHomeDirMock(t *testing.T) {
  2283. user := getTestUser()
  2284. user.HomeDir = "relative_path"
  2285. userAsJSON := getUserAsJSON(t, user)
  2286. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2287. rr := executeRequest(req)
  2288. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2289. }
  2290. func TestAddUserInvalidPermsMock(t *testing.T) {
  2291. user := getTestUser()
  2292. user.Permissions["/"] = []string{}
  2293. userAsJSON := getUserAsJSON(t, user)
  2294. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2295. rr := executeRequest(req)
  2296. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2297. }
  2298. func TestAddFolderInvalidJsonMock(t *testing.T) {
  2299. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer([]byte("invalid json")))
  2300. rr := executeRequest(req)
  2301. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2302. }
  2303. func TestAddUserInvalidJsonMock(t *testing.T) {
  2304. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer([]byte("invalid json")))
  2305. rr := executeRequest(req)
  2306. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2307. }
  2308. func TestUpdateUserMock(t *testing.T) {
  2309. user := getTestUser()
  2310. userAsJSON := getUserAsJSON(t, user)
  2311. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2312. rr := executeRequest(req)
  2313. checkResponseCode(t, http.StatusOK, rr.Code)
  2314. err := render.DecodeJSON(rr.Body, &user)
  2315. assert.NoError(t, err)
  2316. // permissions should not change if empty or nil
  2317. permissions := user.Permissions
  2318. user.Permissions = make(map[string][]string)
  2319. userAsJSON = getUserAsJSON(t, user)
  2320. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  2321. rr = executeRequest(req)
  2322. checkResponseCode(t, http.StatusOK, rr.Code)
  2323. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2324. rr = executeRequest(req)
  2325. checkResponseCode(t, http.StatusOK, rr.Code)
  2326. var updatedUser dataprovider.User
  2327. err = render.DecodeJSON(rr.Body, &updatedUser)
  2328. assert.NoError(t, err)
  2329. for dir, perms := range permissions {
  2330. if actualPerms, ok := updatedUser.Permissions[dir]; ok {
  2331. for _, v := range actualPerms {
  2332. assert.True(t, utils.IsStringInSlice(v, perms))
  2333. }
  2334. } else {
  2335. assert.Fail(t, "Permissions directories mismatch")
  2336. }
  2337. }
  2338. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2339. rr = executeRequest(req)
  2340. checkResponseCode(t, http.StatusOK, rr.Code)
  2341. }
  2342. func TestUpdateUserQuotaUsageMock(t *testing.T) {
  2343. var user dataprovider.User
  2344. u := getTestUser()
  2345. usedQuotaFiles := 1
  2346. usedQuotaSize := int64(65535)
  2347. u.UsedQuotaFiles = usedQuotaFiles
  2348. u.UsedQuotaSize = usedQuotaSize
  2349. userAsJSON := getUserAsJSON(t, u)
  2350. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2351. rr := executeRequest(req)
  2352. checkResponseCode(t, http.StatusOK, rr.Code)
  2353. err := render.DecodeJSON(rr.Body, &user)
  2354. assert.NoError(t, err)
  2355. req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaPath, bytes.NewBuffer(userAsJSON))
  2356. rr = executeRequest(req)
  2357. checkResponseCode(t, http.StatusOK, rr.Code)
  2358. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2359. rr = executeRequest(req)
  2360. checkResponseCode(t, http.StatusOK, rr.Code)
  2361. err = render.DecodeJSON(rr.Body, &user)
  2362. assert.NoError(t, err)
  2363. assert.Equal(t, usedQuotaFiles, user.UsedQuotaFiles)
  2364. assert.Equal(t, usedQuotaSize, user.UsedQuotaSize)
  2365. req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaPath, bytes.NewBuffer([]byte("string")))
  2366. rr = executeRequest(req)
  2367. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2368. assert.True(t, common.QuotaScans.AddUserQuotaScan(user.Username))
  2369. req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaPath, bytes.NewBuffer(userAsJSON))
  2370. rr = executeRequest(req)
  2371. checkResponseCode(t, http.StatusConflict, rr.Code)
  2372. assert.True(t, common.QuotaScans.RemoveUserQuotaScan(user.Username))
  2373. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2374. rr = executeRequest(req)
  2375. checkResponseCode(t, http.StatusOK, rr.Code)
  2376. }
  2377. func TestUserPermissionsMock(t *testing.T) {
  2378. user := getTestUser()
  2379. user.Permissions = make(map[string][]string)
  2380. user.Permissions["/somedir"] = []string{dataprovider.PermAny}
  2381. userAsJSON := getUserAsJSON(t, user)
  2382. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2383. rr := executeRequest(req)
  2384. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2385. user.Permissions = make(map[string][]string)
  2386. user.Permissions["/"] = []string{dataprovider.PermAny}
  2387. user.Permissions[".."] = []string{dataprovider.PermAny}
  2388. userAsJSON = getUserAsJSON(t, user)
  2389. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2390. rr = executeRequest(req)
  2391. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2392. user.Permissions = make(map[string][]string)
  2393. user.Permissions["/"] = []string{dataprovider.PermAny}
  2394. userAsJSON = getUserAsJSON(t, user)
  2395. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2396. rr = executeRequest(req)
  2397. checkResponseCode(t, http.StatusOK, rr.Code)
  2398. err := render.DecodeJSON(rr.Body, &user)
  2399. assert.NoError(t, err)
  2400. user.Permissions["/somedir"] = []string{"invalid"}
  2401. userAsJSON = getUserAsJSON(t, user)
  2402. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  2403. rr = executeRequest(req)
  2404. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2405. delete(user.Permissions, "/somedir")
  2406. user.Permissions["/somedir/.."] = []string{dataprovider.PermAny}
  2407. userAsJSON = getUserAsJSON(t, user)
  2408. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  2409. rr = executeRequest(req)
  2410. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2411. delete(user.Permissions, "/somedir/..")
  2412. user.Permissions["not_abs_path"] = []string{dataprovider.PermAny}
  2413. userAsJSON = getUserAsJSON(t, user)
  2414. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  2415. rr = executeRequest(req)
  2416. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2417. delete(user.Permissions, "not_abs_path")
  2418. user.Permissions["/somedir/../otherdir/"] = []string{dataprovider.PermListItems}
  2419. userAsJSON = getUserAsJSON(t, user)
  2420. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  2421. rr = executeRequest(req)
  2422. checkResponseCode(t, http.StatusOK, rr.Code)
  2423. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2424. rr = executeRequest(req)
  2425. checkResponseCode(t, http.StatusOK, rr.Code)
  2426. var updatedUser dataprovider.User
  2427. err = render.DecodeJSON(rr.Body, &updatedUser)
  2428. assert.NoError(t, err)
  2429. if val, ok := updatedUser.Permissions["/otherdir"]; ok {
  2430. assert.True(t, utils.IsStringInSlice(dataprovider.PermListItems, val))
  2431. assert.Equal(t, 1, len(val))
  2432. } else {
  2433. assert.Fail(t, "expected dir not found in permissions")
  2434. }
  2435. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2436. rr = executeRequest(req)
  2437. checkResponseCode(t, http.StatusOK, rr.Code)
  2438. }
  2439. func TestUpdateUserInvalidJsonMock(t *testing.T) {
  2440. user := getTestUser()
  2441. userAsJSON := getUserAsJSON(t, user)
  2442. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2443. rr := executeRequest(req)
  2444. checkResponseCode(t, http.StatusOK, rr.Code)
  2445. err := render.DecodeJSON(rr.Body, &user)
  2446. assert.NoError(t, err)
  2447. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer([]byte("Invalid json")))
  2448. rr = executeRequest(req)
  2449. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2450. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2451. rr = executeRequest(req)
  2452. checkResponseCode(t, http.StatusOK, rr.Code)
  2453. }
  2454. func TestUpdateUserInvalidParamsMock(t *testing.T) {
  2455. user := getTestUser()
  2456. userAsJSON := getUserAsJSON(t, user)
  2457. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2458. rr := executeRequest(req)
  2459. checkResponseCode(t, http.StatusOK, rr.Code)
  2460. err := render.DecodeJSON(rr.Body, &user)
  2461. assert.NoError(t, err)
  2462. user.HomeDir = ""
  2463. userAsJSON = getUserAsJSON(t, user)
  2464. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
  2465. rr = executeRequest(req)
  2466. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2467. userID := user.ID
  2468. user.ID = 0
  2469. userAsJSON = getUserAsJSON(t, user)
  2470. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(userID, 10), bytes.NewBuffer(userAsJSON))
  2471. rr = executeRequest(req)
  2472. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2473. user.ID = userID
  2474. req, _ = http.NewRequest(http.MethodPut, userPath+"/0", bytes.NewBuffer(userAsJSON))
  2475. rr = executeRequest(req)
  2476. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2477. req, _ = http.NewRequest(http.MethodPut, userPath+"/a", bytes.NewBuffer(userAsJSON))
  2478. rr = executeRequest(req)
  2479. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2480. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2481. rr = executeRequest(req)
  2482. checkResponseCode(t, http.StatusOK, rr.Code)
  2483. }
  2484. func TestGetUsersMock(t *testing.T) {
  2485. user := getTestUser()
  2486. userAsJSON := getUserAsJSON(t, user)
  2487. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2488. rr := executeRequest(req)
  2489. checkResponseCode(t, http.StatusOK, rr.Code)
  2490. err := render.DecodeJSON(rr.Body, &user)
  2491. assert.NoError(t, err)
  2492. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=510&offset=0&order=ASC&username="+defaultUsername, nil)
  2493. rr = executeRequest(req)
  2494. checkResponseCode(t, http.StatusOK, rr.Code)
  2495. var users []dataprovider.User
  2496. err = render.DecodeJSON(rr.Body, &users)
  2497. assert.NoError(t, err)
  2498. assert.Equal(t, 1, len(users))
  2499. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=a&offset=0&order=ASC", nil)
  2500. rr = executeRequest(req)
  2501. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2502. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=a&order=ASC", nil)
  2503. rr = executeRequest(req)
  2504. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2505. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASCa", nil)
  2506. rr = executeRequest(req)
  2507. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2508. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2509. rr = executeRequest(req)
  2510. checkResponseCode(t, http.StatusOK, rr.Code)
  2511. }
  2512. func TestDeleteUserInvalidParamsMock(t *testing.T) {
  2513. req, _ := http.NewRequest(http.MethodDelete, userPath+"/0", nil)
  2514. rr := executeRequest(req)
  2515. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2516. req, _ = http.NewRequest(http.MethodDelete, userPath+"/a", nil)
  2517. rr = executeRequest(req)
  2518. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2519. }
  2520. func TestGetQuotaScansMock(t *testing.T) {
  2521. req, err := http.NewRequest("GET", quotaScanPath, nil)
  2522. assert.NoError(t, err)
  2523. rr := executeRequest(req)
  2524. checkResponseCode(t, http.StatusOK, rr.Code)
  2525. }
  2526. func TestStartQuotaScanMock(t *testing.T) {
  2527. user := getTestUser()
  2528. userAsJSON := getUserAsJSON(t, user)
  2529. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2530. rr := executeRequest(req)
  2531. checkResponseCode(t, http.StatusOK, rr.Code)
  2532. err := render.DecodeJSON(rr.Body, &user)
  2533. assert.NoError(t, err)
  2534. _, err = os.Stat(user.HomeDir)
  2535. if err == nil {
  2536. err = os.Remove(user.HomeDir)
  2537. assert.NoError(t, err)
  2538. }
  2539. // simulate a duplicate quota scan
  2540. userAsJSON = getUserAsJSON(t, user)
  2541. common.QuotaScans.AddUserQuotaScan(user.Username)
  2542. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  2543. rr = executeRequest(req)
  2544. checkResponseCode(t, http.StatusConflict, rr.Code)
  2545. assert.True(t, common.QuotaScans.RemoveUserQuotaScan(user.Username))
  2546. userAsJSON = getUserAsJSON(t, user)
  2547. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  2548. rr = executeRequest(req)
  2549. checkResponseCode(t, http.StatusAccepted, rr.Code)
  2550. for {
  2551. var scans []common.ActiveQuotaScan
  2552. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  2553. rr = executeRequest(req)
  2554. checkResponseCode(t, http.StatusOK, rr.Code)
  2555. err = render.DecodeJSON(rr.Body, &scans)
  2556. if !assert.NoError(t, err, "Error getting active scans") {
  2557. break
  2558. }
  2559. if len(scans) == 0 {
  2560. break
  2561. }
  2562. time.Sleep(100 * time.Millisecond)
  2563. }
  2564. _, err = os.Stat(user.HomeDir)
  2565. if err != nil && os.IsNotExist(err) {
  2566. err = os.MkdirAll(user.HomeDir, os.ModePerm)
  2567. assert.NoError(t, err)
  2568. }
  2569. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  2570. rr = executeRequest(req)
  2571. checkResponseCode(t, http.StatusAccepted, rr.Code)
  2572. for {
  2573. var scans []common.ActiveQuotaScan
  2574. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  2575. rr = executeRequest(req)
  2576. checkResponseCode(t, http.StatusOK, rr.Code)
  2577. err = render.DecodeJSON(rr.Body, &scans)
  2578. if !assert.NoError(t, err) {
  2579. assert.Fail(t, err.Error(), "Error getting active scans")
  2580. break
  2581. }
  2582. if len(scans) == 0 {
  2583. break
  2584. }
  2585. time.Sleep(100 * time.Millisecond)
  2586. }
  2587. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2588. rr = executeRequest(req)
  2589. checkResponseCode(t, http.StatusOK, rr.Code)
  2590. err = os.RemoveAll(user.GetHomeDir())
  2591. assert.NoError(t, err)
  2592. }
  2593. func TestUpdateFolderQuotaUsageMock(t *testing.T) {
  2594. mappedPath := filepath.Join(os.TempDir(), "vfolder")
  2595. f := vfs.BaseVirtualFolder{
  2596. MappedPath: mappedPath,
  2597. }
  2598. usedQuotaFiles := 1
  2599. usedQuotaSize := int64(65535)
  2600. f.UsedQuotaFiles = usedQuotaFiles
  2601. f.UsedQuotaSize = usedQuotaSize
  2602. var folder vfs.BaseVirtualFolder
  2603. folderAsJSON, err := json.Marshal(f)
  2604. assert.NoError(t, err)
  2605. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  2606. rr := executeRequest(req)
  2607. checkResponseCode(t, http.StatusOK, rr.Code)
  2608. err = render.DecodeJSON(rr.Body, &folder)
  2609. assert.NoError(t, err)
  2610. req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaPath, bytes.NewBuffer(folderAsJSON))
  2611. rr = executeRequest(req)
  2612. checkResponseCode(t, http.StatusOK, rr.Code)
  2613. var folders []vfs.BaseVirtualFolder
  2614. url, err := url.Parse(folderPath)
  2615. assert.NoError(t, err)
  2616. q := url.Query()
  2617. q.Add("folder_path", mappedPath)
  2618. url.RawQuery = q.Encode()
  2619. req, _ = http.NewRequest(http.MethodGet, url.String(), nil)
  2620. rr = executeRequest(req)
  2621. checkResponseCode(t, http.StatusOK, rr.Code)
  2622. err = render.DecodeJSON(rr.Body, &folders)
  2623. assert.NoError(t, err)
  2624. if assert.Len(t, folders, 1) {
  2625. folder = folders[0]
  2626. assert.Equal(t, usedQuotaFiles, folder.UsedQuotaFiles)
  2627. assert.Equal(t, usedQuotaSize, folder.UsedQuotaSize)
  2628. }
  2629. req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaPath, bytes.NewBuffer([]byte("string")))
  2630. rr = executeRequest(req)
  2631. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2632. assert.True(t, common.QuotaScans.AddVFolderQuotaScan(mappedPath))
  2633. req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaPath, bytes.NewBuffer(folderAsJSON))
  2634. rr = executeRequest(req)
  2635. checkResponseCode(t, http.StatusConflict, rr.Code)
  2636. assert.True(t, common.QuotaScans.RemoveVFolderQuotaScan(mappedPath))
  2637. url, err = url.Parse(folderPath)
  2638. assert.NoError(t, err)
  2639. q = url.Query()
  2640. q.Add("folder_path", mappedPath)
  2641. url.RawQuery = q.Encode()
  2642. req, _ = http.NewRequest(http.MethodDelete, url.String(), nil)
  2643. rr = executeRequest(req)
  2644. checkResponseCode(t, http.StatusOK, rr.Code)
  2645. }
  2646. func TestStartFolderQuotaScanMock(t *testing.T) {
  2647. mappedPath := filepath.Join(os.TempDir(), "vfolder")
  2648. folder := vfs.BaseVirtualFolder{
  2649. MappedPath: mappedPath,
  2650. }
  2651. folderAsJSON, err := json.Marshal(folder)
  2652. assert.NoError(t, err)
  2653. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  2654. rr := executeRequest(req)
  2655. checkResponseCode(t, http.StatusOK, rr.Code)
  2656. _, err = os.Stat(mappedPath)
  2657. if err == nil {
  2658. err = os.Remove(mappedPath)
  2659. assert.NoError(t, err)
  2660. }
  2661. // simulate a duplicate quota scan
  2662. common.QuotaScans.AddVFolderQuotaScan(mappedPath)
  2663. req, _ = http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer(folderAsJSON))
  2664. rr = executeRequest(req)
  2665. checkResponseCode(t, http.StatusConflict, rr.Code)
  2666. assert.True(t, common.QuotaScans.RemoveVFolderQuotaScan(mappedPath))
  2667. // and now a real quota scan
  2668. _, err = os.Stat(mappedPath)
  2669. if err != nil && os.IsNotExist(err) {
  2670. err = os.MkdirAll(mappedPath, os.ModePerm)
  2671. assert.NoError(t, err)
  2672. }
  2673. req, _ = http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer(folderAsJSON))
  2674. rr = executeRequest(req)
  2675. checkResponseCode(t, http.StatusAccepted, rr.Code)
  2676. var scans []common.ActiveVirtualFolderQuotaScan
  2677. for {
  2678. req, _ = http.NewRequest(http.MethodGet, quotaScanVFolderPath, nil)
  2679. rr = executeRequest(req)
  2680. checkResponseCode(t, http.StatusOK, rr.Code)
  2681. err = render.DecodeJSON(rr.Body, &scans)
  2682. if !assert.NoError(t, err, "Error getting active folders scans") {
  2683. break
  2684. }
  2685. if len(scans) == 0 {
  2686. break
  2687. }
  2688. time.Sleep(100 * time.Millisecond)
  2689. }
  2690. // cleanup
  2691. url, err := url.Parse(folderPath)
  2692. assert.NoError(t, err)
  2693. q := url.Query()
  2694. q.Add("folder_path", mappedPath)
  2695. url.RawQuery = q.Encode()
  2696. req, _ = http.NewRequest(http.MethodDelete, url.String(), nil)
  2697. rr = executeRequest(req)
  2698. checkResponseCode(t, http.StatusOK, rr.Code)
  2699. err = os.RemoveAll(folderPath)
  2700. assert.NoError(t, err)
  2701. err = os.RemoveAll(mappedPath)
  2702. assert.NoError(t, err)
  2703. }
  2704. func TestStartQuotaScanNonExistentUserMock(t *testing.T) {
  2705. user := getTestUser()
  2706. userAsJSON := getUserAsJSON(t, user)
  2707. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  2708. rr := executeRequest(req)
  2709. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2710. }
  2711. func TestStartQuotaScanBadUserMock(t *testing.T) {
  2712. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer([]byte("invalid json")))
  2713. rr := executeRequest(req)
  2714. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2715. }
  2716. func TestStartQuotaScanBadFolderMock(t *testing.T) {
  2717. req, _ := http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer([]byte("invalid json")))
  2718. rr := executeRequest(req)
  2719. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2720. }
  2721. func TestStartQuotaScanNonExistentFolderMock(t *testing.T) {
  2722. folder := vfs.BaseVirtualFolder{
  2723. MappedPath: os.TempDir(),
  2724. }
  2725. folderAsJSON, err := json.Marshal(folder)
  2726. assert.NoError(t, err)
  2727. req, _ := http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer(folderAsJSON))
  2728. rr := executeRequest(req)
  2729. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2730. }
  2731. func TestGetFoldersMock(t *testing.T) {
  2732. mappedPath := filepath.Join(os.TempDir(), "vfolder")
  2733. folder := vfs.BaseVirtualFolder{
  2734. MappedPath: mappedPath,
  2735. }
  2736. folderAsJSON, err := json.Marshal(folder)
  2737. assert.NoError(t, err)
  2738. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  2739. rr := executeRequest(req)
  2740. checkResponseCode(t, http.StatusOK, rr.Code)
  2741. err = render.DecodeJSON(rr.Body, &folder)
  2742. assert.NoError(t, err)
  2743. var folders []vfs.BaseVirtualFolder
  2744. url, err := url.Parse(folderPath + "?limit=510&offset=0&order=DESC")
  2745. assert.NoError(t, err)
  2746. q := url.Query()
  2747. q.Add("folder_path", mappedPath)
  2748. url.RawQuery = q.Encode()
  2749. req, _ = http.NewRequest(http.MethodGet, url.String(), nil)
  2750. rr = executeRequest(req)
  2751. checkResponseCode(t, http.StatusOK, rr.Code)
  2752. err = render.DecodeJSON(rr.Body, &folders)
  2753. assert.NoError(t, err)
  2754. assert.Len(t, folders, 1)
  2755. req, _ = http.NewRequest(http.MethodGet, folderPath+"?limit=a&offset=0&order=ASC", nil)
  2756. rr = executeRequest(req)
  2757. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2758. req, _ = http.NewRequest(http.MethodGet, folderPath+"?limit=1&offset=a&order=ASC", nil)
  2759. rr = executeRequest(req)
  2760. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2761. req, _ = http.NewRequest(http.MethodGet, folderPath+"?limit=1&offset=0&order=ASCa", nil)
  2762. rr = executeRequest(req)
  2763. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2764. url, err = url.Parse(folderPath)
  2765. assert.NoError(t, err)
  2766. q = url.Query()
  2767. q.Add("folder_path", mappedPath)
  2768. url.RawQuery = q.Encode()
  2769. req, _ = http.NewRequest(http.MethodDelete, url.String(), nil)
  2770. rr = executeRequest(req)
  2771. checkResponseCode(t, http.StatusOK, rr.Code)
  2772. }
  2773. func TestGetVersionMock(t *testing.T) {
  2774. req, _ := http.NewRequest(http.MethodGet, versionPath, nil)
  2775. rr := executeRequest(req)
  2776. checkResponseCode(t, http.StatusOK, rr.Code)
  2777. }
  2778. func TestGetConnectionsMock(t *testing.T) {
  2779. req, _ := http.NewRequest(http.MethodGet, activeConnectionsPath, nil)
  2780. rr := executeRequest(req)
  2781. checkResponseCode(t, http.StatusOK, rr.Code)
  2782. }
  2783. func TestGetStatusMock(t *testing.T) {
  2784. req, _ := http.NewRequest(http.MethodGet, serverStatusPath, nil)
  2785. rr := executeRequest(req)
  2786. checkResponseCode(t, http.StatusOK, rr.Code)
  2787. }
  2788. func TestDeleteActiveConnectionMock(t *testing.T) {
  2789. req, _ := http.NewRequest(http.MethodDelete, activeConnectionsPath+"/connectionID", nil)
  2790. rr := executeRequest(req)
  2791. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2792. }
  2793. func TestNotFoundMock(t *testing.T) {
  2794. req, _ := http.NewRequest(http.MethodGet, "/non/existing/path", nil)
  2795. rr := executeRequest(req)
  2796. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2797. }
  2798. func TestMethodNotAllowedMock(t *testing.T) {
  2799. req, _ := http.NewRequest(http.MethodPost, activeConnectionsPath, nil)
  2800. rr := executeRequest(req)
  2801. checkResponseCode(t, http.StatusMethodNotAllowed, rr.Code)
  2802. }
  2803. func TestMetricsMock(t *testing.T) {
  2804. req, _ := http.NewRequest(http.MethodGet, metricsPath, nil)
  2805. rr := executeRequest(req)
  2806. checkResponseCode(t, http.StatusOK, rr.Code)
  2807. }
  2808. func TestHealthCheck(t *testing.T) {
  2809. req, _ := http.NewRequest(http.MethodGet, "/healthz", nil)
  2810. rr := executeRequest(req)
  2811. checkResponseCode(t, http.StatusOK, rr.Code)
  2812. assert.Equal(t, "ok", rr.Body.String())
  2813. }
  2814. func TestPProfEndPointMock(t *testing.T) {
  2815. req, _ := http.NewRequest(http.MethodGet, pprofPath, nil)
  2816. rr := executeRequest(req)
  2817. checkResponseCode(t, http.StatusOK, rr.Code)
  2818. }
  2819. func TestGetWebRootMock(t *testing.T) {
  2820. req, _ := http.NewRequest(http.MethodGet, "/", nil)
  2821. rr := executeRequest(req)
  2822. checkResponseCode(t, http.StatusMovedPermanently, rr.Code)
  2823. req, _ = http.NewRequest(http.MethodGet, webBasePath, nil)
  2824. rr = executeRequest(req)
  2825. checkResponseCode(t, http.StatusMovedPermanently, rr.Code)
  2826. }
  2827. func TestBasicWebUsersMock(t *testing.T) {
  2828. user := getTestUser()
  2829. userAsJSON := getUserAsJSON(t, user)
  2830. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2831. rr := executeRequest(req)
  2832. checkResponseCode(t, http.StatusOK, rr.Code)
  2833. err := render.DecodeJSON(rr.Body, &user)
  2834. assert.NoError(t, err)
  2835. user1 := getTestUser()
  2836. user1.Username += "1"
  2837. user1AsJSON := getUserAsJSON(t, user1)
  2838. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(user1AsJSON))
  2839. rr = executeRequest(req)
  2840. checkResponseCode(t, http.StatusOK, rr.Code)
  2841. err = render.DecodeJSON(rr.Body, &user1)
  2842. assert.NoError(t, err)
  2843. req, _ = http.NewRequest(http.MethodGet, webUsersPath, nil)
  2844. rr = executeRequest(req)
  2845. checkResponseCode(t, http.StatusOK, rr.Code)
  2846. req, _ = http.NewRequest(http.MethodGet, webUsersPath+"?qlimit=a", nil)
  2847. rr = executeRequest(req)
  2848. checkResponseCode(t, http.StatusOK, rr.Code)
  2849. req, _ = http.NewRequest(http.MethodGet, webUsersPath+"?qlimit=1", nil)
  2850. rr = executeRequest(req)
  2851. checkResponseCode(t, http.StatusOK, rr.Code)
  2852. req, _ = http.NewRequest(http.MethodGet, webUserPath, nil)
  2853. rr = executeRequest(req)
  2854. checkResponseCode(t, http.StatusOK, rr.Code)
  2855. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2856. rr = executeRequest(req)
  2857. checkResponseCode(t, http.StatusOK, rr.Code)
  2858. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/0", nil)
  2859. rr = executeRequest(req)
  2860. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2861. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/a", nil)
  2862. rr = executeRequest(req)
  2863. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2864. form := make(url.Values)
  2865. form.Set("username", user.Username)
  2866. b, contentType, _ := getMultipartFormData(form, "", "")
  2867. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2868. req.Header.Set("Content-Type", contentType)
  2869. rr = executeRequest(req)
  2870. checkResponseCode(t, http.StatusOK, rr.Code)
  2871. b, contentType, _ = getMultipartFormData(form, "", "")
  2872. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  2873. req.Header.Set("Content-Type", contentType)
  2874. rr = executeRequest(req)
  2875. checkResponseCode(t, http.StatusOK, rr.Code)
  2876. b, contentType, _ = getMultipartFormData(form, "", "")
  2877. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/0", &b)
  2878. req.Header.Set("Content-Type", contentType)
  2879. rr = executeRequest(req)
  2880. checkResponseCode(t, http.StatusNotFound, rr.Code)
  2881. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/a", &b)
  2882. req.Header.Set("Content-Type", contentType)
  2883. rr = executeRequest(req)
  2884. checkResponseCode(t, http.StatusBadRequest, rr.Code)
  2885. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  2886. rr = executeRequest(req)
  2887. checkResponseCode(t, http.StatusOK, rr.Code)
  2888. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user1.ID, 10), nil)
  2889. rr = executeRequest(req)
  2890. checkResponseCode(t, http.StatusOK, rr.Code)
  2891. }
  2892. func TestWebUserAddMock(t *testing.T) {
  2893. user := getTestUser()
  2894. user.UploadBandwidth = 32
  2895. user.DownloadBandwidth = 64
  2896. user.UID = 1000
  2897. user.AdditionalInfo = "info"
  2898. mappedDir := filepath.Join(os.TempDir(), "mapped")
  2899. form := make(url.Values)
  2900. form.Set("username", user.Username)
  2901. form.Set("home_dir", user.HomeDir)
  2902. form.Set("password", user.Password)
  2903. form.Set("status", strconv.Itoa(user.Status))
  2904. form.Set("expiration_date", "")
  2905. form.Set("permissions", "*")
  2906. form.Set("sub_dirs_permissions", " /subdir::list ,download ")
  2907. form.Set("virtual_folders", fmt.Sprintf(" /vdir:: %v :: 2 :: 1024", mappedDir))
  2908. form.Set("allowed_extensions", "/dir2::.jpg,.png\n/dir2::.ico\n/dir1::.rar")
  2909. form.Set("denied_extensions", "/dir2::.webp,.webp\n/dir2::.tiff\n/dir1::.zip")
  2910. form.Set("allowed_patterns", "/dir2::*.jpg,*.png\n/dir1::*.png")
  2911. form.Set("denied_patterns", "/dir1::*.zip\n/dir3::*.rar\n/dir2::*.mkv")
  2912. form.Set("additional_info", user.AdditionalInfo)
  2913. b, contentType, _ := getMultipartFormData(form, "", "")
  2914. // test invalid url escape
  2915. req, _ := http.NewRequest(http.MethodPost, webUserPath+"?a=%2", &b)
  2916. req.Header.Set("Content-Type", contentType)
  2917. rr := executeRequest(req)
  2918. checkResponseCode(t, http.StatusOK, rr.Code)
  2919. form.Set("public_keys", testPubKey)
  2920. form.Set("uid", strconv.FormatInt(int64(user.UID), 10))
  2921. form.Set("gid", "a")
  2922. b, contentType, _ = getMultipartFormData(form, "", "")
  2923. // test invalid gid
  2924. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2925. req.Header.Set("Content-Type", contentType)
  2926. rr = executeRequest(req)
  2927. checkResponseCode(t, http.StatusOK, rr.Code)
  2928. form.Set("gid", "0")
  2929. form.Set("max_sessions", "a")
  2930. b, contentType, _ = getMultipartFormData(form, "", "")
  2931. // test invalid max sessions
  2932. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2933. req.Header.Set("Content-Type", contentType)
  2934. rr = executeRequest(req)
  2935. checkResponseCode(t, http.StatusOK, rr.Code)
  2936. form.Set("max_sessions", "0")
  2937. form.Set("quota_size", "a")
  2938. b, contentType, _ = getMultipartFormData(form, "", "")
  2939. // test invalid quota size
  2940. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2941. req.Header.Set("Content-Type", contentType)
  2942. rr = executeRequest(req)
  2943. checkResponseCode(t, http.StatusOK, rr.Code)
  2944. form.Set("quota_size", "0")
  2945. form.Set("quota_files", "a")
  2946. b, contentType, _ = getMultipartFormData(form, "", "")
  2947. // test invalid quota files
  2948. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2949. req.Header.Set("Content-Type", contentType)
  2950. rr = executeRequest(req)
  2951. checkResponseCode(t, http.StatusOK, rr.Code)
  2952. form.Set("quota_files", "0")
  2953. form.Set("upload_bandwidth", "a")
  2954. b, contentType, _ = getMultipartFormData(form, "", "")
  2955. // test invalid upload bandwidth
  2956. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2957. req.Header.Set("Content-Type", contentType)
  2958. rr = executeRequest(req)
  2959. checkResponseCode(t, http.StatusOK, rr.Code)
  2960. form.Set("upload_bandwidth", strconv.FormatInt(user.UploadBandwidth, 10))
  2961. form.Set("download_bandwidth", "a")
  2962. b, contentType, _ = getMultipartFormData(form, "", "")
  2963. // test invalid download bandwidth
  2964. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2965. req.Header.Set("Content-Type", contentType)
  2966. rr = executeRequest(req)
  2967. checkResponseCode(t, http.StatusOK, rr.Code)
  2968. form.Set("download_bandwidth", strconv.FormatInt(user.DownloadBandwidth, 10))
  2969. form.Set("status", "a")
  2970. b, contentType, _ = getMultipartFormData(form, "", "")
  2971. // test invalid status
  2972. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2973. req.Header.Set("Content-Type", contentType)
  2974. rr = executeRequest(req)
  2975. checkResponseCode(t, http.StatusOK, rr.Code)
  2976. form.Set("status", strconv.Itoa(user.Status))
  2977. form.Set("expiration_date", "123")
  2978. b, contentType, _ = getMultipartFormData(form, "", "")
  2979. // test invalid expiration date
  2980. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2981. req.Header.Set("Content-Type", contentType)
  2982. rr = executeRequest(req)
  2983. checkResponseCode(t, http.StatusOK, rr.Code)
  2984. form.Set("expiration_date", "")
  2985. form.Set("allowed_ip", "invalid,ip")
  2986. b, contentType, _ = getMultipartFormData(form, "", "")
  2987. // test invalid allowed_ip
  2988. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2989. req.Header.Set("Content-Type", contentType)
  2990. rr = executeRequest(req)
  2991. checkResponseCode(t, http.StatusOK, rr.Code)
  2992. form.Set("allowed_ip", "")
  2993. form.Set("denied_ip", "192.168.1.2") // it should be 192.168.1.2/32
  2994. b, contentType, _ = getMultipartFormData(form, "", "")
  2995. // test invalid denied_ip
  2996. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  2997. req.Header.Set("Content-Type", contentType)
  2998. rr = executeRequest(req)
  2999. checkResponseCode(t, http.StatusOK, rr.Code)
  3000. form.Set("denied_ip", "")
  3001. // test invalid max file upload size
  3002. form.Set("max_upload_file_size", "a")
  3003. b, contentType, _ = getMultipartFormData(form, "", "")
  3004. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  3005. req.Header.Set("Content-Type", contentType)
  3006. rr = executeRequest(req)
  3007. checkResponseCode(t, http.StatusOK, rr.Code)
  3008. form.Set("max_upload_file_size", "1000")
  3009. b, contentType, _ = getMultipartFormData(form, "", "")
  3010. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  3011. req.Header.Set("Content-Type", contentType)
  3012. rr = executeRequest(req)
  3013. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3014. // the user already exists, was created with the above request
  3015. b, contentType, _ = getMultipartFormData(form, "", "")
  3016. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  3017. req.Header.Set("Content-Type", contentType)
  3018. rr = executeRequest(req)
  3019. checkResponseCode(t, http.StatusOK, rr.Code)
  3020. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3021. rr = executeRequest(req)
  3022. checkResponseCode(t, http.StatusOK, rr.Code)
  3023. var users []dataprovider.User
  3024. err := render.DecodeJSON(rr.Body, &users)
  3025. assert.NoError(t, err)
  3026. assert.Equal(t, 1, len(users))
  3027. newUser := users[0]
  3028. assert.Equal(t, user.UID, newUser.UID)
  3029. assert.Equal(t, user.UploadBandwidth, newUser.UploadBandwidth)
  3030. assert.Equal(t, user.DownloadBandwidth, newUser.DownloadBandwidth)
  3031. assert.Equal(t, int64(1000), newUser.Filters.MaxUploadFileSize)
  3032. assert.Equal(t, user.AdditionalInfo, newUser.AdditionalInfo)
  3033. assert.True(t, utils.IsStringInSlice(testPubKey, newUser.PublicKeys))
  3034. if val, ok := newUser.Permissions["/subdir"]; ok {
  3035. assert.True(t, utils.IsStringInSlice(dataprovider.PermListItems, val))
  3036. assert.True(t, utils.IsStringInSlice(dataprovider.PermDownload, val))
  3037. } else {
  3038. assert.Fail(t, "user permissions must contain /somedir", "actual: %v", newUser.Permissions)
  3039. }
  3040. assert.Len(t, newUser.VirtualFolders, 1)
  3041. for _, v := range newUser.VirtualFolders {
  3042. assert.Equal(t, v.VirtualPath, "/vdir")
  3043. assert.Equal(t, v.MappedPath, mappedDir)
  3044. assert.Equal(t, v.QuotaFiles, 2)
  3045. assert.Equal(t, v.QuotaSize, int64(1024))
  3046. }
  3047. assert.Len(t, newUser.Filters.FileExtensions, 2)
  3048. for _, filter := range newUser.Filters.FileExtensions {
  3049. if filter.Path == "/dir1" {
  3050. assert.Len(t, filter.DeniedExtensions, 1)
  3051. assert.Len(t, filter.AllowedExtensions, 1)
  3052. assert.True(t, utils.IsStringInSlice(".zip", filter.DeniedExtensions))
  3053. assert.True(t, utils.IsStringInSlice(".rar", filter.AllowedExtensions))
  3054. }
  3055. if filter.Path == "/dir2" {
  3056. assert.Len(t, filter.DeniedExtensions, 2)
  3057. assert.Len(t, filter.AllowedExtensions, 3)
  3058. assert.True(t, utils.IsStringInSlice(".jpg", filter.AllowedExtensions))
  3059. assert.True(t, utils.IsStringInSlice(".png", filter.AllowedExtensions))
  3060. assert.True(t, utils.IsStringInSlice(".ico", filter.AllowedExtensions))
  3061. assert.True(t, utils.IsStringInSlice(".webp", filter.DeniedExtensions))
  3062. assert.True(t, utils.IsStringInSlice(".tiff", filter.DeniedExtensions))
  3063. }
  3064. }
  3065. assert.Len(t, newUser.Filters.FilePatterns, 3)
  3066. for _, filter := range newUser.Filters.FilePatterns {
  3067. if filter.Path == "/dir1" {
  3068. assert.Len(t, filter.DeniedPatterns, 1)
  3069. assert.Len(t, filter.AllowedPatterns, 1)
  3070. assert.True(t, utils.IsStringInSlice("*.png", filter.AllowedPatterns))
  3071. assert.True(t, utils.IsStringInSlice("*.zip", filter.DeniedPatterns))
  3072. }
  3073. if filter.Path == "/dir2" {
  3074. assert.Len(t, filter.DeniedPatterns, 1)
  3075. assert.Len(t, filter.AllowedPatterns, 2)
  3076. assert.True(t, utils.IsStringInSlice("*.jpg", filter.AllowedPatterns))
  3077. assert.True(t, utils.IsStringInSlice("*.png", filter.AllowedPatterns))
  3078. assert.True(t, utils.IsStringInSlice("*.mkv", filter.DeniedPatterns))
  3079. }
  3080. if filter.Path == "/dir3" {
  3081. assert.Len(t, filter.DeniedPatterns, 1)
  3082. assert.Len(t, filter.AllowedPatterns, 0)
  3083. assert.True(t, utils.IsStringInSlice("*.rar", filter.DeniedPatterns))
  3084. }
  3085. }
  3086. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(newUser.ID, 10), nil)
  3087. rr = executeRequest(req)
  3088. checkResponseCode(t, http.StatusOK, rr.Code)
  3089. url, err := url.Parse(folderPath)
  3090. assert.NoError(t, err)
  3091. q := url.Query()
  3092. q.Add("folder_path", mappedDir)
  3093. url.RawQuery = q.Encode()
  3094. req, _ = http.NewRequest(http.MethodDelete, url.String(), nil)
  3095. rr = executeRequest(req)
  3096. checkResponseCode(t, http.StatusOK, rr.Code)
  3097. }
  3098. func TestWebUserUpdateMock(t *testing.T) {
  3099. user := getTestUser()
  3100. userAsJSON := getUserAsJSON(t, user)
  3101. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3102. rr := executeRequest(req)
  3103. checkResponseCode(t, http.StatusOK, rr.Code)
  3104. err := render.DecodeJSON(rr.Body, &user)
  3105. assert.NoError(t, err)
  3106. user.MaxSessions = 1
  3107. user.QuotaFiles = 2
  3108. user.QuotaSize = 3
  3109. user.GID = 1000
  3110. user.AdditionalInfo = "new additional info"
  3111. form := make(url.Values)
  3112. form.Set("username", user.Username)
  3113. form.Set("home_dir", user.HomeDir)
  3114. form.Set("uid", "0")
  3115. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  3116. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  3117. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  3118. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  3119. form.Set("upload_bandwidth", "0")
  3120. form.Set("download_bandwidth", "0")
  3121. form.Set("permissions", "*")
  3122. form.Set("sub_dirs_permissions", "/otherdir :: list ,upload ")
  3123. form.Set("status", strconv.Itoa(user.Status))
  3124. form.Set("expiration_date", "2020-01-01 00:00:00")
  3125. form.Set("allowed_ip", " 192.168.1.3/32, 192.168.2.0/24 ")
  3126. form.Set("denied_ip", " 10.0.0.2/32 ")
  3127. form.Set("denied_extensions", "/dir1::.zip")
  3128. form.Set("ssh_login_methods", dataprovider.SSHLoginMethodKeyboardInteractive)
  3129. form.Set("denied_protocols", common.ProtocolFTP)
  3130. form.Set("max_upload_file_size", "100")
  3131. form.Set("disconnect", "1")
  3132. form.Set("additional_info", user.AdditionalInfo)
  3133. b, contentType, _ := getMultipartFormData(form, "", "")
  3134. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3135. req.Header.Set("Content-Type", contentType)
  3136. rr = executeRequest(req)
  3137. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3138. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3139. rr = executeRequest(req)
  3140. checkResponseCode(t, http.StatusOK, rr.Code)
  3141. var users []dataprovider.User
  3142. err = render.DecodeJSON(rr.Body, &users)
  3143. assert.NoError(t, err)
  3144. assert.Equal(t, 1, len(users))
  3145. updateUser := users[0]
  3146. assert.Equal(t, user.HomeDir, updateUser.HomeDir)
  3147. assert.Equal(t, user.MaxSessions, updateUser.MaxSessions)
  3148. assert.Equal(t, user.QuotaFiles, updateUser.QuotaFiles)
  3149. assert.Equal(t, user.QuotaSize, updateUser.QuotaSize)
  3150. assert.Equal(t, user.UID, updateUser.UID)
  3151. assert.Equal(t, user.GID, updateUser.GID)
  3152. assert.Equal(t, user.AdditionalInfo, updateUser.AdditionalInfo)
  3153. assert.Equal(t, int64(100), updateUser.Filters.MaxUploadFileSize)
  3154. if val, ok := updateUser.Permissions["/otherdir"]; ok {
  3155. assert.True(t, utils.IsStringInSlice(dataprovider.PermListItems, val))
  3156. assert.True(t, utils.IsStringInSlice(dataprovider.PermUpload, val))
  3157. } else {
  3158. assert.Fail(t, "user permissions must contains /otherdir", "actual: %v", updateUser.Permissions)
  3159. }
  3160. assert.True(t, utils.IsStringInSlice("192.168.1.3/32", updateUser.Filters.AllowedIP))
  3161. assert.True(t, utils.IsStringInSlice("10.0.0.2/32", updateUser.Filters.DeniedIP))
  3162. assert.True(t, utils.IsStringInSlice(dataprovider.SSHLoginMethodKeyboardInteractive, updateUser.Filters.DeniedLoginMethods))
  3163. assert.True(t, utils.IsStringInSlice(common.ProtocolFTP, updateUser.Filters.DeniedProtocols))
  3164. assert.True(t, utils.IsStringInSlice(".zip", updateUser.Filters.FileExtensions[0].DeniedExtensions))
  3165. req, err = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  3166. assert.NoError(t, err)
  3167. rr = executeRequest(req)
  3168. checkResponseCode(t, http.StatusOK, rr.Code)
  3169. }
  3170. func TestWebUserS3Mock(t *testing.T) {
  3171. user := getTestUser()
  3172. userAsJSON := getUserAsJSON(t, user)
  3173. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3174. rr := executeRequest(req)
  3175. checkResponseCode(t, http.StatusOK, rr.Code)
  3176. err := render.DecodeJSON(rr.Body, &user)
  3177. assert.NoError(t, err)
  3178. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  3179. user.FsConfig.S3Config.Bucket = "test"
  3180. user.FsConfig.S3Config.Region = "eu-west-1"
  3181. user.FsConfig.S3Config.AccessKey = "access-key"
  3182. user.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("access-secret")
  3183. user.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/path?a=b"
  3184. user.FsConfig.S3Config.StorageClass = "Standard"
  3185. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir/"
  3186. user.FsConfig.S3Config.UploadPartSize = 5
  3187. user.FsConfig.S3Config.UploadConcurrency = 4
  3188. form := make(url.Values)
  3189. form.Set("username", user.Username)
  3190. form.Set("home_dir", user.HomeDir)
  3191. form.Set("uid", "0")
  3192. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  3193. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  3194. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  3195. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  3196. form.Set("upload_bandwidth", "0")
  3197. form.Set("download_bandwidth", "0")
  3198. form.Set("permissions", "*")
  3199. form.Set("sub_dirs_permissions", "")
  3200. form.Set("status", strconv.Itoa(user.Status))
  3201. form.Set("expiration_date", "2020-01-01 00:00:00")
  3202. form.Set("allowed_ip", "")
  3203. form.Set("denied_ip", "")
  3204. form.Set("fs_provider", "1")
  3205. form.Set("s3_bucket", user.FsConfig.S3Config.Bucket)
  3206. form.Set("s3_region", user.FsConfig.S3Config.Region)
  3207. form.Set("s3_access_key", user.FsConfig.S3Config.AccessKey)
  3208. form.Set("s3_access_secret", user.FsConfig.S3Config.AccessSecret.GetPayload())
  3209. form.Set("s3_storage_class", user.FsConfig.S3Config.StorageClass)
  3210. form.Set("s3_endpoint", user.FsConfig.S3Config.Endpoint)
  3211. form.Set("s3_key_prefix", user.FsConfig.S3Config.KeyPrefix)
  3212. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  3213. form.Set("denied_extensions", "/dir2::.zip")
  3214. form.Set("max_upload_file_size", "0")
  3215. // test invalid s3_upload_part_size
  3216. form.Set("s3_upload_part_size", "a")
  3217. b, contentType, _ := getMultipartFormData(form, "", "")
  3218. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3219. req.Header.Set("Content-Type", contentType)
  3220. rr = executeRequest(req)
  3221. checkResponseCode(t, http.StatusOK, rr.Code)
  3222. // test invalid s3_concurrency
  3223. form.Set("s3_upload_part_size", strconv.FormatInt(user.FsConfig.S3Config.UploadPartSize, 10))
  3224. form.Set("s3_upload_concurrency", "a")
  3225. b, contentType, _ = getMultipartFormData(form, "", "")
  3226. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3227. req.Header.Set("Content-Type", contentType)
  3228. rr = executeRequest(req)
  3229. checkResponseCode(t, http.StatusOK, rr.Code)
  3230. // now add the user
  3231. form.Set("s3_upload_concurrency", strconv.Itoa(user.FsConfig.S3Config.UploadConcurrency))
  3232. b, contentType, _ = getMultipartFormData(form, "", "")
  3233. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3234. req.Header.Set("Content-Type", contentType)
  3235. rr = executeRequest(req)
  3236. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3237. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3238. rr = executeRequest(req)
  3239. checkResponseCode(t, http.StatusOK, rr.Code)
  3240. var users []dataprovider.User
  3241. err = render.DecodeJSON(rr.Body, &users)
  3242. assert.NoError(t, err)
  3243. assert.Equal(t, 1, len(users))
  3244. updateUser := users[0]
  3245. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  3246. assert.Equal(t, updateUser.FsConfig.S3Config.Bucket, user.FsConfig.S3Config.Bucket)
  3247. assert.Equal(t, updateUser.FsConfig.S3Config.Region, user.FsConfig.S3Config.Region)
  3248. assert.Equal(t, updateUser.FsConfig.S3Config.AccessKey, user.FsConfig.S3Config.AccessKey)
  3249. assert.Equal(t, updateUser.FsConfig.S3Config.StorageClass, user.FsConfig.S3Config.StorageClass)
  3250. assert.Equal(t, updateUser.FsConfig.S3Config.Endpoint, user.FsConfig.S3Config.Endpoint)
  3251. assert.Equal(t, updateUser.FsConfig.S3Config.KeyPrefix, user.FsConfig.S3Config.KeyPrefix)
  3252. assert.Equal(t, updateUser.FsConfig.S3Config.UploadPartSize, user.FsConfig.S3Config.UploadPartSize)
  3253. assert.Equal(t, updateUser.FsConfig.S3Config.UploadConcurrency, user.FsConfig.S3Config.UploadConcurrency)
  3254. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  3255. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.S3Config.AccessSecret.GetStatus())
  3256. assert.NotEmpty(t, updateUser.FsConfig.S3Config.AccessSecret.GetPayload())
  3257. assert.Empty(t, updateUser.FsConfig.S3Config.AccessSecret.GetKey())
  3258. assert.Empty(t, updateUser.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  3259. // now check that a redacted password is not saved
  3260. form.Set("s3_access_secret", "[**redacted**] ")
  3261. b, contentType, _ = getMultipartFormData(form, "", "")
  3262. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3263. req.Header.Set("Content-Type", contentType)
  3264. rr = executeRequest(req)
  3265. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3266. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3267. rr = executeRequest(req)
  3268. checkResponseCode(t, http.StatusOK, rr.Code)
  3269. users = nil
  3270. err = render.DecodeJSON(rr.Body, &users)
  3271. assert.NoError(t, err)
  3272. assert.Equal(t, 1, len(users))
  3273. lastUpdatedUser := users[0]
  3274. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetStatus())
  3275. assert.Equal(t, updateUser.FsConfig.S3Config.AccessSecret.GetPayload(), lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetPayload())
  3276. assert.Empty(t, lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetKey())
  3277. assert.Empty(t, lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  3278. // now clear credentials
  3279. form.Set("s3_access_key", "")
  3280. form.Set("s3_access_secret", "")
  3281. b, contentType, _ = getMultipartFormData(form, "", "")
  3282. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3283. req.Header.Set("Content-Type", contentType)
  3284. rr = executeRequest(req)
  3285. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3286. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3287. rr = executeRequest(req)
  3288. checkResponseCode(t, http.StatusOK, rr.Code)
  3289. users = nil
  3290. err = render.DecodeJSON(rr.Body, &users)
  3291. assert.NoError(t, err)
  3292. assert.Equal(t, 1, len(users))
  3293. assert.True(t, users[0].FsConfig.S3Config.AccessSecret.IsEmpty())
  3294. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  3295. rr = executeRequest(req)
  3296. checkResponseCode(t, http.StatusOK, rr.Code)
  3297. }
  3298. func TestWebUserGCSMock(t *testing.T) {
  3299. user := getTestUser()
  3300. userAsJSON := getUserAsJSON(t, user)
  3301. req, err := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3302. assert.NoError(t, err)
  3303. rr := executeRequest(req)
  3304. checkResponseCode(t, http.StatusOK, rr.Code)
  3305. err = render.DecodeJSON(rr.Body, &user)
  3306. assert.NoError(t, err)
  3307. credentialsFilePath := filepath.Join(os.TempDir(), "gcs.json")
  3308. err = createTestFile(credentialsFilePath, 0)
  3309. assert.NoError(t, err)
  3310. user.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  3311. user.FsConfig.GCSConfig.Bucket = "test"
  3312. user.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir/"
  3313. user.FsConfig.GCSConfig.StorageClass = "standard"
  3314. form := make(url.Values)
  3315. form.Set("username", user.Username)
  3316. form.Set("home_dir", user.HomeDir)
  3317. form.Set("uid", "0")
  3318. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  3319. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  3320. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  3321. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  3322. form.Set("upload_bandwidth", "0")
  3323. form.Set("download_bandwidth", "0")
  3324. form.Set("permissions", "*")
  3325. form.Set("sub_dirs_permissions", "")
  3326. form.Set("status", strconv.Itoa(user.Status))
  3327. form.Set("expiration_date", "2020-01-01 00:00:00")
  3328. form.Set("allowed_ip", "")
  3329. form.Set("denied_ip", "")
  3330. form.Set("fs_provider", "2")
  3331. form.Set("gcs_bucket", user.FsConfig.GCSConfig.Bucket)
  3332. form.Set("gcs_storage_class", user.FsConfig.GCSConfig.StorageClass)
  3333. form.Set("gcs_key_prefix", user.FsConfig.GCSConfig.KeyPrefix)
  3334. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  3335. form.Set("max_upload_file_size", "0")
  3336. b, contentType, _ := getMultipartFormData(form, "", "")
  3337. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3338. req.Header.Set("Content-Type", contentType)
  3339. rr = executeRequest(req)
  3340. checkResponseCode(t, http.StatusOK, rr.Code)
  3341. b, contentType, _ = getMultipartFormData(form, "gcs_credential_file", credentialsFilePath)
  3342. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3343. req.Header.Set("Content-Type", contentType)
  3344. rr = executeRequest(req)
  3345. checkResponseCode(t, http.StatusOK, rr.Code)
  3346. err = createTestFile(credentialsFilePath, 4096)
  3347. assert.NoError(t, err)
  3348. b, contentType, _ = getMultipartFormData(form, "gcs_credential_file", credentialsFilePath)
  3349. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3350. req.Header.Set("Content-Type", contentType)
  3351. rr = executeRequest(req)
  3352. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3353. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3354. rr = executeRequest(req)
  3355. checkResponseCode(t, http.StatusOK, rr.Code)
  3356. var users []dataprovider.User
  3357. err = render.DecodeJSON(rr.Body, &users)
  3358. assert.NoError(t, err)
  3359. assert.Equal(t, 1, len(users))
  3360. updateUser := users[0]
  3361. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  3362. assert.Equal(t, user.FsConfig.Provider, updateUser.FsConfig.Provider)
  3363. assert.Equal(t, user.FsConfig.GCSConfig.Bucket, updateUser.FsConfig.GCSConfig.Bucket)
  3364. assert.Equal(t, user.FsConfig.GCSConfig.StorageClass, updateUser.FsConfig.GCSConfig.StorageClass)
  3365. assert.Equal(t, user.FsConfig.GCSConfig.KeyPrefix, updateUser.FsConfig.GCSConfig.KeyPrefix)
  3366. assert.Equal(t, "/dir1", updateUser.Filters.FileExtensions[0].Path)
  3367. form.Set("gcs_auto_credentials", "on")
  3368. b, contentType, _ = getMultipartFormData(form, "", "")
  3369. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3370. req.Header.Set("Content-Type", contentType)
  3371. rr = executeRequest(req)
  3372. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3373. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3374. rr = executeRequest(req)
  3375. checkResponseCode(t, http.StatusOK, rr.Code)
  3376. err = render.DecodeJSON(rr.Body, &users)
  3377. assert.NoError(t, err)
  3378. assert.Equal(t, 1, len(users))
  3379. updateUser = users[0]
  3380. assert.Equal(t, 1, updateUser.FsConfig.GCSConfig.AutomaticCredentials)
  3381. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  3382. rr = executeRequest(req)
  3383. checkResponseCode(t, http.StatusOK, rr.Code)
  3384. err = os.Remove(credentialsFilePath)
  3385. assert.NoError(t, err)
  3386. }
  3387. func TestWebUserAzureBlobMock(t *testing.T) {
  3388. user := getTestUser()
  3389. userAsJSON := getUserAsJSON(t, user)
  3390. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3391. rr := executeRequest(req)
  3392. checkResponseCode(t, http.StatusOK, rr.Code)
  3393. err := render.DecodeJSON(rr.Body, &user)
  3394. assert.NoError(t, err)
  3395. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  3396. user.FsConfig.AzBlobConfig.Container = "container"
  3397. user.FsConfig.AzBlobConfig.AccountName = "aname"
  3398. user.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("access-skey")
  3399. user.FsConfig.AzBlobConfig.Endpoint = "http://127.0.0.1:9000/path?b=c"
  3400. user.FsConfig.AzBlobConfig.KeyPrefix = "somedir/subdir/"
  3401. user.FsConfig.AzBlobConfig.UploadPartSize = 5
  3402. user.FsConfig.AzBlobConfig.UploadConcurrency = 4
  3403. user.FsConfig.AzBlobConfig.UseEmulator = true
  3404. form := make(url.Values)
  3405. form.Set("username", user.Username)
  3406. form.Set("home_dir", user.HomeDir)
  3407. form.Set("uid", "0")
  3408. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  3409. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  3410. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  3411. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  3412. form.Set("upload_bandwidth", "0")
  3413. form.Set("download_bandwidth", "0")
  3414. form.Set("permissions", "*")
  3415. form.Set("sub_dirs_permissions", "")
  3416. form.Set("status", strconv.Itoa(user.Status))
  3417. form.Set("expiration_date", "2020-01-01 00:00:00")
  3418. form.Set("allowed_ip", "")
  3419. form.Set("denied_ip", "")
  3420. form.Set("fs_provider", "3")
  3421. form.Set("az_container", user.FsConfig.AzBlobConfig.Container)
  3422. form.Set("az_account_name", user.FsConfig.AzBlobConfig.AccountName)
  3423. form.Set("az_account_key", user.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  3424. form.Set("az_sas_url", user.FsConfig.AzBlobConfig.SASURL)
  3425. form.Set("az_endpoint", user.FsConfig.AzBlobConfig.Endpoint)
  3426. form.Set("az_key_prefix", user.FsConfig.AzBlobConfig.KeyPrefix)
  3427. form.Set("az_use_emulator", "checked")
  3428. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  3429. form.Set("denied_extensions", "/dir2::.zip")
  3430. form.Set("max_upload_file_size", "0")
  3431. // test invalid az_upload_part_size
  3432. form.Set("az_upload_part_size", "a")
  3433. b, contentType, _ := getMultipartFormData(form, "", "")
  3434. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3435. req.Header.Set("Content-Type", contentType)
  3436. rr = executeRequest(req)
  3437. checkResponseCode(t, http.StatusOK, rr.Code)
  3438. // test invalid az_upload_concurrency
  3439. form.Set("az_upload_part_size", strconv.FormatInt(user.FsConfig.AzBlobConfig.UploadPartSize, 10))
  3440. form.Set("az_upload_concurrency", "a")
  3441. b, contentType, _ = getMultipartFormData(form, "", "")
  3442. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3443. req.Header.Set("Content-Type", contentType)
  3444. rr = executeRequest(req)
  3445. checkResponseCode(t, http.StatusOK, rr.Code)
  3446. // now add the user
  3447. form.Set("az_upload_concurrency", strconv.Itoa(user.FsConfig.AzBlobConfig.UploadConcurrency))
  3448. b, contentType, _ = getMultipartFormData(form, "", "")
  3449. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3450. req.Header.Set("Content-Type", contentType)
  3451. rr = executeRequest(req)
  3452. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3453. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3454. rr = executeRequest(req)
  3455. checkResponseCode(t, http.StatusOK, rr.Code)
  3456. var users []dataprovider.User
  3457. err = render.DecodeJSON(rr.Body, &users)
  3458. assert.NoError(t, err)
  3459. assert.Equal(t, 1, len(users))
  3460. updateUser := users[0]
  3461. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  3462. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.Container, user.FsConfig.AzBlobConfig.Container)
  3463. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.AccountName, user.FsConfig.AzBlobConfig.AccountName)
  3464. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.Endpoint, user.FsConfig.AzBlobConfig.Endpoint)
  3465. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.SASURL, user.FsConfig.AzBlobConfig.SASURL)
  3466. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.KeyPrefix, user.FsConfig.AzBlobConfig.KeyPrefix)
  3467. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.UploadPartSize, user.FsConfig.AzBlobConfig.UploadPartSize)
  3468. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.UploadConcurrency, user.FsConfig.AzBlobConfig.UploadConcurrency)
  3469. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  3470. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  3471. assert.NotEmpty(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  3472. assert.Empty(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetKey())
  3473. assert.Empty(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  3474. // now check that a redacted password is not saved
  3475. form.Set("az_account_key", "[**redacted**] ")
  3476. b, contentType, _ = getMultipartFormData(form, "", "")
  3477. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3478. req.Header.Set("Content-Type", contentType)
  3479. rr = executeRequest(req)
  3480. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3481. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3482. rr = executeRequest(req)
  3483. checkResponseCode(t, http.StatusOK, rr.Code)
  3484. users = nil
  3485. err = render.DecodeJSON(rr.Body, &users)
  3486. assert.NoError(t, err)
  3487. assert.Equal(t, 1, len(users))
  3488. lastUpdatedUser := users[0]
  3489. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  3490. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetPayload(), lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  3491. assert.Empty(t, lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetKey())
  3492. assert.Empty(t, lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  3493. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  3494. rr = executeRequest(req)
  3495. checkResponseCode(t, http.StatusOK, rr.Code)
  3496. }
  3497. func TestWebUserCryptMock(t *testing.T) {
  3498. user := getTestUser()
  3499. userAsJSON := getUserAsJSON(t, user)
  3500. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3501. rr := executeRequest(req)
  3502. checkResponseCode(t, http.StatusOK, rr.Code)
  3503. err := render.DecodeJSON(rr.Body, &user)
  3504. assert.NoError(t, err)
  3505. user.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  3506. user.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("crypted passphrase")
  3507. form := make(url.Values)
  3508. form.Set("username", user.Username)
  3509. form.Set("home_dir", user.HomeDir)
  3510. form.Set("uid", "0")
  3511. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  3512. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  3513. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  3514. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  3515. form.Set("upload_bandwidth", "0")
  3516. form.Set("download_bandwidth", "0")
  3517. form.Set("permissions", "*")
  3518. form.Set("sub_dirs_permissions", "")
  3519. form.Set("status", strconv.Itoa(user.Status))
  3520. form.Set("expiration_date", "2020-01-01 00:00:00")
  3521. form.Set("allowed_ip", "")
  3522. form.Set("denied_ip", "")
  3523. form.Set("fs_provider", "4")
  3524. form.Set("crypt_passphrase", "")
  3525. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  3526. form.Set("denied_extensions", "/dir2::.zip")
  3527. form.Set("max_upload_file_size", "0")
  3528. // passphrase cannot be empty
  3529. b, contentType, _ := getMultipartFormData(form, "", "")
  3530. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3531. req.Header.Set("Content-Type", contentType)
  3532. rr = executeRequest(req)
  3533. checkResponseCode(t, http.StatusOK, rr.Code)
  3534. form.Set("crypt_passphrase", user.FsConfig.CryptConfig.Passphrase.GetPayload())
  3535. b, contentType, _ = getMultipartFormData(form, "", "")
  3536. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3537. req.Header.Set("Content-Type", contentType)
  3538. rr = executeRequest(req)
  3539. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3540. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3541. rr = executeRequest(req)
  3542. checkResponseCode(t, http.StatusOK, rr.Code)
  3543. var users []dataprovider.User
  3544. err = render.DecodeJSON(rr.Body, &users)
  3545. assert.NoError(t, err)
  3546. assert.Equal(t, 1, len(users))
  3547. updateUser := users[0]
  3548. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  3549. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  3550. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.CryptConfig.Passphrase.GetStatus())
  3551. assert.NotEmpty(t, updateUser.FsConfig.CryptConfig.Passphrase.GetPayload())
  3552. assert.Empty(t, updateUser.FsConfig.CryptConfig.Passphrase.GetKey())
  3553. assert.Empty(t, updateUser.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  3554. // now check that a redacted password is not saved
  3555. form.Set("crypt_passphrase", "[**redacted**] ")
  3556. b, contentType, _ = getMultipartFormData(form, "", "")
  3557. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3558. req.Header.Set("Content-Type", contentType)
  3559. rr = executeRequest(req)
  3560. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3561. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3562. rr = executeRequest(req)
  3563. checkResponseCode(t, http.StatusOK, rr.Code)
  3564. users = nil
  3565. err = render.DecodeJSON(rr.Body, &users)
  3566. assert.NoError(t, err)
  3567. assert.Equal(t, 1, len(users))
  3568. lastUpdatedUser := users[0]
  3569. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetStatus())
  3570. assert.Equal(t, updateUser.FsConfig.CryptConfig.Passphrase.GetPayload(), lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetPayload())
  3571. assert.Empty(t, lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetKey())
  3572. assert.Empty(t, lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  3573. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  3574. rr = executeRequest(req)
  3575. checkResponseCode(t, http.StatusOK, rr.Code)
  3576. }
  3577. func TestWebUserSFTPFsMock(t *testing.T) {
  3578. user := getTestUser()
  3579. userAsJSON := getUserAsJSON(t, user)
  3580. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3581. rr := executeRequest(req)
  3582. checkResponseCode(t, http.StatusOK, rr.Code)
  3583. err := render.DecodeJSON(rr.Body, &user)
  3584. assert.NoError(t, err)
  3585. user.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  3586. user.FsConfig.SFTPConfig.Endpoint = "127.0.0.1"
  3587. user.FsConfig.SFTPConfig.Username = "sftpuser"
  3588. user.FsConfig.SFTPConfig.Password = kms.NewPlainSecret("pwd")
  3589. user.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  3590. user.FsConfig.SFTPConfig.Fingerprints = []string{sftpPkeyFingerprint}
  3591. user.FsConfig.SFTPConfig.Prefix = "/home/sftpuser"
  3592. form := make(url.Values)
  3593. form.Set("username", user.Username)
  3594. form.Set("home_dir", user.HomeDir)
  3595. form.Set("uid", "0")
  3596. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  3597. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  3598. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  3599. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  3600. form.Set("upload_bandwidth", "0")
  3601. form.Set("download_bandwidth", "0")
  3602. form.Set("permissions", "*")
  3603. form.Set("sub_dirs_permissions", "")
  3604. form.Set("status", strconv.Itoa(user.Status))
  3605. form.Set("expiration_date", "2020-01-01 00:00:00")
  3606. form.Set("allowed_ip", "")
  3607. form.Set("denied_ip", "")
  3608. form.Set("fs_provider", "5")
  3609. form.Set("crypt_passphrase", "")
  3610. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  3611. form.Set("denied_extensions", "/dir2::.zip")
  3612. form.Set("max_upload_file_size", "0")
  3613. // empty sftpconfig
  3614. b, contentType, _ := getMultipartFormData(form, "", "")
  3615. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3616. req.Header.Set("Content-Type", contentType)
  3617. rr = executeRequest(req)
  3618. checkResponseCode(t, http.StatusOK, rr.Code)
  3619. form.Set("sftp_endpoint", user.FsConfig.SFTPConfig.Endpoint)
  3620. form.Set("sftp_username", user.FsConfig.SFTPConfig.Username)
  3621. form.Set("sftp_password", user.FsConfig.SFTPConfig.Password.GetPayload())
  3622. form.Set("sftp_private_key", user.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  3623. form.Set("sftp_fingerprints", user.FsConfig.SFTPConfig.Fingerprints[0])
  3624. form.Set("sftp_prefix", user.FsConfig.SFTPConfig.Prefix)
  3625. b, contentType, _ = getMultipartFormData(form, "", "")
  3626. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3627. req.Header.Set("Content-Type", contentType)
  3628. rr = executeRequest(req)
  3629. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3630. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3631. rr = executeRequest(req)
  3632. checkResponseCode(t, http.StatusOK, rr.Code)
  3633. var users []dataprovider.User
  3634. err = render.DecodeJSON(rr.Body, &users)
  3635. assert.NoError(t, err)
  3636. assert.Equal(t, 1, len(users))
  3637. updateUser := users[0]
  3638. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  3639. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  3640. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.SFTPConfig.Password.GetStatus())
  3641. assert.NotEmpty(t, updateUser.FsConfig.SFTPConfig.Password.GetPayload())
  3642. assert.Empty(t, updateUser.FsConfig.SFTPConfig.Password.GetKey())
  3643. assert.Empty(t, updateUser.FsConfig.SFTPConfig.Password.GetAdditionalData())
  3644. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  3645. assert.NotEmpty(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  3646. assert.Empty(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetKey())
  3647. assert.Empty(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  3648. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Prefix, user.FsConfig.SFTPConfig.Prefix)
  3649. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Username, user.FsConfig.SFTPConfig.Username)
  3650. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Endpoint, user.FsConfig.SFTPConfig.Endpoint)
  3651. assert.Len(t, updateUser.FsConfig.SFTPConfig.Fingerprints, 1)
  3652. assert.Contains(t, updateUser.FsConfig.SFTPConfig.Fingerprints, sftpPkeyFingerprint)
  3653. // now check that a redacted credentials are not saved
  3654. form.Set("sftp_password", "[**redacted**] ")
  3655. form.Set("sftp_private_key", "[**redacted**]")
  3656. b, contentType, _ = getMultipartFormData(form, "", "")
  3657. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/"+strconv.FormatInt(user.ID, 10), &b)
  3658. req.Header.Set("Content-Type", contentType)
  3659. rr = executeRequest(req)
  3660. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3661. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASC&username="+user.Username, nil)
  3662. rr = executeRequest(req)
  3663. checkResponseCode(t, http.StatusOK, rr.Code)
  3664. users = nil
  3665. err = render.DecodeJSON(rr.Body, &users)
  3666. assert.NoError(t, err)
  3667. assert.Equal(t, 1, len(users))
  3668. lastUpdatedUser := users[0]
  3669. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.SFTPConfig.Password.GetStatus())
  3670. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Password.GetPayload(), lastUpdatedUser.FsConfig.SFTPConfig.Password.GetPayload())
  3671. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.Password.GetKey())
  3672. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.Password.GetAdditionalData())
  3673. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  3674. assert.Equal(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetPayload(), lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  3675. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetKey())
  3676. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  3677. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+strconv.FormatInt(user.ID, 10), nil)
  3678. rr = executeRequest(req)
  3679. checkResponseCode(t, http.StatusOK, rr.Code)
  3680. }
  3681. func TestAddWebFoldersMock(t *testing.T) {
  3682. mappedPath := filepath.Clean(os.TempDir())
  3683. form := make(url.Values)
  3684. form.Set("mapped_path", mappedPath)
  3685. req, err := http.NewRequest(http.MethodPost, webFolderPath, strings.NewReader(form.Encode()))
  3686. assert.NoError(t, err)
  3687. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3688. rr := executeRequest(req)
  3689. checkResponseCode(t, http.StatusSeeOther, rr.Code)
  3690. // adding the same folder will fail since the path must be unique
  3691. req, err = http.NewRequest(http.MethodPost, webFolderPath, strings.NewReader(form.Encode()))
  3692. assert.NoError(t, err)
  3693. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3694. rr = executeRequest(req)
  3695. checkResponseCode(t, http.StatusOK, rr.Code)
  3696. // invalid form
  3697. req, err = http.NewRequest(http.MethodPost, webFolderPath, strings.NewReader(form.Encode()))
  3698. assert.NoError(t, err)
  3699. req.Header.Set("Content-Type", "text/plain; boundary=")
  3700. rr = executeRequest(req)
  3701. checkResponseCode(t, http.StatusOK, rr.Code)
  3702. // now render the add folder page
  3703. req, err = http.NewRequest(http.MethodGet, webFolderPath, nil)
  3704. assert.NoError(t, err)
  3705. rr = executeRequest(req)
  3706. checkResponseCode(t, http.StatusOK, rr.Code)
  3707. var folders []vfs.BaseVirtualFolder
  3708. url, err := url.Parse(folderPath)
  3709. assert.NoError(t, err)
  3710. q := url.Query()
  3711. q.Add("folder_path", mappedPath)
  3712. url.RawQuery = q.Encode()
  3713. req, _ = http.NewRequest(http.MethodGet, url.String(), nil)
  3714. rr = executeRequest(req)
  3715. checkResponseCode(t, http.StatusOK, rr.Code)
  3716. err = render.DecodeJSON(rr.Body, &folders)
  3717. assert.NoError(t, err)
  3718. if assert.Len(t, folders, 1) {
  3719. folder := folders[0]
  3720. assert.Equal(t, mappedPath, folder.MappedPath)
  3721. }
  3722. // cleanup
  3723. url, err = url.Parse(folderPath)
  3724. assert.NoError(t, err)
  3725. q = url.Query()
  3726. q.Add("folder_path", mappedPath)
  3727. url.RawQuery = q.Encode()
  3728. req, _ = http.NewRequest(http.MethodDelete, url.String(), nil)
  3729. rr = executeRequest(req)
  3730. checkResponseCode(t, http.StatusOK, rr.Code)
  3731. }
  3732. func TestWebFoldersMock(t *testing.T) {
  3733. mappedPath1 := filepath.Join(os.TempDir(), "vfolder1")
  3734. mappedPath2 := filepath.Join(os.TempDir(), "vfolder2")
  3735. folders := []vfs.BaseVirtualFolder{
  3736. {
  3737. MappedPath: mappedPath1,
  3738. },
  3739. {
  3740. MappedPath: mappedPath2,
  3741. },
  3742. }
  3743. for _, folder := range folders {
  3744. folderAsJSON, err := json.Marshal(folder)
  3745. assert.NoError(t, err)
  3746. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  3747. rr := executeRequest(req)
  3748. checkResponseCode(t, http.StatusOK, rr.Code)
  3749. }
  3750. req, err := http.NewRequest(http.MethodGet, webFoldersPath, nil)
  3751. assert.NoError(t, err)
  3752. rr := executeRequest(req)
  3753. checkResponseCode(t, http.StatusOK, rr.Code)
  3754. req, err = http.NewRequest(http.MethodGet, webFoldersPath+"?qlimit=a", nil)
  3755. assert.NoError(t, err)
  3756. rr = executeRequest(req)
  3757. checkResponseCode(t, http.StatusOK, rr.Code)
  3758. req, err = http.NewRequest(http.MethodGet, webFoldersPath+"?qlimit=1", nil)
  3759. assert.NoError(t, err)
  3760. rr = executeRequest(req)
  3761. checkResponseCode(t, http.StatusOK, rr.Code)
  3762. for _, folder := range folders {
  3763. url, err := url.Parse(folderPath)
  3764. assert.NoError(t, err)
  3765. q := url.Query()
  3766. q.Add("folder_path", folder.MappedPath)
  3767. url.RawQuery = q.Encode()
  3768. req, _ := http.NewRequest(http.MethodDelete, url.String(), nil)
  3769. rr := executeRequest(req)
  3770. checkResponseCode(t, http.StatusOK, rr.Code)
  3771. }
  3772. }
  3773. func TestProviderClosedMock(t *testing.T) {
  3774. dataprovider.Close()
  3775. req, _ := http.NewRequest(http.MethodGet, webFoldersPath, nil)
  3776. rr := executeRequest(req)
  3777. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  3778. req, _ = http.NewRequest(http.MethodGet, webUsersPath, nil)
  3779. rr = executeRequest(req)
  3780. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  3781. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/0", nil)
  3782. rr = executeRequest(req)
  3783. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  3784. form := make(url.Values)
  3785. form.Set("username", "test")
  3786. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/0", strings.NewReader(form.Encode()))
  3787. rr = executeRequest(req)
  3788. checkResponseCode(t, http.StatusInternalServerError, rr.Code)
  3789. err := config.LoadConfig(configDir, "")
  3790. assert.NoError(t, err)
  3791. providerConf := config.GetProviderConf()
  3792. providerConf.CredentialsPath = credentialsPath
  3793. err = os.RemoveAll(credentialsPath)
  3794. assert.NoError(t, err)
  3795. err = dataprovider.Initialize(providerConf, configDir)
  3796. assert.NoError(t, err)
  3797. }
  3798. func TestGetWebConnectionsMock(t *testing.T) {
  3799. req, _ := http.NewRequest(http.MethodGet, webConnectionsPath, nil)
  3800. rr := executeRequest(req)
  3801. checkResponseCode(t, http.StatusOK, rr.Code)
  3802. }
  3803. func TestGetWebStatusMock(t *testing.T) {
  3804. req, _ := http.NewRequest(http.MethodGet, webStatusPath, nil)
  3805. rr := executeRequest(req)
  3806. checkResponseCode(t, http.StatusOK, rr.Code)
  3807. }
  3808. func TestStaticFilesMock(t *testing.T) {
  3809. req, _ := http.NewRequest(http.MethodGet, "/static/favicon.ico", nil)
  3810. rr := executeRequest(req)
  3811. checkResponseCode(t, http.StatusOK, rr.Code)
  3812. }
  3813. func waitTCPListening(address string) {
  3814. for {
  3815. conn, err := net.Dial("tcp", address)
  3816. if err != nil {
  3817. logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
  3818. time.Sleep(100 * time.Millisecond)
  3819. continue
  3820. }
  3821. logger.InfoToConsole("tcp server %v now listening\n", address)
  3822. conn.Close()
  3823. break
  3824. }
  3825. }
  3826. func getTestUser() dataprovider.User {
  3827. user := dataprovider.User{
  3828. Username: defaultUsername,
  3829. Password: defaultPassword,
  3830. HomeDir: filepath.Join(homeBasePath, defaultUsername),
  3831. Status: 1,
  3832. }
  3833. user.Permissions = make(map[string][]string)
  3834. user.Permissions["/"] = defaultPerms
  3835. return user
  3836. }
  3837. func getUserAsJSON(t *testing.T, user dataprovider.User) []byte {
  3838. json, err := json.Marshal(user)
  3839. assert.NoError(t, err)
  3840. return json
  3841. }
  3842. func executeRequest(req *http.Request) *httptest.ResponseRecorder {
  3843. rr := httptest.NewRecorder()
  3844. testServer.Config.Handler.ServeHTTP(rr, req)
  3845. return rr
  3846. }
  3847. func checkResponseCode(t *testing.T, expected, actual int) {
  3848. assert.Equal(t, expected, actual)
  3849. }
  3850. func createTestFile(path string, size int64) error {
  3851. baseDir := filepath.Dir(path)
  3852. if _, err := os.Stat(baseDir); os.IsNotExist(err) {
  3853. err = os.MkdirAll(baseDir, os.ModePerm)
  3854. if err != nil {
  3855. return err
  3856. }
  3857. }
  3858. content := make([]byte, size)
  3859. if size > 0 {
  3860. _, err := rand.Read(content)
  3861. if err != nil {
  3862. return err
  3863. }
  3864. }
  3865. return ioutil.WriteFile(path, content, os.ModePerm)
  3866. }
  3867. func getMultipartFormData(values url.Values, fileFieldName, filePath string) (bytes.Buffer, string, error) {
  3868. var b bytes.Buffer
  3869. w := multipart.NewWriter(&b)
  3870. for k, v := range values {
  3871. for _, s := range v {
  3872. if err := w.WriteField(k, s); err != nil {
  3873. return b, "", err
  3874. }
  3875. }
  3876. }
  3877. if len(fileFieldName) > 0 && len(filePath) > 0 {
  3878. fw, err := w.CreateFormFile(fileFieldName, filepath.Base(filePath))
  3879. if err != nil {
  3880. return b, "", err
  3881. }
  3882. f, err := os.Open(filePath)
  3883. if err != nil {
  3884. return b, "", err
  3885. }
  3886. defer f.Close()
  3887. if _, err = io.Copy(fw, f); err != nil {
  3888. return b, "", err
  3889. }
  3890. }
  3891. err := w.Close()
  3892. return b, w.FormDataContentType(), err
  3893. }
  3894. func BenchmarkSecretDecryption(b *testing.B) {
  3895. s := kms.NewPlainSecret("test data")
  3896. s.SetAdditionalData("username")
  3897. err := s.Encrypt()
  3898. require.NoError(b, err)
  3899. for i := 0; i < b.N; i++ {
  3900. err = s.Clone().Decrypt()
  3901. require.NoError(b, err)
  3902. }
  3903. }