httpd_test.go 234 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916
  1. package httpd_test
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "mime/multipart"
  11. "net"
  12. "net/http"
  13. "net/http/httptest"
  14. "net/url"
  15. "os"
  16. "path"
  17. "path/filepath"
  18. "runtime"
  19. "strconv"
  20. "strings"
  21. "testing"
  22. "time"
  23. "github.com/go-chi/render"
  24. _ "github.com/go-sql-driver/mysql"
  25. _ "github.com/lib/pq"
  26. _ "github.com/mattn/go-sqlite3"
  27. "github.com/rs/zerolog"
  28. "github.com/stretchr/testify/assert"
  29. "github.com/stretchr/testify/require"
  30. "github.com/drakkan/sftpgo/common"
  31. "github.com/drakkan/sftpgo/config"
  32. "github.com/drakkan/sftpgo/dataprovider"
  33. "github.com/drakkan/sftpgo/httpclient"
  34. "github.com/drakkan/sftpgo/httpd"
  35. "github.com/drakkan/sftpgo/httpdtest"
  36. "github.com/drakkan/sftpgo/kms"
  37. "github.com/drakkan/sftpgo/logger"
  38. "github.com/drakkan/sftpgo/utils"
  39. "github.com/drakkan/sftpgo/vfs"
  40. )
  41. const (
  42. defaultUsername = "test_user"
  43. defaultPassword = "test_password"
  44. testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  45. defaultTokenAuthUser = "admin"
  46. defaultTokenAuthPass = "password"
  47. altAdminUsername = "newTestAdmin"
  48. altAdminPassword = "password1"
  49. userPath = "/api/v2/users"
  50. adminPath = "/api/v2/admins"
  51. adminPwdPath = "/api/v2/changepwd/admin"
  52. folderPath = "/api/v2/folders"
  53. activeConnectionsPath = "/api/v2/connections"
  54. serverStatusPath = "/api/v2/status"
  55. quotaScanPath = "/api/v2/quota-scans"
  56. quotaScanVFolderPath = "/api/v2/folder-quota-scans"
  57. updateUsedQuotaPath = "/api/v2/quota-update"
  58. updateFolderUsedQuotaPath = "/api/v2/folder-quota-update"
  59. defenderUnban = "/api/v2/defender/unban"
  60. versionPath = "/api/v2/version"
  61. logoutPath = "/api/v2/logout"
  62. healthzPath = "/healthz"
  63. webBasePath = "/web"
  64. webLoginPath = "/web/login"
  65. webLogoutPath = "/web/logout"
  66. webUsersPath = "/web/users"
  67. webUserPath = "/web/user"
  68. webFoldersPath = "/web/folders"
  69. webFolderPath = "/web/folder"
  70. webConnectionsPath = "/web/connections"
  71. webStatusPath = "/web/status"
  72. webAdminsPath = "/web/admins"
  73. webAdminPath = "/web/admin"
  74. webMaintenancePath = "/web/maintenance"
  75. webRestorePath = "/web/restore"
  76. webChangeAdminPwdPath = "/web/changepwd/admin"
  77. webTemplateUser = "/web/template/user"
  78. httpBaseURL = "http://127.0.0.1:8081"
  79. configDir = ".."
  80. httpsCert = `-----BEGIN CERTIFICATE-----
  81. MIICHTCCAaKgAwIBAgIUHnqw7QnB1Bj9oUsNpdb+ZkFPOxMwCgYIKoZIzj0EAwIw
  82. RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
  83. dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDAyMDQwOTUzMDRaFw0zMDAyMDEw
  84. OTUzMDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
  85. VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
  86. IgNiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVqWvrJ51t5OxV0v25NsOgR82CA
  87. NXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIVCzgWkxiz7XE4lgUwX44FCXZM
  88. 3+JeUbKjUzBRMB0GA1UdDgQWBBRhLw+/o3+Z02MI/d4tmaMui9W16jAfBgNVHSME
  89. GDAWgBRhLw+/o3+Z02MI/d4tmaMui9W16jAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
  90. SM49BAMCA2kAMGYCMQDqLt2lm8mE+tGgtjDmtFgdOcI72HSbRQ74D5rYTzgST1rY
  91. /8wTi5xl8TiFUyLMUsICMQC5ViVxdXbhuG7gX6yEqSkMKZICHpO8hqFwOD/uaFVI
  92. dV4vKmHUzwK/eIx+8Ay3neE=
  93. -----END CERTIFICATE-----`
  94. httpsKey = `-----BEGIN EC PARAMETERS-----
  95. BgUrgQQAIg==
  96. -----END EC PARAMETERS-----
  97. -----BEGIN EC PRIVATE KEY-----
  98. MIGkAgEBBDCfMNsN6miEE3rVyUPwElfiJSWaR5huPCzUenZOfJT04GAcQdWvEju3
  99. UM2lmBLIXpGgBwYFK4EEACKhZANiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVq
  100. WvrJ51t5OxV0v25NsOgR82CANXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIV
  101. CzgWkxiz7XE4lgUwX44FCXZM3+JeUbI=
  102. -----END EC PRIVATE KEY-----`
  103. sftpPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
  104. b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
  105. QyNTUxOQAAACB+RB4yNTZz9mHOkawwUibNdemijVV3ErMeLxWUBlCN/gAAAJA7DjpfOw46
  106. XwAAAAtzc2gtZWQyNTUxOQAAACB+RB4yNTZz9mHOkawwUibNdemijVV3ErMeLxWUBlCN/g
  107. AAAEA0E24gi8ab/XRSvJ85TGZJMe6HVmwxSG4ExPfTMwwe2n5EHjI1NnP2Yc6RrDBSJs11
  108. 6aKNVXcSsx4vFZQGUI3+AAAACW5pY29sYUBwMQECAwQ=
  109. -----END OPENSSH PRIVATE KEY-----`
  110. sftpPkeyFingerprint = "SHA256:QVQ06XHZZbYZzqfrsZcf3Yozy2WTnqQPeLOkcJCdbP0"
  111. )
  112. var (
  113. defaultPerms = []string{dataprovider.PermAny}
  114. homeBasePath string
  115. backupsPath string
  116. credentialsPath string
  117. testServer *httptest.Server
  118. providerDriverName string
  119. )
  120. type fakeConnection struct {
  121. *common.BaseConnection
  122. command string
  123. }
  124. func (c *fakeConnection) Disconnect() error {
  125. common.Connections.Remove(c.GetID())
  126. return nil
  127. }
  128. func (c *fakeConnection) GetClientVersion() string {
  129. return ""
  130. }
  131. func (c *fakeConnection) GetCommand() string {
  132. return c.command
  133. }
  134. func (c *fakeConnection) GetRemoteAddress() string {
  135. return ""
  136. }
  137. func TestMain(m *testing.M) {
  138. homeBasePath = os.TempDir()
  139. logfilePath := filepath.Join(configDir, "sftpgo_api_test.log")
  140. logger.InitLogger(logfilePath, 5, 1, 28, false, zerolog.DebugLevel)
  141. err := config.LoadConfig(configDir, "")
  142. if err != nil {
  143. logger.WarnToConsole("error loading configuration: %v", err)
  144. os.Exit(1)
  145. }
  146. providerConf := config.GetProviderConf()
  147. credentialsPath = filepath.Join(os.TempDir(), "test_credentials")
  148. providerConf.CredentialsPath = credentialsPath
  149. providerDriverName = providerConf.Driver
  150. os.RemoveAll(credentialsPath) //nolint:errcheck
  151. logger.InfoToConsole("Starting HTTPD tests, provider: %v", providerConf.Driver)
  152. err = common.Initialize(config.GetCommonConfig())
  153. if err != nil {
  154. logger.WarnToConsole("error initializing common: %v", err)
  155. os.Exit(1)
  156. }
  157. err = dataprovider.Initialize(providerConf, configDir, true)
  158. if err != nil {
  159. logger.WarnToConsole("error initializing data provider: %v", err)
  160. os.Exit(1)
  161. }
  162. httpConfig := config.GetHTTPConfig()
  163. httpConfig.Initialize(configDir)
  164. kmsConfig := config.GetKMSConfig()
  165. err = kmsConfig.Initialize()
  166. if err != nil {
  167. logger.ErrorToConsole("error initializing kms: %v", err)
  168. os.Exit(1)
  169. }
  170. httpdConf := config.GetHTTPDConfig()
  171. httpdConf.Bindings[0].Port = 8081
  172. httpdtest.SetBaseURL(httpBaseURL)
  173. backupsPath = filepath.Join(os.TempDir(), "test_backups")
  174. httpdConf.BackupsPath = backupsPath
  175. err = os.MkdirAll(backupsPath, os.ModePerm)
  176. if err != nil {
  177. logger.ErrorToConsole("error creating backups path: %v", err)
  178. os.Exit(1)
  179. }
  180. go func() {
  181. if err := httpdConf.Initialize(configDir); err != nil {
  182. logger.ErrorToConsole("could not start HTTP server: %v", err)
  183. os.Exit(1)
  184. }
  185. }()
  186. waitTCPListening(httpdConf.Bindings[0].GetAddress())
  187. httpd.ReloadCertificateMgr() //nolint:errcheck
  188. // now start an https server
  189. certPath := filepath.Join(os.TempDir(), "test.crt")
  190. keyPath := filepath.Join(os.TempDir(), "test.key")
  191. err = ioutil.WriteFile(certPath, []byte(httpsCert), os.ModePerm)
  192. if err != nil {
  193. logger.ErrorToConsole("error writing HTTPS certificate: %v", err)
  194. os.Exit(1)
  195. }
  196. err = ioutil.WriteFile(keyPath, []byte(httpsKey), os.ModePerm)
  197. if err != nil {
  198. logger.ErrorToConsole("error writing HTTPS private key: %v", err)
  199. os.Exit(1)
  200. }
  201. httpdConf.Bindings[0].Port = 8443
  202. httpdConf.Bindings[0].EnableHTTPS = true
  203. httpdConf.CertificateFile = certPath
  204. httpdConf.CertificateKeyFile = keyPath
  205. httpdConf.Bindings = append(httpdConf.Bindings, httpd.Binding{})
  206. go func() {
  207. if err := httpdConf.Initialize(configDir); err != nil {
  208. logger.ErrorToConsole("could not start HTTPS server: %v", err)
  209. os.Exit(1)
  210. }
  211. }()
  212. waitTCPListening(httpdConf.Bindings[0].GetAddress())
  213. httpd.ReloadCertificateMgr() //nolint:errcheck
  214. testServer = httptest.NewServer(httpd.GetHTTPRouter())
  215. defer testServer.Close()
  216. exitCode := m.Run()
  217. os.Remove(logfilePath) //nolint:errcheck
  218. os.RemoveAll(backupsPath) //nolint:errcheck
  219. os.RemoveAll(credentialsPath) //nolint:errcheck
  220. os.Remove(certPath) //nolint:errcheck
  221. os.Remove(keyPath) //nolint:errcheck
  222. os.Exit(exitCode) //nolint:errcheck
  223. }
  224. func TestInitialization(t *testing.T) {
  225. err := config.LoadConfig(configDir, "")
  226. assert.NoError(t, err)
  227. invalidFile := "invalid file"
  228. httpdConf := config.GetHTTPDConfig()
  229. httpdConf.BackupsPath = backupsPath
  230. httpdConf.CertificateFile = invalidFile
  231. httpdConf.CertificateKeyFile = invalidFile
  232. err = httpdConf.Initialize(configDir)
  233. assert.Error(t, err)
  234. httpdConf.CertificateFile = ""
  235. httpdConf.CertificateKeyFile = ""
  236. httpdConf.TemplatesPath = "."
  237. err = httpdConf.Initialize(configDir)
  238. assert.Error(t, err)
  239. httpdConf = config.GetHTTPDConfig()
  240. httpdConf.BackupsPath = ".."
  241. err = httpdConf.Initialize(configDir)
  242. assert.Error(t, err)
  243. httpdConf.BackupsPath = backupsPath
  244. httpdConf.CertificateFile = invalidFile
  245. httpdConf.CertificateKeyFile = invalidFile
  246. httpdConf.StaticFilesPath = ""
  247. httpdConf.TemplatesPath = ""
  248. err = httpdConf.Initialize(configDir)
  249. assert.Error(t, err)
  250. httpdConf.CertificateFile = filepath.Join(os.TempDir(), "test.crt")
  251. httpdConf.CertificateKeyFile = filepath.Join(os.TempDir(), "test.key")
  252. httpdConf.CACertificates = append(httpdConf.CACertificates, invalidFile)
  253. err = httpdConf.Initialize(configDir)
  254. assert.Error(t, err)
  255. httpdConf.CACertificates = nil
  256. httpdConf.CARevocationLists = append(httpdConf.CARevocationLists, invalidFile)
  257. err = httpdConf.Initialize(configDir)
  258. assert.Error(t, err)
  259. httpdConf.CARevocationLists = nil
  260. httpdConf.Bindings[0].Port = 8081
  261. httpdConf.Bindings[0].EnableHTTPS = true
  262. httpdConf.Bindings[0].ClientAuthType = 1
  263. err = httpdConf.Initialize(configDir)
  264. assert.Error(t, err)
  265. }
  266. func TestBasicUserHandling(t *testing.T) {
  267. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  268. assert.NoError(t, err)
  269. user.MaxSessions = 10
  270. user.QuotaSize = 4096
  271. user.QuotaFiles = 2
  272. user.UploadBandwidth = 128
  273. user.DownloadBandwidth = 64
  274. user.ExpirationDate = utils.GetTimeAsMsSinceEpoch(time.Now())
  275. user.AdditionalInfo = "some free text"
  276. originalUser := user
  277. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  278. assert.NoError(t, err)
  279. assert.Equal(t, originalUser.ID, user.ID)
  280. user, _, err = httpdtest.GetUserByUsername(defaultUsername, http.StatusOK)
  281. assert.NoError(t, err)
  282. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  283. assert.NoError(t, err)
  284. }
  285. func TestBasicAdminHandling(t *testing.T) {
  286. // we have one admin by default
  287. admins, _, err := httpdtest.GetAdmins(0, 0, http.StatusOK)
  288. assert.NoError(t, err)
  289. assert.GreaterOrEqual(t, len(admins), 1)
  290. admin := getTestAdmin()
  291. // the default admin already exists
  292. _, _, err = httpdtest.AddAdmin(admin, http.StatusInternalServerError)
  293. assert.NoError(t, err)
  294. admin.Username = altAdminUsername
  295. admin, _, err = httpdtest.AddAdmin(admin, http.StatusCreated)
  296. assert.NoError(t, err)
  297. admin, _, err = httpdtest.GetAdminByUsername(admin.Username, http.StatusOK)
  298. assert.NoError(t, err)
  299. admin.AdditionalInfo = "test info"
  300. admin, _, err = httpdtest.UpdateAdmin(admin, http.StatusOK)
  301. assert.NoError(t, err)
  302. assert.Equal(t, "test info", admin.AdditionalInfo)
  303. admins, _, err = httpdtest.GetAdmins(1, 0, http.StatusOK)
  304. assert.NoError(t, err)
  305. assert.Len(t, admins, 1)
  306. assert.NotEqual(t, admin.Username, admins[0].Username)
  307. admins, _, err = httpdtest.GetAdmins(1, 1, http.StatusOK)
  308. assert.NoError(t, err)
  309. assert.Len(t, admins, 1)
  310. assert.Equal(t, admin.Username, admins[0].Username)
  311. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  312. assert.NoError(t, err)
  313. _, err = httpdtest.RemoveAdmin(admin, http.StatusNotFound)
  314. assert.NoError(t, err)
  315. admin, _, err = httpdtest.GetAdminByUsername(admin.Username+"123", http.StatusNotFound)
  316. assert.NoError(t, err)
  317. admin.Username = defaultTokenAuthUser
  318. _, err = httpdtest.RemoveAdmin(admin, http.StatusBadRequest)
  319. assert.NoError(t, err)
  320. }
  321. func TestChangeAdminPassword(t *testing.T) {
  322. _, err := httpdtest.ChangeAdminPassword("wrong", defaultTokenAuthPass, http.StatusBadRequest)
  323. assert.NoError(t, err)
  324. _, err = httpdtest.ChangeAdminPassword(defaultTokenAuthPass, defaultTokenAuthPass, http.StatusBadRequest)
  325. assert.NoError(t, err)
  326. _, err = httpdtest.ChangeAdminPassword(defaultTokenAuthPass, defaultTokenAuthPass+"1", http.StatusOK)
  327. assert.NoError(t, err)
  328. _, err = httpdtest.ChangeAdminPassword(defaultTokenAuthPass+"1", defaultTokenAuthPass, http.StatusUnauthorized)
  329. assert.NoError(t, err)
  330. admin, err := dataprovider.AdminExists(defaultTokenAuthUser)
  331. assert.NoError(t, err)
  332. admin.Password = defaultTokenAuthPass
  333. err = dataprovider.UpdateAdmin(&admin)
  334. assert.NoError(t, err)
  335. }
  336. func TestAdminAllowList(t *testing.T) {
  337. a := getTestAdmin()
  338. a.Username = altAdminUsername
  339. a.Password = altAdminPassword
  340. admin, _, err := httpdtest.AddAdmin(a, http.StatusCreated)
  341. assert.NoError(t, err)
  342. token, _, err := httpdtest.GetToken(altAdminUsername, altAdminPassword)
  343. assert.NoError(t, err)
  344. httpdtest.SetJWTToken(token)
  345. _, _, err = httpdtest.GetStatus(http.StatusOK)
  346. assert.NoError(t, err)
  347. httpdtest.SetJWTToken("")
  348. admin.Password = altAdminPassword
  349. admin.Filters.AllowList = []string{"10.6.6.0/32"}
  350. admin, _, err = httpdtest.UpdateAdmin(admin, http.StatusOK)
  351. assert.NoError(t, err)
  352. _, _, err = httpdtest.GetToken(altAdminUsername, altAdminPassword)
  353. assert.EqualError(t, err, "wrong status code: got 401 want 200")
  354. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  355. assert.NoError(t, err)
  356. }
  357. func TestUserStatus(t *testing.T) {
  358. u := getTestUser()
  359. u.Status = 3
  360. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  361. assert.NoError(t, err)
  362. u.Status = 0
  363. user, _, err := httpdtest.AddUser(u, http.StatusCreated)
  364. assert.NoError(t, err)
  365. user.Status = 2
  366. _, _, err = httpdtest.UpdateUser(user, http.StatusBadRequest, "")
  367. assert.NoError(t, err)
  368. user.Status = 1
  369. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  370. assert.NoError(t, err)
  371. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  372. assert.NoError(t, err)
  373. }
  374. func TestAddUserNoCredentials(t *testing.T) {
  375. u := getTestUser()
  376. u.Password = ""
  377. u.PublicKeys = []string{}
  378. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  379. assert.NoError(t, err)
  380. }
  381. func TestAddUserNoUsername(t *testing.T) {
  382. u := getTestUser()
  383. u.Username = ""
  384. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  385. assert.NoError(t, err)
  386. }
  387. func TestAddUserNoHomeDir(t *testing.T) {
  388. u := getTestUser()
  389. u.HomeDir = ""
  390. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  391. assert.NoError(t, err)
  392. }
  393. func TestAddUserInvalidHomeDir(t *testing.T) {
  394. u := getTestUser()
  395. u.HomeDir = "relative_path" //nolint:goconst
  396. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  397. assert.NoError(t, err)
  398. }
  399. func TestAddUserNoPerms(t *testing.T) {
  400. u := getTestUser()
  401. u.Permissions = make(map[string][]string)
  402. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  403. assert.NoError(t, err)
  404. u.Permissions["/"] = []string{}
  405. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  406. assert.NoError(t, err)
  407. }
  408. func TestAddUserInvalidPerms(t *testing.T) {
  409. u := getTestUser()
  410. u.Permissions["/"] = []string{"invalidPerm"}
  411. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  412. assert.NoError(t, err)
  413. // permissions for root dir are mandatory
  414. u.Permissions["/"] = []string{}
  415. u.Permissions["/somedir"] = []string{dataprovider.PermAny}
  416. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  417. assert.NoError(t, err)
  418. u.Permissions["/"] = []string{dataprovider.PermAny}
  419. u.Permissions["/subdir/.."] = []string{dataprovider.PermAny}
  420. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  421. assert.NoError(t, err)
  422. }
  423. func TestAddUserInvalidFilters(t *testing.T) {
  424. u := getTestUser()
  425. u.Filters.AllowedIP = []string{"192.168.1.0/24", "192.168.2.0"}
  426. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  427. assert.NoError(t, err)
  428. u.Filters.AllowedIP = []string{}
  429. u.Filters.DeniedIP = []string{"192.168.3.0/16", "invalid"}
  430. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  431. assert.NoError(t, err)
  432. u.Filters.DeniedIP = []string{}
  433. u.Filters.DeniedLoginMethods = []string{"invalid"}
  434. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  435. assert.NoError(t, err)
  436. u.Filters.DeniedLoginMethods = dataprovider.ValidSSHLoginMethods
  437. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  438. assert.NoError(t, err)
  439. u.Filters.DeniedLoginMethods = []string{}
  440. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  441. {
  442. Path: "relative",
  443. AllowedExtensions: []string{},
  444. DeniedExtensions: []string{},
  445. },
  446. }
  447. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  448. assert.NoError(t, err)
  449. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  450. {
  451. Path: "/",
  452. AllowedExtensions: []string{},
  453. DeniedExtensions: []string{},
  454. },
  455. }
  456. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  457. assert.NoError(t, err)
  458. u.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  459. {
  460. Path: "/subdir",
  461. AllowedExtensions: []string{".zip"},
  462. DeniedExtensions: []string{},
  463. },
  464. {
  465. Path: "/subdir",
  466. AllowedExtensions: []string{".rar"},
  467. DeniedExtensions: []string{".jpg"},
  468. },
  469. }
  470. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  471. assert.NoError(t, err)
  472. u.Filters.FileExtensions = nil
  473. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  474. {
  475. Path: "relative",
  476. AllowedPatterns: []string{},
  477. DeniedPatterns: []string{},
  478. },
  479. }
  480. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  481. assert.NoError(t, err)
  482. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  483. {
  484. Path: "/",
  485. AllowedPatterns: []string{},
  486. DeniedPatterns: []string{},
  487. },
  488. }
  489. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  490. assert.NoError(t, err)
  491. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  492. {
  493. Path: "/subdir",
  494. AllowedPatterns: []string{"*.zip"},
  495. },
  496. {
  497. Path: "/subdir",
  498. AllowedPatterns: []string{"*.rar"},
  499. DeniedPatterns: []string{"*.jpg"},
  500. },
  501. }
  502. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  503. assert.NoError(t, err)
  504. u.Filters.FilePatterns = []dataprovider.PatternsFilter{
  505. {
  506. Path: "/subdir",
  507. AllowedPatterns: []string{"a\\"},
  508. },
  509. }
  510. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  511. assert.NoError(t, err)
  512. u.Filters.DeniedProtocols = []string{"invalid"}
  513. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  514. assert.NoError(t, err)
  515. u.Filters.DeniedProtocols = dataprovider.ValidProtocols
  516. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  517. assert.NoError(t, err)
  518. }
  519. func TestAddUserInvalidFsConfig(t *testing.T) {
  520. u := getTestUser()
  521. u.FsConfig.Provider = dataprovider.S3FilesystemProvider
  522. u.FsConfig.S3Config.Bucket = ""
  523. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  524. assert.NoError(t, err)
  525. err = os.RemoveAll(credentialsPath)
  526. assert.NoError(t, err)
  527. err = os.MkdirAll(credentialsPath, 0700)
  528. assert.NoError(t, err)
  529. u.FsConfig.S3Config.Bucket = "testbucket"
  530. u.FsConfig.S3Config.Region = "eu-west-1"
  531. u.FsConfig.S3Config.AccessKey = "access-key"
  532. u.FsConfig.S3Config.AccessSecret = kms.NewSecret(kms.SecretStatusRedacted, "access-secret", "", "")
  533. u.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/path?a=b"
  534. u.FsConfig.S3Config.StorageClass = "Standard" //nolint:goconst
  535. u.FsConfig.S3Config.KeyPrefix = "/adir/subdir/"
  536. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  537. assert.NoError(t, err)
  538. u.FsConfig.S3Config.AccessSecret.SetStatus(kms.SecretStatusPlain)
  539. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  540. assert.NoError(t, err)
  541. u.FsConfig.S3Config.KeyPrefix = ""
  542. u.FsConfig.S3Config.UploadPartSize = 3
  543. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  544. assert.NoError(t, err)
  545. u.FsConfig.S3Config.UploadPartSize = 5001
  546. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  547. assert.NoError(t, err)
  548. u.FsConfig.S3Config.UploadPartSize = 0
  549. u.FsConfig.S3Config.UploadConcurrency = -1
  550. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  551. assert.NoError(t, err)
  552. u = getTestUser()
  553. u.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  554. u.FsConfig.GCSConfig.Bucket = ""
  555. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  556. assert.NoError(t, err)
  557. u.FsConfig.GCSConfig.Bucket = "abucket"
  558. u.FsConfig.GCSConfig.StorageClass = "Standard"
  559. u.FsConfig.GCSConfig.KeyPrefix = "/somedir/subdir/"
  560. u.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusRedacted, "test", "", "") //nolint:goconst
  561. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  562. assert.NoError(t, err)
  563. u.FsConfig.GCSConfig.Credentials.SetStatus(kms.SecretStatusPlain)
  564. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  565. assert.NoError(t, err)
  566. u.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir/" //nolint:goconst
  567. u.FsConfig.GCSConfig.Credentials = kms.NewEmptySecret()
  568. u.FsConfig.GCSConfig.AutomaticCredentials = 0
  569. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  570. assert.NoError(t, err)
  571. u.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusSecretBox, "invalid", "", "")
  572. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  573. assert.NoError(t, err)
  574. u = getTestUser()
  575. u.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  576. u.FsConfig.AzBlobConfig.SASURL = "http://foo\x7f.com/"
  577. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  578. assert.NoError(t, err)
  579. u.FsConfig.AzBlobConfig.SASURL = ""
  580. u.FsConfig.AzBlobConfig.AccountName = "name"
  581. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  582. assert.NoError(t, err)
  583. u.FsConfig.AzBlobConfig.Container = "container"
  584. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  585. assert.NoError(t, err)
  586. u.FsConfig.AzBlobConfig.AccountKey = kms.NewSecret(kms.SecretStatusRedacted, "key", "", "")
  587. u.FsConfig.AzBlobConfig.KeyPrefix = "/amedir/subdir/"
  588. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  589. assert.NoError(t, err)
  590. u.FsConfig.AzBlobConfig.AccountKey.SetStatus(kms.SecretStatusPlain)
  591. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  592. assert.NoError(t, err)
  593. u.FsConfig.AzBlobConfig.KeyPrefix = "amedir/subdir/"
  594. u.FsConfig.AzBlobConfig.UploadPartSize = -1
  595. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  596. assert.NoError(t, err)
  597. u.FsConfig.AzBlobConfig.UploadPartSize = 101
  598. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  599. assert.NoError(t, err)
  600. u = getTestUser()
  601. u.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  602. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  603. assert.NoError(t, err)
  604. u.FsConfig.CryptConfig.Passphrase = kms.NewSecret(kms.SecretStatusRedacted, "akey", "", "")
  605. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  606. assert.NoError(t, err)
  607. u = getTestUser()
  608. u.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  609. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  610. assert.NoError(t, err)
  611. u.FsConfig.SFTPConfig.Password = kms.NewSecret(kms.SecretStatusRedacted, "randompkey", "", "")
  612. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  613. assert.NoError(t, err)
  614. u.FsConfig.SFTPConfig.Password = kms.NewEmptySecret()
  615. u.FsConfig.SFTPConfig.PrivateKey = kms.NewSecret(kms.SecretStatusRedacted, "keyforpkey", "", "")
  616. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  617. assert.NoError(t, err)
  618. }
  619. func TestAddUserInvalidVirtualFolders(t *testing.T) {
  620. u := getTestUser()
  621. folderName := "fname"
  622. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  623. BaseVirtualFolder: vfs.BaseVirtualFolder{
  624. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  625. Name: folderName,
  626. },
  627. VirtualPath: "vdir", // invalid
  628. })
  629. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  630. assert.NoError(t, err)
  631. u.VirtualFolders = nil
  632. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  633. BaseVirtualFolder: vfs.BaseVirtualFolder{
  634. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  635. Name: folderName,
  636. },
  637. VirtualPath: "/", // invalid
  638. })
  639. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  640. assert.NoError(t, err)
  641. u.VirtualFolders = nil
  642. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  643. BaseVirtualFolder: vfs.BaseVirtualFolder{
  644. MappedPath: filepath.Join(u.GetHomeDir(), "mapped_dir"), // invalid, inside home dir
  645. Name: folderName,
  646. },
  647. VirtualPath: "/vdir",
  648. })
  649. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  650. assert.NoError(t, err)
  651. u.VirtualFolders = nil
  652. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  653. BaseVirtualFolder: vfs.BaseVirtualFolder{
  654. MappedPath: u.GetHomeDir(), // invalid
  655. Name: folderName,
  656. },
  657. VirtualPath: "/vdir",
  658. })
  659. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  660. assert.NoError(t, err)
  661. u.VirtualFolders = nil
  662. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  663. BaseVirtualFolder: vfs.BaseVirtualFolder{
  664. MappedPath: filepath.Join(u.GetHomeDir(), ".."), // invalid, contains home dir
  665. Name: "tmp",
  666. },
  667. VirtualPath: "/vdir",
  668. })
  669. _, _, err = httpdtest.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_dir"),
  675. Name: folderName,
  676. },
  677. VirtualPath: "/vdir",
  678. })
  679. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  680. BaseVirtualFolder: vfs.BaseVirtualFolder{
  681. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  682. Name: folderName + "1",
  683. },
  684. VirtualPath: "/vdir", // invalid, already defined
  685. })
  686. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  687. assert.NoError(t, err)
  688. u.VirtualFolders = nil
  689. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  690. BaseVirtualFolder: vfs.BaseVirtualFolder{
  691. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  692. Name: folderName,
  693. },
  694. VirtualPath: "/vdir1",
  695. })
  696. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  697. BaseVirtualFolder: vfs.BaseVirtualFolder{
  698. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"), // invalid, already defined
  699. Name: folderName,
  700. },
  701. VirtualPath: "/vdir2",
  702. })
  703. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  704. assert.NoError(t, err)
  705. u.VirtualFolders = nil
  706. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  707. BaseVirtualFolder: vfs.BaseVirtualFolder{
  708. MappedPath: filepath.Join(os.TempDir(), "mapped_dir", "subdir"),
  709. Name: folderName + "2",
  710. },
  711. VirtualPath: "/vdir1",
  712. })
  713. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  714. BaseVirtualFolder: vfs.BaseVirtualFolder{
  715. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"), // invalid, contains mapped_dir/subdir
  716. Name: folderName,
  717. },
  718. VirtualPath: "/vdir2",
  719. })
  720. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  721. assert.NoError(t, err)
  722. u.VirtualFolders = nil
  723. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  724. BaseVirtualFolder: vfs.BaseVirtualFolder{
  725. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  726. Name: folderName,
  727. },
  728. VirtualPath: "/vdir1",
  729. })
  730. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  731. BaseVirtualFolder: vfs.BaseVirtualFolder{
  732. MappedPath: filepath.Join(os.TempDir(), "mapped_dir", "subdir"), // invalid, contained in mapped_dir
  733. Name: folderName + "3",
  734. },
  735. VirtualPath: "/vdir2",
  736. })
  737. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  738. assert.NoError(t, err)
  739. u.VirtualFolders = nil
  740. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  741. BaseVirtualFolder: vfs.BaseVirtualFolder{
  742. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  743. Name: folderName + "1",
  744. },
  745. VirtualPath: "/vdir1/subdir",
  746. })
  747. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  748. BaseVirtualFolder: vfs.BaseVirtualFolder{
  749. MappedPath: filepath.Join(os.TempDir(), "mapped_dir2"),
  750. Name: folderName + "2",
  751. },
  752. VirtualPath: "/vdir1/../vdir1", // invalid, overlaps with /vdir1/subdir
  753. })
  754. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  755. assert.NoError(t, err)
  756. u.VirtualFolders = nil
  757. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  758. BaseVirtualFolder: vfs.BaseVirtualFolder{
  759. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  760. Name: folderName + "1",
  761. },
  762. VirtualPath: "/vdir1/",
  763. })
  764. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  765. BaseVirtualFolder: vfs.BaseVirtualFolder{
  766. MappedPath: filepath.Join(os.TempDir(), "mapped_dir2"),
  767. Name: folderName + "2",
  768. },
  769. VirtualPath: "/vdir1/subdir", // invalid, contained inside /vdir1
  770. })
  771. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  772. assert.NoError(t, err)
  773. u.VirtualFolders = nil
  774. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  775. BaseVirtualFolder: vfs.BaseVirtualFolder{
  776. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  777. Name: folderName + "1",
  778. },
  779. VirtualPath: "/vdir1/",
  780. QuotaSize: -1,
  781. QuotaFiles: 1, // invvalid, we cannot have -1 and > 0
  782. })
  783. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  784. assert.NoError(t, err)
  785. u.VirtualFolders = nil
  786. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  787. BaseVirtualFolder: vfs.BaseVirtualFolder{
  788. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  789. Name: folderName + "1",
  790. },
  791. VirtualPath: "/vdir1/",
  792. QuotaSize: 1,
  793. QuotaFiles: -1,
  794. })
  795. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  796. assert.NoError(t, err)
  797. u.VirtualFolders = nil
  798. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  799. BaseVirtualFolder: vfs.BaseVirtualFolder{
  800. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  801. Name: folderName + "1",
  802. },
  803. VirtualPath: "/vdir1/",
  804. QuotaSize: -2, // invalid
  805. QuotaFiles: 0,
  806. })
  807. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  808. assert.NoError(t, err)
  809. u.VirtualFolders = nil
  810. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  811. BaseVirtualFolder: vfs.BaseVirtualFolder{
  812. MappedPath: filepath.Join(os.TempDir(), "mapped_dir1"),
  813. Name: folderName + "1",
  814. },
  815. VirtualPath: "/vdir1/",
  816. QuotaSize: 0,
  817. QuotaFiles: -2, // invalid
  818. })
  819. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  820. assert.NoError(t, err)
  821. u.VirtualFolders = nil
  822. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  823. BaseVirtualFolder: vfs.BaseVirtualFolder{
  824. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  825. },
  826. VirtualPath: "/vdir1",
  827. })
  828. // folder name is mandatory
  829. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  830. assert.NoError(t, err)
  831. u.VirtualFolders = nil
  832. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  833. BaseVirtualFolder: vfs.BaseVirtualFolder{
  834. Name: "aa=a", // char not allowed
  835. MappedPath: filepath.Join(os.TempDir(), "mapped_dir"),
  836. },
  837. VirtualPath: "/vdir1",
  838. })
  839. _, _, err = httpdtest.AddUser(u, http.StatusBadRequest)
  840. assert.NoError(t, err)
  841. }
  842. func TestUserPublicKey(t *testing.T) {
  843. u := getTestUser()
  844. invalidPubKey := "invalid"
  845. validPubKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  846. u.PublicKeys = []string{invalidPubKey}
  847. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  848. assert.NoError(t, err)
  849. u.PublicKeys = []string{validPubKey}
  850. user, _, err := httpdtest.AddUser(u, http.StatusCreated)
  851. assert.NoError(t, err)
  852. user.PublicKeys = []string{validPubKey, invalidPubKey}
  853. _, _, err = httpdtest.UpdateUser(user, http.StatusBadRequest, "")
  854. assert.NoError(t, err)
  855. user.PublicKeys = []string{validPubKey, validPubKey, validPubKey}
  856. _, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  857. assert.NoError(t, err)
  858. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  859. assert.NoError(t, err)
  860. }
  861. func TestUpdateUser(t *testing.T) {
  862. u := getTestUser()
  863. u.UsedQuotaFiles = 1
  864. u.UsedQuotaSize = 2
  865. user, _, err := httpdtest.AddUser(u, http.StatusCreated)
  866. assert.NoError(t, err)
  867. assert.Equal(t, 0, user.UsedQuotaFiles)
  868. assert.Equal(t, int64(0), user.UsedQuotaSize)
  869. user.HomeDir = filepath.Join(homeBasePath, "testmod")
  870. user.UID = 33
  871. user.GID = 101
  872. user.MaxSessions = 10
  873. user.QuotaSize = 4096
  874. user.QuotaFiles = 2
  875. user.Permissions["/"] = []string{dataprovider.PermCreateDirs, dataprovider.PermDelete, dataprovider.PermDownload}
  876. user.Permissions["/subdir"] = []string{dataprovider.PermListItems, dataprovider.PermUpload}
  877. user.Filters.AllowedIP = []string{"192.168.1.0/24", "192.168.2.0/24"}
  878. user.Filters.DeniedIP = []string{"192.168.3.0/24", "192.168.4.0/24"}
  879. user.Filters.DeniedLoginMethods = []string{dataprovider.LoginMethodPassword}
  880. user.Filters.DeniedProtocols = []string{common.ProtocolWebDAV}
  881. user.Filters.FileExtensions = append(user.Filters.FileExtensions, dataprovider.ExtensionsFilter{
  882. Path: "/subdir",
  883. AllowedExtensions: []string{".zip", ".rar"},
  884. DeniedExtensions: []string{".jpg", ".png"},
  885. })
  886. user.Filters.FilePatterns = append(user.Filters.FilePatterns, dataprovider.PatternsFilter{
  887. Path: "/subdir",
  888. AllowedPatterns: []string{"*.zip", "*.rar"},
  889. DeniedPatterns: []string{"*.jpg", "*.png"},
  890. })
  891. user.Filters.MaxUploadFileSize = 4096
  892. user.UploadBandwidth = 1024
  893. user.DownloadBandwidth = 512
  894. user.VirtualFolders = nil
  895. mappedPath1 := filepath.Join(os.TempDir(), "mapped_dir1")
  896. mappedPath2 := filepath.Join(os.TempDir(), "mapped_dir2")
  897. folderName1 := filepath.Base(mappedPath1)
  898. folderName2 := filepath.Base(mappedPath2)
  899. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  900. BaseVirtualFolder: vfs.BaseVirtualFolder{
  901. Name: folderName1,
  902. MappedPath: mappedPath1,
  903. },
  904. VirtualPath: "/vdir1",
  905. })
  906. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  907. BaseVirtualFolder: vfs.BaseVirtualFolder{
  908. Name: folderName2,
  909. MappedPath: mappedPath2,
  910. },
  911. VirtualPath: "/vdir12/subdir",
  912. QuotaSize: 123,
  913. QuotaFiles: 2,
  914. })
  915. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  916. assert.NoError(t, err)
  917. _, _, err = httpdtest.UpdateUser(user, http.StatusBadRequest, "invalid")
  918. assert.NoError(t, err)
  919. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "0")
  920. assert.NoError(t, err)
  921. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "1")
  922. assert.NoError(t, err)
  923. user.Permissions["/subdir"] = []string{}
  924. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  925. assert.NoError(t, err)
  926. assert.Len(t, user.Permissions["/subdir"], 0)
  927. assert.Len(t, user.VirtualFolders, 2)
  928. for _, folder := range user.VirtualFolders {
  929. assert.Greater(t, folder.ID, int64(0))
  930. if folder.VirtualPath == "/vdir12/subdir" {
  931. assert.Equal(t, int64(123), folder.QuotaSize)
  932. assert.Equal(t, 2, folder.QuotaFiles)
  933. }
  934. }
  935. folder, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
  936. assert.NoError(t, err)
  937. assert.Len(t, folder.Users, 1)
  938. assert.Contains(t, folder.Users, user.Username)
  939. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  940. assert.NoError(t, err)
  941. // removing the user must remove folder mapping
  942. folder, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
  943. assert.NoError(t, err)
  944. assert.Len(t, folder.Users, 0)
  945. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  946. assert.NoError(t, err)
  947. folder, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
  948. assert.NoError(t, err)
  949. assert.Len(t, folder.Users, 0)
  950. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  951. assert.NoError(t, err)
  952. }
  953. func TestUpdateUserQuotaUsage(t *testing.T) {
  954. u := getTestUser()
  955. usedQuotaFiles := 1
  956. usedQuotaSize := int64(65535)
  957. u.UsedQuotaFiles = usedQuotaFiles
  958. u.UsedQuotaSize = usedQuotaSize
  959. user, _, err := httpdtest.AddUser(u, http.StatusCreated)
  960. assert.NoError(t, err)
  961. _, err = httpdtest.UpdateQuotaUsage(u, "invalid_mode", http.StatusBadRequest)
  962. assert.NoError(t, err)
  963. _, err = httpdtest.UpdateQuotaUsage(u, "", http.StatusOK)
  964. assert.NoError(t, err)
  965. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  966. assert.NoError(t, err)
  967. assert.Equal(t, usedQuotaFiles, user.UsedQuotaFiles)
  968. assert.Equal(t, usedQuotaSize, user.UsedQuotaSize)
  969. _, err = httpdtest.UpdateQuotaUsage(u, "add", http.StatusBadRequest)
  970. assert.NoError(t, err, "user has no quota restrictions add mode should fail")
  971. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  972. assert.NoError(t, err)
  973. assert.Equal(t, usedQuotaFiles, user.UsedQuotaFiles)
  974. assert.Equal(t, usedQuotaSize, user.UsedQuotaSize)
  975. user.QuotaFiles = 100
  976. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  977. assert.NoError(t, err)
  978. _, err = httpdtest.UpdateQuotaUsage(u, "add", http.StatusOK)
  979. assert.NoError(t, err)
  980. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  981. assert.NoError(t, err)
  982. assert.Equal(t, 2*usedQuotaFiles, user.UsedQuotaFiles)
  983. assert.Equal(t, 2*usedQuotaSize, user.UsedQuotaSize)
  984. u.UsedQuotaFiles = -1
  985. _, err = httpdtest.UpdateQuotaUsage(u, "", http.StatusBadRequest)
  986. assert.NoError(t, err)
  987. u.UsedQuotaFiles = usedQuotaFiles
  988. u.Username = u.Username + "1"
  989. _, err = httpdtest.UpdateQuotaUsage(u, "", http.StatusNotFound)
  990. assert.NoError(t, err)
  991. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  992. assert.NoError(t, err)
  993. }
  994. func TestUserFolderMapping(t *testing.T) {
  995. mappedPath1 := filepath.Join(os.TempDir(), "mapped_dir1")
  996. mappedPath2 := filepath.Join(os.TempDir(), "mapped_dir2")
  997. folderName1 := filepath.Base(mappedPath1)
  998. folderName2 := filepath.Base(mappedPath2)
  999. u1 := getTestUser()
  1000. u1.VirtualFolders = append(u1.VirtualFolders, vfs.VirtualFolder{
  1001. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1002. Name: folderName1,
  1003. MappedPath: mappedPath1,
  1004. UsedQuotaFiles: 2,
  1005. UsedQuotaSize: 123,
  1006. },
  1007. VirtualPath: "/vdir",
  1008. QuotaSize: -1,
  1009. QuotaFiles: -1,
  1010. })
  1011. user1, _, err := httpdtest.AddUser(u1, http.StatusCreated)
  1012. assert.NoError(t, err)
  1013. // virtual folder must be auto created
  1014. folder, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
  1015. assert.NoError(t, err)
  1016. assert.Len(t, folder.Users, 1)
  1017. assert.Contains(t, folder.Users, user1.Username)
  1018. assert.Equal(t, 0, folder.UsedQuotaFiles)
  1019. assert.Equal(t, int64(0), folder.UsedQuotaSize)
  1020. u2 := getTestUser()
  1021. u2.Username = defaultUsername + "2"
  1022. u2.VirtualFolders = append(u2.VirtualFolders, vfs.VirtualFolder{
  1023. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1024. Name: folderName1,
  1025. MappedPath: mappedPath1,
  1026. },
  1027. VirtualPath: "/vdir1",
  1028. QuotaSize: 0,
  1029. QuotaFiles: 0,
  1030. })
  1031. u2.VirtualFolders = append(u2.VirtualFolders, vfs.VirtualFolder{
  1032. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1033. Name: folderName2,
  1034. MappedPath: mappedPath2,
  1035. },
  1036. VirtualPath: "/vdir2",
  1037. QuotaSize: -1,
  1038. QuotaFiles: -1,
  1039. })
  1040. user2, _, err := httpdtest.AddUser(u2, http.StatusCreated)
  1041. assert.NoError(t, err)
  1042. folder, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
  1043. assert.NoError(t, err)
  1044. assert.Len(t, folder.Users, 1)
  1045. assert.Contains(t, folder.Users, user2.Username)
  1046. folder, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
  1047. assert.NoError(t, err)
  1048. assert.Len(t, folder.Users, 2)
  1049. assert.Contains(t, folder.Users, user1.Username)
  1050. assert.Contains(t, folder.Users, user2.Username)
  1051. // now update user2 removing mappedPath1
  1052. user2.VirtualFolders = nil
  1053. user2.VirtualFolders = append(user2.VirtualFolders, vfs.VirtualFolder{
  1054. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1055. Name: folderName2,
  1056. MappedPath: mappedPath2,
  1057. UsedQuotaFiles: 2,
  1058. UsedQuotaSize: 123,
  1059. },
  1060. VirtualPath: "/vdir",
  1061. QuotaSize: 0,
  1062. QuotaFiles: 0,
  1063. })
  1064. user2, _, err = httpdtest.UpdateUser(user2, http.StatusOK, "")
  1065. assert.NoError(t, err)
  1066. folder, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
  1067. assert.NoError(t, err)
  1068. assert.Len(t, folder.Users, 1)
  1069. assert.Contains(t, folder.Users, user2.Username)
  1070. assert.Equal(t, 0, folder.UsedQuotaFiles)
  1071. assert.Equal(t, int64(0), folder.UsedQuotaSize)
  1072. folder, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
  1073. assert.NoError(t, err)
  1074. assert.Len(t, folder.Users, 1)
  1075. assert.Contains(t, folder.Users, user1.Username)
  1076. // add mappedPath1 again to user2
  1077. user2.VirtualFolders = append(user2.VirtualFolders, vfs.VirtualFolder{
  1078. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1079. Name: folderName1,
  1080. MappedPath: mappedPath1,
  1081. },
  1082. VirtualPath: "/vdir1",
  1083. })
  1084. user2, _, err = httpdtest.UpdateUser(user2, http.StatusOK, "")
  1085. assert.NoError(t, err)
  1086. folder, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
  1087. assert.NoError(t, err)
  1088. assert.Len(t, folder.Users, 1)
  1089. assert.Contains(t, folder.Users, user2.Username)
  1090. // removing virtual folders should clear relations on both side
  1091. _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
  1092. assert.NoError(t, err)
  1093. user2, _, err = httpdtest.GetUserByUsername(user2.Username, http.StatusOK)
  1094. assert.NoError(t, err)
  1095. if assert.Len(t, user2.VirtualFolders, 1) {
  1096. folder := user2.VirtualFolders[0]
  1097. assert.Equal(t, mappedPath1, folder.MappedPath)
  1098. assert.Equal(t, folderName1, folder.Name)
  1099. }
  1100. user1, _, err = httpdtest.GetUserByUsername(user1.Username, http.StatusOK)
  1101. assert.NoError(t, err)
  1102. if assert.Len(t, user2.VirtualFolders, 1) {
  1103. folder := user2.VirtualFolders[0]
  1104. assert.Equal(t, mappedPath1, folder.MappedPath)
  1105. }
  1106. folder, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
  1107. assert.NoError(t, err)
  1108. assert.Len(t, folder.Users, 2)
  1109. // removing a user should clear virtual folder mapping
  1110. _, err = httpdtest.RemoveUser(user1, http.StatusOK)
  1111. assert.NoError(t, err)
  1112. folder, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
  1113. assert.NoError(t, err)
  1114. assert.Len(t, folder.Users, 1)
  1115. assert.Contains(t, folder.Users, user2.Username)
  1116. // removing a folder should clear mapping on the user side too
  1117. _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
  1118. assert.NoError(t, err)
  1119. user2, _, err = httpdtest.GetUserByUsername(user2.Username, http.StatusOK)
  1120. assert.NoError(t, err)
  1121. assert.Len(t, user2.VirtualFolders, 0)
  1122. _, err = httpdtest.RemoveUser(user2, http.StatusOK)
  1123. assert.NoError(t, err)
  1124. }
  1125. func TestUserS3Config(t *testing.T) {
  1126. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1127. assert.NoError(t, err)
  1128. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1129. user.FsConfig.S3Config.Bucket = "test" //nolint:goconst
  1130. user.FsConfig.S3Config.Region = "us-east-1" //nolint:goconst
  1131. user.FsConfig.S3Config.AccessKey = "Server-Access-Key"
  1132. user.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("Server-Access-Secret")
  1133. user.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000"
  1134. user.FsConfig.S3Config.UploadPartSize = 8
  1135. user, body, err := httpdtest.UpdateUser(user, http.StatusOK, "")
  1136. assert.NoError(t, err, string(body))
  1137. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.S3Config.AccessSecret.GetStatus())
  1138. assert.NotEmpty(t, user.FsConfig.S3Config.AccessSecret.GetPayload())
  1139. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1140. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetKey())
  1141. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1142. assert.NoError(t, err)
  1143. user.Password = defaultPassword
  1144. user.ID = 0
  1145. secret := kms.NewSecret(kms.SecretStatusSecretBox, "Server-Access-Secret", "", "")
  1146. user.FsConfig.S3Config.AccessSecret = secret
  1147. _, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1148. assert.Error(t, err)
  1149. user.FsConfig.S3Config.AccessSecret.SetStatus(kms.SecretStatusPlain)
  1150. user, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1151. assert.NoError(t, err)
  1152. initialSecretPayload := user.FsConfig.S3Config.AccessSecret.GetPayload()
  1153. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.S3Config.AccessSecret.GetStatus())
  1154. assert.NotEmpty(t, initialSecretPayload)
  1155. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1156. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetKey())
  1157. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1158. user.FsConfig.S3Config.Bucket = "test-bucket"
  1159. user.FsConfig.S3Config.Region = "us-east-1" //nolint:goconst
  1160. user.FsConfig.S3Config.AccessKey = "Server-Access-Key1"
  1161. user.FsConfig.S3Config.Endpoint = "http://localhost:9000"
  1162. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir" //nolint:goconst
  1163. user.FsConfig.S3Config.UploadConcurrency = 5
  1164. user, bb, err := httpdtest.UpdateUser(user, http.StatusOK, "")
  1165. assert.NoError(t, err, string(bb))
  1166. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.S3Config.AccessSecret.GetStatus())
  1167. assert.Equal(t, initialSecretPayload, user.FsConfig.S3Config.AccessSecret.GetPayload())
  1168. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1169. assert.Empty(t, user.FsConfig.S3Config.AccessSecret.GetKey())
  1170. // test user without access key and access secret (shared config state)
  1171. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1172. user.FsConfig.S3Config.Bucket = "testbucket"
  1173. user.FsConfig.S3Config.Region = "us-east-1"
  1174. user.FsConfig.S3Config.AccessKey = ""
  1175. user.FsConfig.S3Config.AccessSecret = kms.NewEmptySecret()
  1176. user.FsConfig.S3Config.Endpoint = ""
  1177. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  1178. user.FsConfig.S3Config.UploadPartSize = 6
  1179. user.FsConfig.S3Config.UploadConcurrency = 4
  1180. user, body, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1181. assert.NoError(t, err, string(body))
  1182. assert.True(t, user.FsConfig.S3Config.AccessSecret.IsEmpty())
  1183. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1184. assert.NoError(t, err)
  1185. user.Password = defaultPassword
  1186. user.ID = 0
  1187. // shared credential test for add instead of update
  1188. user, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1189. assert.NoError(t, err)
  1190. assert.True(t, user.FsConfig.S3Config.AccessSecret.IsEmpty())
  1191. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1192. assert.NoError(t, err)
  1193. }
  1194. func TestUserGCSConfig(t *testing.T) {
  1195. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1196. assert.NoError(t, err)
  1197. err = os.RemoveAll(credentialsPath)
  1198. assert.NoError(t, err)
  1199. err = os.MkdirAll(credentialsPath, 0700)
  1200. assert.NoError(t, err)
  1201. user.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  1202. user.FsConfig.GCSConfig.Bucket = "test"
  1203. user.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("fake credentials") //nolint:goconst
  1204. user, bb, err := httpdtest.UpdateUser(user, http.StatusOK, "")
  1205. assert.NoError(t, err, string(bb))
  1206. credentialFile := filepath.Join(credentialsPath, fmt.Sprintf("%v_gcs_credentials.json", user.Username))
  1207. assert.FileExists(t, credentialFile)
  1208. creds, err := ioutil.ReadFile(credentialFile)
  1209. assert.NoError(t, err)
  1210. secret := kms.NewEmptySecret()
  1211. err = json.Unmarshal(creds, secret)
  1212. assert.NoError(t, err)
  1213. err = secret.Decrypt()
  1214. assert.NoError(t, err)
  1215. assert.Equal(t, "fake credentials", secret.GetPayload())
  1216. user.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusSecretBox, "fake encrypted credentials", "", "")
  1217. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1218. assert.NoError(t, err)
  1219. assert.FileExists(t, credentialFile)
  1220. creds, err = ioutil.ReadFile(credentialFile)
  1221. assert.NoError(t, err)
  1222. secret = kms.NewEmptySecret()
  1223. err = json.Unmarshal(creds, secret)
  1224. assert.NoError(t, err)
  1225. err = secret.Decrypt()
  1226. assert.NoError(t, err)
  1227. assert.Equal(t, "fake credentials", secret.GetPayload())
  1228. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1229. assert.NoError(t, err)
  1230. user.Password = defaultPassword
  1231. user.ID = 0
  1232. user.FsConfig.GCSConfig.Credentials = kms.NewSecret(kms.SecretStatusSecretBox, "fake credentials", "", "")
  1233. _, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1234. assert.Error(t, err)
  1235. user.FsConfig.GCSConfig.Credentials.SetStatus(kms.SecretStatusPlain)
  1236. user, body, err := httpdtest.AddUser(user, http.StatusCreated)
  1237. assert.NoError(t, err, string(body))
  1238. err = os.RemoveAll(credentialsPath)
  1239. assert.NoError(t, err)
  1240. err = os.MkdirAll(credentialsPath, 0700)
  1241. assert.NoError(t, err)
  1242. user.FsConfig.GCSConfig.Credentials = kms.NewEmptySecret()
  1243. user.FsConfig.GCSConfig.AutomaticCredentials = 1
  1244. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1245. assert.NoError(t, err)
  1246. assert.NoFileExists(t, credentialFile)
  1247. user.FsConfig.GCSConfig = vfs.GCSFsConfig{}
  1248. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1249. user.FsConfig.S3Config.Bucket = "test1"
  1250. user.FsConfig.S3Config.Region = "us-east-1"
  1251. user.FsConfig.S3Config.AccessKey = "Server-Access-Key1"
  1252. user.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("secret")
  1253. user.FsConfig.S3Config.Endpoint = "http://localhost:9000"
  1254. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
  1255. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1256. assert.NoError(t, err)
  1257. user.FsConfig.S3Config = vfs.S3FsConfig{}
  1258. user.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  1259. user.FsConfig.GCSConfig.Bucket = "test1"
  1260. user.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("fake credentials")
  1261. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1262. assert.NoError(t, err)
  1263. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1264. assert.NoError(t, err)
  1265. }
  1266. func TestUserAzureBlobConfig(t *testing.T) {
  1267. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1268. assert.NoError(t, err)
  1269. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1270. user.FsConfig.AzBlobConfig.Container = "test"
  1271. user.FsConfig.AzBlobConfig.AccountName = "Server-Account-Name"
  1272. user.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("Server-Account-Key")
  1273. user.FsConfig.AzBlobConfig.Endpoint = "http://127.0.0.1:9000"
  1274. user.FsConfig.AzBlobConfig.UploadPartSize = 8
  1275. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1276. assert.NoError(t, err)
  1277. initialPayload := user.FsConfig.AzBlobConfig.AccountKey.GetPayload()
  1278. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1279. assert.NotEmpty(t, initialPayload)
  1280. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1281. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1282. user.FsConfig.AzBlobConfig.AccountKey.SetStatus(kms.SecretStatusSecretBox)
  1283. user.FsConfig.AzBlobConfig.AccountKey.SetAdditionalData("data")
  1284. user.FsConfig.AzBlobConfig.AccountKey.SetKey("fake key")
  1285. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1286. assert.NoError(t, err)
  1287. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1288. assert.Equal(t, initialPayload, user.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1289. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1290. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1291. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1292. assert.NoError(t, err)
  1293. user.Password = defaultPassword
  1294. user.ID = 0
  1295. secret := kms.NewSecret(kms.SecretStatusSecretBox, "Server-Account-Key", "", "")
  1296. user.FsConfig.AzBlobConfig.AccountKey = secret
  1297. _, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1298. assert.Error(t, err)
  1299. user.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("Server-Account-Key-Test")
  1300. user, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1301. assert.NoError(t, err)
  1302. initialPayload = user.FsConfig.AzBlobConfig.AccountKey.GetPayload()
  1303. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1304. assert.NotEmpty(t, initialPayload)
  1305. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1306. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1307. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1308. user.FsConfig.AzBlobConfig.Container = "test-container"
  1309. user.FsConfig.AzBlobConfig.Endpoint = "http://localhost:9001"
  1310. user.FsConfig.AzBlobConfig.KeyPrefix = "somedir/subdir"
  1311. user.FsConfig.AzBlobConfig.UploadConcurrency = 5
  1312. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1313. assert.NoError(t, err)
  1314. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1315. assert.NotEmpty(t, initialPayload)
  1316. assert.Equal(t, initialPayload, user.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1317. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1318. assert.Empty(t, user.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1319. // test user without access key and access secret (sas)
  1320. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1321. 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"
  1322. user.FsConfig.AzBlobConfig.KeyPrefix = "somedir/subdir"
  1323. user.FsConfig.AzBlobConfig.AccountName = ""
  1324. user.FsConfig.AzBlobConfig.AccountKey = kms.NewEmptySecret()
  1325. user.FsConfig.AzBlobConfig.UploadPartSize = 6
  1326. user.FsConfig.AzBlobConfig.UploadConcurrency = 4
  1327. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1328. assert.NoError(t, err)
  1329. assert.True(t, user.FsConfig.AzBlobConfig.AccountKey.IsEmpty())
  1330. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1331. assert.NoError(t, err)
  1332. user.Password = defaultPassword
  1333. user.ID = 0
  1334. // sas test for add instead of update
  1335. user, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1336. assert.NoError(t, err)
  1337. assert.True(t, user.FsConfig.AzBlobConfig.AccountKey.IsEmpty())
  1338. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1339. assert.NoError(t, err)
  1340. }
  1341. func TestUserCryptFs(t *testing.T) {
  1342. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1343. assert.NoError(t, err)
  1344. user.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  1345. user.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("crypt passphrase")
  1346. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1347. assert.NoError(t, err)
  1348. initialPayload := user.FsConfig.CryptConfig.Passphrase.GetPayload()
  1349. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1350. assert.NotEmpty(t, initialPayload)
  1351. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1352. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1353. user.FsConfig.CryptConfig.Passphrase.SetStatus(kms.SecretStatusSecretBox)
  1354. user.FsConfig.CryptConfig.Passphrase.SetAdditionalData("data")
  1355. user.FsConfig.CryptConfig.Passphrase.SetKey("fake pass key")
  1356. user, bb, err := httpdtest.UpdateUser(user, http.StatusOK, "")
  1357. assert.NoError(t, err, string(bb))
  1358. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1359. assert.Equal(t, initialPayload, user.FsConfig.CryptConfig.Passphrase.GetPayload())
  1360. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1361. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1362. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1363. assert.NoError(t, err)
  1364. user.Password = defaultPassword
  1365. user.ID = 0
  1366. secret := kms.NewSecret(kms.SecretStatusSecretBox, "invalid encrypted payload", "", "")
  1367. user.FsConfig.CryptConfig.Passphrase = secret
  1368. _, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1369. assert.Error(t, err)
  1370. user.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("passphrase test")
  1371. user, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1372. assert.NoError(t, err)
  1373. initialPayload = user.FsConfig.CryptConfig.Passphrase.GetPayload()
  1374. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1375. assert.NotEmpty(t, initialPayload)
  1376. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1377. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1378. user.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  1379. user.FsConfig.CryptConfig.Passphrase.SetKey("pass")
  1380. user, bb, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1381. assert.NoError(t, err, string(bb))
  1382. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.CryptConfig.Passphrase.GetStatus())
  1383. assert.NotEmpty(t, initialPayload)
  1384. assert.Equal(t, initialPayload, user.FsConfig.CryptConfig.Passphrase.GetPayload())
  1385. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1386. assert.Empty(t, user.FsConfig.CryptConfig.Passphrase.GetKey())
  1387. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1388. assert.NoError(t, err)
  1389. }
  1390. func TestUserSFTPFs(t *testing.T) {
  1391. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1392. assert.NoError(t, err)
  1393. user.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  1394. user.FsConfig.SFTPConfig.Endpoint = "127.0.0.1:2022"
  1395. user.FsConfig.SFTPConfig.Username = "sftp_user"
  1396. user.FsConfig.SFTPConfig.Password = kms.NewPlainSecret("sftp_pwd")
  1397. user.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  1398. user.FsConfig.SFTPConfig.Fingerprints = []string{sftpPkeyFingerprint}
  1399. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1400. assert.NoError(t, err)
  1401. assert.Equal(t, "/", user.FsConfig.SFTPConfig.Prefix)
  1402. initialPwdPayload := user.FsConfig.SFTPConfig.Password.GetPayload()
  1403. initialPkeyPayload := user.FsConfig.SFTPConfig.PrivateKey.GetPayload()
  1404. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.Password.GetStatus())
  1405. assert.NotEmpty(t, initialPwdPayload)
  1406. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1407. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetKey())
  1408. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1409. assert.NotEmpty(t, initialPkeyPayload)
  1410. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1411. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1412. user.FsConfig.SFTPConfig.Password.SetStatus(kms.SecretStatusSecretBox)
  1413. user.FsConfig.SFTPConfig.Password.SetAdditionalData("adata")
  1414. user.FsConfig.SFTPConfig.Password.SetKey("fake pwd key")
  1415. user.FsConfig.SFTPConfig.PrivateKey.SetStatus(kms.SecretStatusSecretBox)
  1416. user.FsConfig.SFTPConfig.PrivateKey.SetAdditionalData("adata")
  1417. user.FsConfig.SFTPConfig.PrivateKey.SetKey("fake key")
  1418. user, bb, err := httpdtest.UpdateUser(user, http.StatusOK, "")
  1419. assert.NoError(t, err, string(bb))
  1420. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.Password.GetStatus())
  1421. assert.Equal(t, initialPwdPayload, user.FsConfig.SFTPConfig.Password.GetPayload())
  1422. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1423. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetKey())
  1424. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1425. assert.Equal(t, initialPkeyPayload, user.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1426. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1427. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1428. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1429. assert.NoError(t, err)
  1430. user.Password = defaultPassword
  1431. user.ID = 0
  1432. secret := kms.NewSecret(kms.SecretStatusSecretBox, "invalid encrypted payload", "", "")
  1433. user.FsConfig.SFTPConfig.Password = secret
  1434. _, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1435. assert.Error(t, err)
  1436. user.FsConfig.SFTPConfig.Password = kms.NewEmptySecret()
  1437. user.FsConfig.SFTPConfig.PrivateKey = secret
  1438. _, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1439. assert.Error(t, err)
  1440. user.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  1441. user, _, err = httpdtest.AddUser(user, http.StatusCreated)
  1442. assert.NoError(t, err)
  1443. initialPkeyPayload = user.FsConfig.SFTPConfig.PrivateKey.GetPayload()
  1444. assert.Empty(t, user.FsConfig.SFTPConfig.Password.GetStatus())
  1445. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1446. assert.NotEmpty(t, initialPkeyPayload)
  1447. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1448. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1449. user.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  1450. user.FsConfig.SFTPConfig.PrivateKey.SetKey("k")
  1451. user, bb, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1452. assert.NoError(t, err, string(bb))
  1453. assert.Equal(t, kms.SecretStatusSecretBox, user.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1454. assert.NotEmpty(t, initialPkeyPayload)
  1455. assert.Equal(t, initialPkeyPayload, user.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1456. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1457. assert.Empty(t, user.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1458. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1459. assert.NoError(t, err)
  1460. }
  1461. func TestUserHiddenFields(t *testing.T) {
  1462. err := dataprovider.Close()
  1463. assert.NoError(t, err)
  1464. err = config.LoadConfig(configDir, "")
  1465. assert.NoError(t, err)
  1466. providerConf := config.GetProviderConf()
  1467. providerConf.PreferDatabaseCredentials = true
  1468. err = dataprovider.Initialize(providerConf, configDir, true)
  1469. assert.NoError(t, err)
  1470. // sensitive data must be hidden but not deleted from the dataprovider
  1471. usernames := []string{"user1", "user2", "user3", "user4", "user5"}
  1472. u1 := getTestUser()
  1473. u1.Username = usernames[0]
  1474. u1.FsConfig.Provider = dataprovider.S3FilesystemProvider
  1475. u1.FsConfig.S3Config.Bucket = "test"
  1476. u1.FsConfig.S3Config.Region = "us-east-1"
  1477. u1.FsConfig.S3Config.AccessKey = "S3-Access-Key"
  1478. u1.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("S3-Access-Secret")
  1479. user1, _, err := httpdtest.AddUser(u1, http.StatusCreated)
  1480. assert.NoError(t, err)
  1481. u2 := getTestUser()
  1482. u2.Username = usernames[1]
  1483. u2.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  1484. u2.FsConfig.GCSConfig.Bucket = "test"
  1485. u2.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("fake credentials")
  1486. user2, _, err := httpdtest.AddUser(u2, http.StatusCreated)
  1487. assert.NoError(t, err)
  1488. u3 := getTestUser()
  1489. u3.Username = usernames[2]
  1490. u3.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  1491. u3.FsConfig.AzBlobConfig.Container = "test"
  1492. u3.FsConfig.AzBlobConfig.AccountName = "Server-Account-Name"
  1493. u3.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("Server-Account-Key")
  1494. user3, _, err := httpdtest.AddUser(u3, http.StatusCreated)
  1495. assert.NoError(t, err)
  1496. u4 := getTestUser()
  1497. u4.Username = usernames[3]
  1498. u4.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  1499. u4.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("test passphrase")
  1500. user4, _, err := httpdtest.AddUser(u4, http.StatusCreated)
  1501. assert.NoError(t, err)
  1502. u5 := getTestUser()
  1503. u5.Username = usernames[4]
  1504. u5.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  1505. u5.FsConfig.SFTPConfig.Endpoint = "127.0.0.1:2022"
  1506. u5.FsConfig.SFTPConfig.Username = "sftp_user"
  1507. u5.FsConfig.SFTPConfig.Password = kms.NewPlainSecret("apassword")
  1508. u5.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  1509. u5.FsConfig.SFTPConfig.Fingerprints = []string{sftpPkeyFingerprint}
  1510. u5.FsConfig.SFTPConfig.Prefix = "/prefix"
  1511. user5, _, err := httpdtest.AddUser(u5, http.StatusCreated)
  1512. assert.NoError(t, err)
  1513. users, _, err := httpdtest.GetUsers(0, 0, http.StatusOK)
  1514. assert.NoError(t, err)
  1515. assert.GreaterOrEqual(t, len(users), 5)
  1516. for _, username := range usernames {
  1517. user, _, err := httpdtest.GetUserByUsername(username, http.StatusOK)
  1518. assert.NoError(t, err)
  1519. assert.Empty(t, user.Password)
  1520. }
  1521. user1, _, err = httpdtest.GetUserByUsername(user1.Username, http.StatusOK)
  1522. assert.NoError(t, err)
  1523. assert.Empty(t, user1.Password)
  1524. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetKey())
  1525. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1526. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetStatus())
  1527. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetPayload())
  1528. user2, _, err = httpdtest.GetUserByUsername(user2.Username, http.StatusOK)
  1529. assert.NoError(t, err)
  1530. assert.Empty(t, user2.Password)
  1531. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetKey())
  1532. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetAdditionalData())
  1533. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetStatus())
  1534. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetPayload())
  1535. user3, _, err = httpdtest.GetUserByUsername(user3.Username, http.StatusOK)
  1536. assert.NoError(t, err)
  1537. assert.Empty(t, user3.Password)
  1538. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1539. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1540. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1541. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1542. user4, _, err = httpdtest.GetUserByUsername(user4.Username, http.StatusOK)
  1543. assert.NoError(t, err)
  1544. assert.Empty(t, user4.Password)
  1545. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetKey())
  1546. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1547. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetStatus())
  1548. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetPayload())
  1549. user5, _, err = httpdtest.GetUserByUsername(user5.Username, http.StatusOK)
  1550. assert.NoError(t, err)
  1551. assert.Empty(t, user5.Password)
  1552. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetKey())
  1553. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1554. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetStatus())
  1555. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetPayload())
  1556. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1557. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1558. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1559. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1560. assert.Equal(t, "/prefix", user5.FsConfig.SFTPConfig.Prefix)
  1561. // finally check that we have all the data inside the data provider
  1562. user1, err = dataprovider.UserExists(user1.Username)
  1563. assert.NoError(t, err)
  1564. assert.NotEmpty(t, user1.Password)
  1565. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetKey())
  1566. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1567. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetStatus())
  1568. assert.NotEmpty(t, user1.FsConfig.S3Config.AccessSecret.GetPayload())
  1569. err = user1.FsConfig.S3Config.AccessSecret.Decrypt()
  1570. assert.NoError(t, err)
  1571. assert.Equal(t, kms.SecretStatusPlain, user1.FsConfig.S3Config.AccessSecret.GetStatus())
  1572. assert.Equal(t, u1.FsConfig.S3Config.AccessSecret.GetPayload(), user1.FsConfig.S3Config.AccessSecret.GetPayload())
  1573. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetKey())
  1574. assert.Empty(t, user1.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  1575. user2, err = dataprovider.UserExists(user2.Username)
  1576. assert.NoError(t, err)
  1577. assert.NotEmpty(t, user2.Password)
  1578. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetKey())
  1579. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetAdditionalData())
  1580. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetStatus())
  1581. assert.NotEmpty(t, user2.FsConfig.GCSConfig.Credentials.GetPayload())
  1582. err = user2.FsConfig.GCSConfig.Credentials.Decrypt()
  1583. assert.NoError(t, err)
  1584. assert.Equal(t, kms.SecretStatusPlain, user2.FsConfig.GCSConfig.Credentials.GetStatus())
  1585. assert.Equal(t, u2.FsConfig.GCSConfig.Credentials.GetPayload(), user2.FsConfig.GCSConfig.Credentials.GetPayload())
  1586. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetKey())
  1587. assert.Empty(t, user2.FsConfig.GCSConfig.Credentials.GetAdditionalData())
  1588. user3, err = dataprovider.UserExists(user3.Username)
  1589. assert.NoError(t, err)
  1590. assert.NotEmpty(t, user3.Password)
  1591. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1592. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1593. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1594. assert.NotEmpty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1595. err = user3.FsConfig.AzBlobConfig.AccountKey.Decrypt()
  1596. assert.NoError(t, err)
  1597. assert.Equal(t, kms.SecretStatusPlain, user3.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  1598. assert.Equal(t, u3.FsConfig.AzBlobConfig.AccountKey.GetPayload(), user3.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  1599. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetKey())
  1600. assert.Empty(t, user3.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  1601. user4, err = dataprovider.UserExists(user4.Username)
  1602. assert.NoError(t, err)
  1603. assert.NotEmpty(t, user4.Password)
  1604. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetKey())
  1605. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1606. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetStatus())
  1607. assert.NotEmpty(t, user4.FsConfig.CryptConfig.Passphrase.GetPayload())
  1608. err = user4.FsConfig.CryptConfig.Passphrase.Decrypt()
  1609. assert.NoError(t, err)
  1610. assert.Equal(t, kms.SecretStatusPlain, user4.FsConfig.CryptConfig.Passphrase.GetStatus())
  1611. assert.Equal(t, u4.FsConfig.CryptConfig.Passphrase.GetPayload(), user4.FsConfig.CryptConfig.Passphrase.GetPayload())
  1612. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetKey())
  1613. assert.Empty(t, user4.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  1614. user5, err = dataprovider.UserExists(user5.Username)
  1615. assert.NoError(t, err)
  1616. assert.NotEmpty(t, user5.Password)
  1617. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetKey())
  1618. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1619. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetStatus())
  1620. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.Password.GetPayload())
  1621. err = user5.FsConfig.SFTPConfig.Password.Decrypt()
  1622. assert.NoError(t, err)
  1623. assert.Equal(t, kms.SecretStatusPlain, user5.FsConfig.SFTPConfig.Password.GetStatus())
  1624. assert.Equal(t, u5.FsConfig.SFTPConfig.Password.GetPayload(), user5.FsConfig.SFTPConfig.Password.GetPayload())
  1625. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetKey())
  1626. assert.Empty(t, user5.FsConfig.SFTPConfig.Password.GetAdditionalData())
  1627. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1628. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1629. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1630. assert.NotEmpty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1631. err = user5.FsConfig.SFTPConfig.PrivateKey.Decrypt()
  1632. assert.NoError(t, err)
  1633. assert.Equal(t, kms.SecretStatusPlain, user5.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  1634. assert.Equal(t, u5.FsConfig.SFTPConfig.PrivateKey.GetPayload(), user5.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  1635. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetKey())
  1636. assert.Empty(t, user5.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  1637. _, err = httpdtest.RemoveUser(user1, http.StatusOK)
  1638. assert.NoError(t, err)
  1639. _, err = httpdtest.RemoveUser(user2, http.StatusOK)
  1640. assert.NoError(t, err)
  1641. _, err = httpdtest.RemoveUser(user3, http.StatusOK)
  1642. assert.NoError(t, err)
  1643. _, err = httpdtest.RemoveUser(user4, http.StatusOK)
  1644. assert.NoError(t, err)
  1645. _, err = httpdtest.RemoveUser(user5, http.StatusOK)
  1646. assert.NoError(t, err)
  1647. err = dataprovider.Close()
  1648. assert.NoError(t, err)
  1649. err = config.LoadConfig(configDir, "")
  1650. assert.NoError(t, err)
  1651. providerConf = config.GetProviderConf()
  1652. providerConf.CredentialsPath = credentialsPath
  1653. err = os.RemoveAll(credentialsPath)
  1654. assert.NoError(t, err)
  1655. err = dataprovider.Initialize(providerConf, configDir, true)
  1656. assert.NoError(t, err)
  1657. }
  1658. func TestSecretObject(t *testing.T) {
  1659. s := kms.NewPlainSecret("test data")
  1660. s.SetAdditionalData("username")
  1661. require.True(t, s.IsValid())
  1662. err := s.Encrypt()
  1663. require.NoError(t, err)
  1664. require.Equal(t, kms.SecretStatusSecretBox, s.GetStatus())
  1665. require.NotEmpty(t, s.GetPayload())
  1666. require.NotEmpty(t, s.GetKey())
  1667. require.True(t, s.IsValid())
  1668. err = s.Decrypt()
  1669. require.NoError(t, err)
  1670. require.Equal(t, kms.SecretStatusPlain, s.GetStatus())
  1671. require.Equal(t, "test data", s.GetPayload())
  1672. require.Empty(t, s.GetKey())
  1673. oldFormat := "$aes$5b97e3a3324a2f53e2357483383367c0$0ed3132b584742ab217866219da633266782b69b13e50ebc6ddfb7c4fbf2f2a414c6d5f813"
  1674. s, err = kms.GetSecretFromCompatString(oldFormat)
  1675. require.NoError(t, err)
  1676. require.True(t, s.IsValid())
  1677. require.Equal(t, kms.SecretStatusPlain, s.GetStatus())
  1678. require.Equal(t, "test data", s.GetPayload())
  1679. require.Empty(t, s.GetKey())
  1680. }
  1681. func TestSecretObjectCompatibility(t *testing.T) {
  1682. // this is manually tested against vault too
  1683. testPayload := "test payload"
  1684. s := kms.NewPlainSecret(testPayload)
  1685. require.True(t, s.IsValid())
  1686. err := s.Encrypt()
  1687. require.NoError(t, err)
  1688. localAsJSON, err := json.Marshal(s)
  1689. assert.NoError(t, err)
  1690. for _, secretStatus := range []string{kms.SecretStatusSecretBox} {
  1691. kmsConfig := config.GetKMSConfig()
  1692. assert.Empty(t, kmsConfig.Secrets.MasterKeyPath)
  1693. if secretStatus == kms.SecretStatusVaultTransit {
  1694. os.Setenv("VAULT_SERVER_URL", "http://127.0.0.1:8200")
  1695. os.Setenv("VAULT_SERVER_TOKEN", "s.9lYGq83MbgG5KR5kfebXVyhJ")
  1696. kmsConfig.Secrets.URL = "hashivault://mykey"
  1697. }
  1698. err := kmsConfig.Initialize()
  1699. assert.NoError(t, err)
  1700. // encrypt without a master key
  1701. secret := kms.NewPlainSecret(testPayload)
  1702. secret.SetAdditionalData("add data")
  1703. err = secret.Encrypt()
  1704. assert.NoError(t, err)
  1705. assert.Equal(t, 0, secret.GetMode())
  1706. secretClone := secret.Clone()
  1707. err = secretClone.Decrypt()
  1708. assert.NoError(t, err)
  1709. assert.Equal(t, testPayload, secretClone.GetPayload())
  1710. if secretStatus == kms.SecretStatusVaultTransit {
  1711. // decrypt the local secret now that the provider is vault
  1712. secretLocal := kms.NewEmptySecret()
  1713. err = json.Unmarshal(localAsJSON, secretLocal)
  1714. assert.NoError(t, err)
  1715. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1716. assert.Equal(t, 0, secretLocal.GetMode())
  1717. err = secretLocal.Decrypt()
  1718. assert.NoError(t, err)
  1719. assert.Equal(t, testPayload, secretLocal.GetPayload())
  1720. assert.Equal(t, kms.SecretStatusPlain, secretLocal.GetStatus())
  1721. err = secretLocal.Encrypt()
  1722. assert.NoError(t, err)
  1723. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1724. assert.Equal(t, 0, secretLocal.GetMode())
  1725. }
  1726. asJSON, err := json.Marshal(secret)
  1727. assert.NoError(t, err)
  1728. masterKeyPath := filepath.Join(os.TempDir(), "mkey")
  1729. err = ioutil.WriteFile(masterKeyPath, []byte("test key"), os.ModePerm)
  1730. assert.NoError(t, err)
  1731. config := kms.Configuration{
  1732. Secrets: kms.Secrets{
  1733. MasterKeyPath: masterKeyPath,
  1734. },
  1735. }
  1736. if secretStatus == kms.SecretStatusVaultTransit {
  1737. config.Secrets.URL = "hashivault://mykey"
  1738. }
  1739. err = config.Initialize()
  1740. assert.NoError(t, err)
  1741. // now build the secret from JSON
  1742. secret = kms.NewEmptySecret()
  1743. err = json.Unmarshal(asJSON, secret)
  1744. assert.NoError(t, err)
  1745. assert.Equal(t, 0, secret.GetMode())
  1746. err = secret.Decrypt()
  1747. assert.NoError(t, err)
  1748. assert.Equal(t, testPayload, secret.GetPayload())
  1749. err = secret.Encrypt()
  1750. assert.NoError(t, err)
  1751. assert.Equal(t, 1, secret.GetMode())
  1752. err = secret.Decrypt()
  1753. assert.NoError(t, err)
  1754. assert.Equal(t, testPayload, secret.GetPayload())
  1755. if secretStatus == kms.SecretStatusVaultTransit {
  1756. // decrypt the local secret encryped without a master key now that
  1757. // the provider is vault and a master key is set.
  1758. // The provider will not change, the master key will be used
  1759. secretLocal := kms.NewEmptySecret()
  1760. err = json.Unmarshal(localAsJSON, secretLocal)
  1761. assert.NoError(t, err)
  1762. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1763. assert.Equal(t, 0, secretLocal.GetMode())
  1764. err = secretLocal.Decrypt()
  1765. assert.NoError(t, err)
  1766. assert.Equal(t, testPayload, secretLocal.GetPayload())
  1767. assert.Equal(t, kms.SecretStatusPlain, secretLocal.GetStatus())
  1768. err = secretLocal.Encrypt()
  1769. assert.NoError(t, err)
  1770. assert.Equal(t, kms.SecretStatusSecretBox, secretLocal.GetStatus())
  1771. assert.Equal(t, 1, secretLocal.GetMode())
  1772. }
  1773. err = kmsConfig.Initialize()
  1774. assert.NoError(t, err)
  1775. err = os.Remove(masterKeyPath)
  1776. assert.NoError(t, err)
  1777. if secretStatus == kms.SecretStatusVaultTransit {
  1778. os.Unsetenv("VAULT_SERVER_URL")
  1779. os.Unsetenv("VAULT_SERVER_TOKEN")
  1780. }
  1781. }
  1782. }
  1783. func TestUpdateUserNoCredentials(t *testing.T) {
  1784. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1785. assert.NoError(t, err)
  1786. user.Password = ""
  1787. user.PublicKeys = []string{}
  1788. // password and public key will be omitted from json serialization if empty and so they will remain unchanged
  1789. // and no validation error will be raised
  1790. _, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  1791. assert.NoError(t, err)
  1792. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1793. assert.NoError(t, err)
  1794. }
  1795. func TestUpdateUserEmptyHomeDir(t *testing.T) {
  1796. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1797. assert.NoError(t, err)
  1798. user.HomeDir = ""
  1799. _, _, err = httpdtest.UpdateUser(user, http.StatusBadRequest, "")
  1800. assert.NoError(t, err)
  1801. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1802. assert.NoError(t, err)
  1803. }
  1804. func TestUpdateUserInvalidHomeDir(t *testing.T) {
  1805. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1806. assert.NoError(t, err)
  1807. user.HomeDir = "relative_path"
  1808. _, _, err = httpdtest.UpdateUser(user, http.StatusBadRequest, "")
  1809. assert.NoError(t, err)
  1810. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1811. assert.NoError(t, err)
  1812. }
  1813. func TestUpdateNonExistentUser(t *testing.T) {
  1814. _, _, err := httpdtest.UpdateUser(getTestUser(), http.StatusNotFound, "")
  1815. assert.NoError(t, err)
  1816. }
  1817. func TestGetNonExistentUser(t *testing.T) {
  1818. _, _, err := httpdtest.GetUserByUsername("na", http.StatusNotFound)
  1819. assert.NoError(t, err)
  1820. }
  1821. func TestDeleteNonExistentUser(t *testing.T) {
  1822. _, err := httpdtest.RemoveUser(getTestUser(), http.StatusNotFound)
  1823. assert.NoError(t, err)
  1824. }
  1825. func TestAddDuplicateUser(t *testing.T) {
  1826. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1827. assert.NoError(t, err)
  1828. _, _, err = httpdtest.AddUser(getTestUser(), http.StatusInternalServerError)
  1829. assert.NoError(t, err)
  1830. _, _, err = httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1831. assert.Error(t, err, "adding a duplicate user must fail")
  1832. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1833. assert.NoError(t, err)
  1834. }
  1835. func TestGetUsers(t *testing.T) {
  1836. user1, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1837. assert.NoError(t, err)
  1838. u := getTestUser()
  1839. u.Username = defaultUsername + "1"
  1840. user2, _, err := httpdtest.AddUser(u, http.StatusCreated)
  1841. assert.NoError(t, err)
  1842. users, _, err := httpdtest.GetUsers(0, 0, http.StatusOK)
  1843. assert.NoError(t, err)
  1844. assert.GreaterOrEqual(t, len(users), 2)
  1845. users, _, err = httpdtest.GetUsers(1, 0, http.StatusOK)
  1846. assert.NoError(t, err)
  1847. assert.Equal(t, 1, len(users))
  1848. users, _, err = httpdtest.GetUsers(1, 1, http.StatusOK)
  1849. assert.NoError(t, err)
  1850. assert.Equal(t, 1, len(users))
  1851. _, _, err = httpdtest.GetUsers(1, 1, http.StatusInternalServerError)
  1852. assert.Error(t, err)
  1853. _, err = httpdtest.RemoveUser(user1, http.StatusOK)
  1854. assert.NoError(t, err)
  1855. _, err = httpdtest.RemoveUser(user2, http.StatusOK)
  1856. assert.NoError(t, err)
  1857. }
  1858. func TestGetQuotaScans(t *testing.T) {
  1859. _, _, err := httpdtest.GetQuotaScans(http.StatusOK)
  1860. assert.NoError(t, err)
  1861. _, _, err = httpdtest.GetQuotaScans(http.StatusInternalServerError)
  1862. assert.Error(t, err)
  1863. _, _, err = httpdtest.GetFoldersQuotaScans(http.StatusOK)
  1864. assert.NoError(t, err)
  1865. _, _, err = httpdtest.GetFoldersQuotaScans(http.StatusInternalServerError)
  1866. assert.Error(t, err)
  1867. }
  1868. func TestStartQuotaScan(t *testing.T) {
  1869. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  1870. assert.NoError(t, err)
  1871. _, err = httpdtest.StartQuotaScan(user, http.StatusAccepted)
  1872. assert.NoError(t, err)
  1873. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1874. assert.NoError(t, err)
  1875. folder := vfs.BaseVirtualFolder{
  1876. Name: "vfolder",
  1877. MappedPath: filepath.Join(os.TempDir(), "folder"),
  1878. }
  1879. _, _, err = httpdtest.AddFolder(folder, http.StatusCreated)
  1880. assert.NoError(t, err)
  1881. _, err = httpdtest.StartFolderQuotaScan(folder, http.StatusAccepted)
  1882. assert.NoError(t, err)
  1883. for {
  1884. quotaScan, _, err := httpdtest.GetFoldersQuotaScans(http.StatusOK)
  1885. if !assert.NoError(t, err, "Error getting active scans") {
  1886. break
  1887. }
  1888. if len(quotaScan) == 0 {
  1889. break
  1890. }
  1891. time.Sleep(100 * time.Millisecond)
  1892. }
  1893. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  1894. assert.NoError(t, err)
  1895. }
  1896. func TestEmbeddedFolders(t *testing.T) {
  1897. u := getTestUser()
  1898. mappedPath := filepath.Join(os.TempDir(), "mapped_path")
  1899. name := filepath.Base(mappedPath)
  1900. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  1901. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1902. Name: name,
  1903. UsedQuotaFiles: 1000,
  1904. UsedQuotaSize: 8192,
  1905. LastQuotaUpdate: 123,
  1906. },
  1907. VirtualPath: "/vdir",
  1908. QuotaSize: 4096,
  1909. QuotaFiles: 1,
  1910. })
  1911. _, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
  1912. assert.NoError(t, err)
  1913. u.VirtualFolders[0].MappedPath = mappedPath
  1914. user, _, err := httpdtest.AddUser(u, http.StatusCreated)
  1915. assert.NoError(t, err)
  1916. // check that the folder was created
  1917. folder, _, err := httpdtest.GetFolderByName(name, http.StatusOK)
  1918. assert.NoError(t, err)
  1919. assert.Equal(t, mappedPath, folder.MappedPath)
  1920. assert.Equal(t, 0, folder.UsedQuotaFiles)
  1921. assert.Equal(t, int64(0), folder.UsedQuotaSize)
  1922. assert.Equal(t, int64(0), folder.LastQuotaUpdate)
  1923. if assert.Len(t, user.VirtualFolders, 1) {
  1924. assert.Equal(t, mappedPath, user.VirtualFolders[0].MappedPath)
  1925. assert.Equal(t, u.VirtualFolders[0].VirtualPath, user.VirtualFolders[0].VirtualPath)
  1926. assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user.VirtualFolders[0].QuotaFiles)
  1927. assert.Equal(t, u.VirtualFolders[0].QuotaSize, user.VirtualFolders[0].QuotaSize)
  1928. }
  1929. // if the folder already exists we can just reference it by name while adding/updating a user
  1930. u.Username = u.Username + "1"
  1931. u.VirtualFolders[0].MappedPath = ""
  1932. user1, _, err := httpdtest.AddUser(u, http.StatusCreated)
  1933. assert.EqualError(t, err, "Virtual folders mismatch")
  1934. if assert.Len(t, user1.VirtualFolders, 1) {
  1935. assert.Equal(t, mappedPath, user1.VirtualFolders[0].MappedPath)
  1936. assert.Equal(t, u.VirtualFolders[0].VirtualPath, user1.VirtualFolders[0].VirtualPath)
  1937. assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user1.VirtualFolders[0].QuotaFiles)
  1938. assert.Equal(t, u.VirtualFolders[0].QuotaSize, user1.VirtualFolders[0].QuotaSize)
  1939. }
  1940. user1.VirtualFolders = u.VirtualFolders
  1941. user1, _, err = httpdtest.UpdateUser(user1, http.StatusOK, "")
  1942. assert.EqualError(t, err, "Virtual folders mismatch")
  1943. if assert.Len(t, user1.VirtualFolders, 1) {
  1944. assert.Equal(t, mappedPath, user1.VirtualFolders[0].MappedPath)
  1945. assert.Equal(t, u.VirtualFolders[0].VirtualPath, user1.VirtualFolders[0].VirtualPath)
  1946. assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user1.VirtualFolders[0].QuotaFiles)
  1947. assert.Equal(t, u.VirtualFolders[0].QuotaSize, user1.VirtualFolders[0].QuotaSize)
  1948. }
  1949. // now the virtual folder contains all the required paths
  1950. user1, _, err = httpdtest.UpdateUser(user1, http.StatusOK, "")
  1951. assert.NoError(t, err)
  1952. if assert.Len(t, user1.VirtualFolders, 1) {
  1953. assert.Equal(t, mappedPath, user1.VirtualFolders[0].MappedPath)
  1954. assert.Equal(t, u.VirtualFolders[0].VirtualPath, user1.VirtualFolders[0].VirtualPath)
  1955. assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user1.VirtualFolders[0].QuotaFiles)
  1956. assert.Equal(t, u.VirtualFolders[0].QuotaSize, user1.VirtualFolders[0].QuotaSize)
  1957. }
  1958. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  1959. assert.NoError(t, err)
  1960. _, err = httpdtest.RemoveUser(user1, http.StatusOK)
  1961. assert.NoError(t, err)
  1962. _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: name}, http.StatusOK)
  1963. assert.NoError(t, err)
  1964. }
  1965. func TestUpdateFolderQuotaUsage(t *testing.T) {
  1966. f := vfs.BaseVirtualFolder{
  1967. Name: "vdir",
  1968. MappedPath: filepath.Join(os.TempDir(), "folder"),
  1969. }
  1970. usedQuotaFiles := 1
  1971. usedQuotaSize := int64(65535)
  1972. f.UsedQuotaFiles = usedQuotaFiles
  1973. f.UsedQuotaSize = usedQuotaSize
  1974. folder, _, err := httpdtest.AddFolder(f, http.StatusCreated)
  1975. if assert.NoError(t, err) {
  1976. assert.Equal(t, usedQuotaFiles, folder.UsedQuotaFiles)
  1977. assert.Equal(t, usedQuotaSize, folder.UsedQuotaSize)
  1978. }
  1979. _, err = httpdtest.UpdateFolderQuotaUsage(folder, "invalid mode", http.StatusBadRequest)
  1980. assert.NoError(t, err)
  1981. _, err = httpdtest.UpdateFolderQuotaUsage(f, "reset", http.StatusOK)
  1982. assert.NoError(t, err)
  1983. folder, _, err = httpdtest.GetFolderByName(f.Name, http.StatusOK)
  1984. assert.NoError(t, err)
  1985. assert.Equal(t, usedQuotaFiles, folder.UsedQuotaFiles)
  1986. assert.Equal(t, usedQuotaSize, folder.UsedQuotaSize)
  1987. _, err = httpdtest.UpdateFolderQuotaUsage(f, "add", http.StatusOK)
  1988. assert.NoError(t, err)
  1989. folder, _, err = httpdtest.GetFolderByName(f.Name, http.StatusOK)
  1990. assert.NoError(t, err)
  1991. assert.Equal(t, 2*usedQuotaFiles, folder.UsedQuotaFiles)
  1992. assert.Equal(t, 2*usedQuotaSize, folder.UsedQuotaSize)
  1993. f.UsedQuotaSize = -1
  1994. _, err = httpdtest.UpdateFolderQuotaUsage(f, "", http.StatusBadRequest)
  1995. assert.NoError(t, err)
  1996. f.UsedQuotaSize = usedQuotaSize
  1997. f.Name = f.Name + "1"
  1998. _, err = httpdtest.UpdateFolderQuotaUsage(f, "", http.StatusNotFound)
  1999. assert.NoError(t, err)
  2000. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  2001. assert.NoError(t, err)
  2002. }
  2003. func TestGetVersion(t *testing.T) {
  2004. _, _, err := httpdtest.GetVersion(http.StatusOK)
  2005. assert.NoError(t, err)
  2006. _, _, err = httpdtest.GetVersion(http.StatusInternalServerError)
  2007. assert.Error(t, err, "get version request must succeed, we requested to check a wrong status code")
  2008. }
  2009. func TestGetStatus(t *testing.T) {
  2010. _, _, err := httpdtest.GetStatus(http.StatusOK)
  2011. assert.NoError(t, err)
  2012. _, _, err = httpdtest.GetStatus(http.StatusBadRequest)
  2013. assert.Error(t, err, "get provider status request must succeed, we requested to check a wrong status code")
  2014. }
  2015. func TestGetConnections(t *testing.T) {
  2016. _, _, err := httpdtest.GetConnections(http.StatusOK)
  2017. assert.NoError(t, err)
  2018. _, _, err = httpdtest.GetConnections(http.StatusInternalServerError)
  2019. assert.Error(t, err, "get sftp connections request must succeed, we requested to check a wrong status code")
  2020. }
  2021. func TestCloseActiveConnection(t *testing.T) {
  2022. _, err := httpdtest.CloseConnection("non_existent_id", http.StatusNotFound)
  2023. assert.NoError(t, err)
  2024. user := getTestUser()
  2025. c := common.NewBaseConnection("connID", common.ProtocolSFTP, user, nil)
  2026. fakeConn := &fakeConnection{
  2027. BaseConnection: c,
  2028. }
  2029. common.Connections.Add(fakeConn)
  2030. _, err = httpdtest.CloseConnection(c.GetID(), http.StatusOK)
  2031. assert.NoError(t, err)
  2032. assert.Len(t, common.Connections.GetStats(), 0)
  2033. }
  2034. func TestCloseConnectionAfterUserUpdateDelete(t *testing.T) {
  2035. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  2036. assert.NoError(t, err)
  2037. c := common.NewBaseConnection("connID", common.ProtocolFTP, user, nil)
  2038. fakeConn := &fakeConnection{
  2039. BaseConnection: c,
  2040. }
  2041. common.Connections.Add(fakeConn)
  2042. c1 := common.NewBaseConnection("connID1", common.ProtocolSFTP, user, nil)
  2043. fakeConn1 := &fakeConnection{
  2044. BaseConnection: c1,
  2045. }
  2046. common.Connections.Add(fakeConn1)
  2047. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "0")
  2048. assert.NoError(t, err)
  2049. assert.Len(t, common.Connections.GetStats(), 2)
  2050. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "1")
  2051. assert.NoError(t, err)
  2052. assert.Len(t, common.Connections.GetStats(), 0)
  2053. common.Connections.Add(fakeConn)
  2054. common.Connections.Add(fakeConn1)
  2055. assert.Len(t, common.Connections.GetStats(), 2)
  2056. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  2057. assert.NoError(t, err)
  2058. assert.Len(t, common.Connections.GetStats(), 0)
  2059. }
  2060. func TestUserBaseDir(t *testing.T) {
  2061. err := dataprovider.Close()
  2062. assert.NoError(t, err)
  2063. err = config.LoadConfig(configDir, "")
  2064. assert.NoError(t, err)
  2065. providerConf := config.GetProviderConf()
  2066. providerConf.UsersBaseDir = homeBasePath
  2067. err = dataprovider.Initialize(providerConf, configDir, true)
  2068. assert.NoError(t, err)
  2069. u := getTestUser()
  2070. u.HomeDir = ""
  2071. user, _, err := httpdtest.AddUser(u, http.StatusCreated)
  2072. if assert.Error(t, err) {
  2073. assert.EqualError(t, err, "HomeDir mismatch")
  2074. }
  2075. assert.Equal(t, filepath.Join(providerConf.UsersBaseDir, u.Username), user.HomeDir)
  2076. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  2077. assert.NoError(t, err)
  2078. err = dataprovider.Close()
  2079. assert.NoError(t, err)
  2080. err = config.LoadConfig(configDir, "")
  2081. assert.NoError(t, err)
  2082. providerConf = config.GetProviderConf()
  2083. providerConf.CredentialsPath = credentialsPath
  2084. err = os.RemoveAll(credentialsPath)
  2085. assert.NoError(t, err)
  2086. err = dataprovider.Initialize(providerConf, configDir, true)
  2087. assert.NoError(t, err)
  2088. }
  2089. func TestQuotaTrackingDisabled(t *testing.T) {
  2090. err := dataprovider.Close()
  2091. assert.NoError(t, err)
  2092. err = config.LoadConfig(configDir, "")
  2093. assert.NoError(t, err)
  2094. providerConf := config.GetProviderConf()
  2095. providerConf.TrackQuota = 0
  2096. err = dataprovider.Initialize(providerConf, configDir, true)
  2097. assert.NoError(t, err)
  2098. // user quota scan must fail
  2099. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  2100. assert.NoError(t, err)
  2101. _, err = httpdtest.StartQuotaScan(user, http.StatusForbidden)
  2102. assert.NoError(t, err)
  2103. _, err = httpdtest.UpdateQuotaUsage(user, "", http.StatusForbidden)
  2104. assert.NoError(t, err)
  2105. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  2106. assert.NoError(t, err)
  2107. // folder quota scan must fail
  2108. folder := vfs.BaseVirtualFolder{
  2109. Name: "folder_quota_test",
  2110. MappedPath: filepath.Clean(os.TempDir()),
  2111. }
  2112. folder, resp, err := httpdtest.AddFolder(folder, http.StatusCreated)
  2113. assert.NoError(t, err, string(resp))
  2114. _, err = httpdtest.StartFolderQuotaScan(folder, http.StatusForbidden)
  2115. assert.NoError(t, err)
  2116. _, err = httpdtest.UpdateFolderQuotaUsage(folder, "", http.StatusForbidden)
  2117. assert.NoError(t, err)
  2118. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  2119. assert.NoError(t, err)
  2120. err = dataprovider.Close()
  2121. assert.NoError(t, err)
  2122. err = config.LoadConfig(configDir, "")
  2123. assert.NoError(t, err)
  2124. providerConf = config.GetProviderConf()
  2125. providerConf.CredentialsPath = credentialsPath
  2126. err = os.RemoveAll(credentialsPath)
  2127. assert.NoError(t, err)
  2128. err = dataprovider.Initialize(providerConf, configDir, true)
  2129. assert.NoError(t, err)
  2130. }
  2131. func TestProviderErrors(t *testing.T) {
  2132. token, _, err := httpdtest.GetToken(defaultTokenAuthUser, defaultTokenAuthPass)
  2133. assert.NoError(t, err)
  2134. testServerToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2135. assert.NoError(t, err)
  2136. httpdtest.SetJWTToken(token)
  2137. err = dataprovider.Close()
  2138. assert.NoError(t, err)
  2139. _, _, err = httpdtest.GetUserByUsername("na", http.StatusInternalServerError)
  2140. assert.NoError(t, err)
  2141. _, _, err = httpdtest.GetUsers(1, 0, http.StatusInternalServerError)
  2142. assert.NoError(t, err)
  2143. _, _, err = httpdtest.GetAdmins(1, 0, http.StatusInternalServerError)
  2144. assert.NoError(t, err)
  2145. _, _, err = httpdtest.UpdateUser(dataprovider.User{Username: "auser"}, http.StatusInternalServerError, "")
  2146. assert.NoError(t, err)
  2147. _, err = httpdtest.RemoveUser(dataprovider.User{Username: "auser"}, http.StatusInternalServerError)
  2148. assert.NoError(t, err)
  2149. _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: "aname"}, http.StatusInternalServerError)
  2150. assert.NoError(t, err)
  2151. status, _, err := httpdtest.GetStatus(http.StatusOK)
  2152. if assert.NoError(t, err) {
  2153. assert.False(t, status.DataProvider.IsActive)
  2154. }
  2155. _, _, err = httpdtest.Dumpdata("backup.json", "", "", http.StatusInternalServerError)
  2156. assert.NoError(t, err)
  2157. _, _, err = httpdtest.GetFolders(0, 0, http.StatusInternalServerError)
  2158. assert.NoError(t, err)
  2159. user := getTestUser()
  2160. user.ID = 1
  2161. backupData := dataprovider.BackupData{}
  2162. backupData.Users = append(backupData.Users, user)
  2163. backupContent, err := json.Marshal(backupData)
  2164. assert.NoError(t, err)
  2165. backupFilePath := filepath.Join(backupsPath, "backup.json")
  2166. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  2167. assert.NoError(t, err)
  2168. _, _, err = httpdtest.Loaddata(backupFilePath, "", "", http.StatusInternalServerError)
  2169. assert.NoError(t, err)
  2170. backupData.Folders = append(backupData.Folders, vfs.BaseVirtualFolder{Name: "testFolder", MappedPath: filepath.Clean(os.TempDir())})
  2171. backupContent, err = json.Marshal(backupData)
  2172. assert.NoError(t, err)
  2173. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  2174. assert.NoError(t, err)
  2175. _, _, err = httpdtest.Loaddata(backupFilePath, "", "", http.StatusInternalServerError)
  2176. assert.NoError(t, err)
  2177. backupData.Users = nil
  2178. backupData.Folders = nil
  2179. backupData.Admins = append(backupData.Admins, getTestAdmin())
  2180. backupContent, err = json.Marshal(backupData)
  2181. assert.NoError(t, err)
  2182. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  2183. assert.NoError(t, err)
  2184. _, _, err = httpdtest.Loaddata(backupFilePath, "", "", http.StatusInternalServerError)
  2185. assert.NoError(t, err)
  2186. err = os.Remove(backupFilePath)
  2187. assert.NoError(t, err)
  2188. req, err := http.NewRequest(http.MethodGet, webUserPath+"?clone-from=user", nil)
  2189. assert.NoError(t, err)
  2190. setJWTCookieForReq(req, testServerToken)
  2191. rr := executeRequest(req)
  2192. checkResponseCode(t, http.StatusInternalServerError, rr)
  2193. req, err = http.NewRequest(http.MethodGet, webTemplateUser+"?from=auser", nil)
  2194. assert.NoError(t, err)
  2195. setJWTCookieForReq(req, testServerToken)
  2196. rr = executeRequest(req)
  2197. checkResponseCode(t, http.StatusInternalServerError, rr)
  2198. err = config.LoadConfig(configDir, "")
  2199. assert.NoError(t, err)
  2200. providerConf := config.GetProviderConf()
  2201. providerConf.CredentialsPath = credentialsPath
  2202. err = os.RemoveAll(credentialsPath)
  2203. assert.NoError(t, err)
  2204. err = dataprovider.Initialize(providerConf, configDir, true)
  2205. assert.NoError(t, err)
  2206. httpdtest.SetJWTToken("")
  2207. }
  2208. func TestFolders(t *testing.T) {
  2209. folder := vfs.BaseVirtualFolder{
  2210. Name: "name",
  2211. MappedPath: "relative path",
  2212. Users: []string{"1", "2", "3"},
  2213. }
  2214. _, _, err := httpdtest.AddFolder(folder, http.StatusBadRequest)
  2215. assert.NoError(t, err)
  2216. folder.MappedPath = filepath.Clean(os.TempDir())
  2217. folder1, resp, err := httpdtest.AddFolder(folder, http.StatusCreated)
  2218. assert.EqualError(t, err, "folder users mismatch", string(resp))
  2219. assert.Equal(t, folder.Name, folder1.Name)
  2220. assert.Equal(t, folder.MappedPath, folder1.MappedPath)
  2221. assert.Equal(t, 0, folder1.UsedQuotaFiles)
  2222. assert.Equal(t, int64(0), folder1.UsedQuotaSize)
  2223. assert.Equal(t, int64(0), folder1.LastQuotaUpdate)
  2224. assert.Len(t, folder1.Users, 0)
  2225. // adding a duplicate folder must fail
  2226. _, _, err = httpdtest.AddFolder(folder, http.StatusCreated)
  2227. assert.Error(t, err)
  2228. folder.MappedPath = filepath.Join(os.TempDir(), "vfolder")
  2229. folder.Name = filepath.Base(folder.MappedPath)
  2230. folder.UsedQuotaFiles = 1
  2231. folder.UsedQuotaSize = 345
  2232. folder.LastQuotaUpdate = 10
  2233. folder2, _, err := httpdtest.AddFolder(folder, http.StatusCreated)
  2234. assert.EqualError(t, err, "folder users mismatch", string(resp))
  2235. assert.Equal(t, 1, folder2.UsedQuotaFiles)
  2236. assert.Equal(t, int64(345), folder2.UsedQuotaSize)
  2237. assert.Equal(t, int64(10), folder2.LastQuotaUpdate)
  2238. assert.Len(t, folder2.Users, 0)
  2239. folders, _, err := httpdtest.GetFolders(0, 0, http.StatusOK)
  2240. assert.NoError(t, err)
  2241. numResults := len(folders)
  2242. assert.GreaterOrEqual(t, numResults, 2)
  2243. folders, _, err = httpdtest.GetFolders(0, 1, http.StatusOK)
  2244. assert.NoError(t, err)
  2245. assert.Len(t, folders, numResults-1)
  2246. folders, _, err = httpdtest.GetFolders(1, 0, http.StatusOK)
  2247. assert.NoError(t, err)
  2248. assert.Len(t, folders, 1)
  2249. f, _, err := httpdtest.GetFolderByName(folder1.Name, http.StatusOK)
  2250. assert.NoError(t, err)
  2251. assert.Equal(t, folder1.Name, f.Name)
  2252. assert.Equal(t, folder1.MappedPath, f.MappedPath)
  2253. f, _, err = httpdtest.GetFolderByName(folder2.Name, http.StatusOK)
  2254. assert.NoError(t, err)
  2255. assert.Equal(t, folder2.Name, f.Name)
  2256. assert.Equal(t, folder2.MappedPath, f.MappedPath)
  2257. _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{
  2258. Name: "invalid",
  2259. }, http.StatusNotFound)
  2260. assert.NoError(t, err)
  2261. _, _, err = httpdtest.UpdateFolder(vfs.BaseVirtualFolder{Name: "notfound"}, http.StatusNotFound)
  2262. assert.NoError(t, err)
  2263. folder1.MappedPath = "a/relative/path"
  2264. _, _, err = httpdtest.UpdateFolder(folder1, http.StatusBadRequest)
  2265. assert.NoError(t, err)
  2266. folder1.MappedPath = filepath.Join(os.TempDir(), "updated")
  2267. f, _, err = httpdtest.UpdateFolder(folder1, http.StatusOK)
  2268. assert.NoError(t, err)
  2269. assert.Equal(t, folder1.MappedPath, f.MappedPath)
  2270. _, err = httpdtest.RemoveFolder(folder1, http.StatusOK)
  2271. assert.NoError(t, err)
  2272. _, err = httpdtest.RemoveFolder(folder2, http.StatusOK)
  2273. assert.NoError(t, err)
  2274. }
  2275. func TestDumpdata(t *testing.T) {
  2276. err := dataprovider.Close()
  2277. assert.NoError(t, err)
  2278. err = config.LoadConfig(configDir, "")
  2279. assert.NoError(t, err)
  2280. providerConf := config.GetProviderConf()
  2281. err = dataprovider.Initialize(providerConf, configDir, true)
  2282. assert.NoError(t, err)
  2283. _, _, err = httpdtest.Dumpdata("", "", "", http.StatusBadRequest)
  2284. assert.NoError(t, err)
  2285. _, _, err = httpdtest.Dumpdata(filepath.Join(backupsPath, "backup.json"), "", "", http.StatusBadRequest)
  2286. assert.NoError(t, err)
  2287. _, _, err = httpdtest.Dumpdata("../backup.json", "", "", http.StatusBadRequest)
  2288. assert.NoError(t, err)
  2289. _, _, err = httpdtest.Dumpdata("backup.json", "", "0", http.StatusOK)
  2290. assert.NoError(t, err)
  2291. response, _, err := httpdtest.Dumpdata("", "1", "0", http.StatusOK)
  2292. assert.NoError(t, err)
  2293. _, ok := response["admins"]
  2294. assert.True(t, ok)
  2295. _, ok = response["users"]
  2296. assert.True(t, ok)
  2297. _, ok = response["folders"]
  2298. assert.True(t, ok)
  2299. _, ok = response["version"]
  2300. assert.True(t, ok)
  2301. _, _, err = httpdtest.Dumpdata("backup.json", "", "1", http.StatusOK)
  2302. assert.NoError(t, err)
  2303. err = os.Remove(filepath.Join(backupsPath, "backup.json"))
  2304. assert.NoError(t, err)
  2305. if runtime.GOOS != "windows" {
  2306. err = os.Chmod(backupsPath, 0001)
  2307. assert.NoError(t, err)
  2308. _, _, err = httpdtest.Dumpdata("bck.json", "", "", http.StatusInternalServerError)
  2309. assert.NoError(t, err)
  2310. // subdir cannot be created
  2311. _, _, err = httpdtest.Dumpdata(filepath.Join("subdir", "bck.json"), "", "", http.StatusInternalServerError)
  2312. assert.NoError(t, err)
  2313. err = os.Chmod(backupsPath, 0755)
  2314. assert.NoError(t, err)
  2315. }
  2316. err = dataprovider.Close()
  2317. assert.NoError(t, err)
  2318. err = config.LoadConfig(configDir, "")
  2319. assert.NoError(t, err)
  2320. providerConf = config.GetProviderConf()
  2321. providerConf.CredentialsPath = credentialsPath
  2322. err = os.RemoveAll(credentialsPath)
  2323. assert.NoError(t, err)
  2324. err = dataprovider.Initialize(providerConf, configDir, true)
  2325. assert.NoError(t, err)
  2326. }
  2327. func TestDefenderAPI(t *testing.T) {
  2328. oldConfig := config.GetCommonConfig()
  2329. cfg := config.GetCommonConfig()
  2330. cfg.DefenderConfig.Enabled = true
  2331. cfg.DefenderConfig.Threshold = 3
  2332. err := common.Initialize(cfg)
  2333. require.NoError(t, err)
  2334. ip := "::1"
  2335. response, _, err := httpdtest.GetBanTime(ip, http.StatusOK)
  2336. require.NoError(t, err)
  2337. banTime, ok := response["date_time"]
  2338. require.True(t, ok)
  2339. assert.Nil(t, banTime)
  2340. response, _, err = httpdtest.GetScore(ip, http.StatusOK)
  2341. require.NoError(t, err)
  2342. score, ok := response["score"]
  2343. require.True(t, ok)
  2344. assert.Equal(t, float64(0), score)
  2345. err = httpdtest.UnbanIP(ip, http.StatusNotFound)
  2346. require.NoError(t, err)
  2347. common.AddDefenderEvent(ip, common.HostEventNoLoginTried)
  2348. response, _, err = httpdtest.GetScore(ip, http.StatusOK)
  2349. require.NoError(t, err)
  2350. score, ok = response["score"]
  2351. require.True(t, ok)
  2352. assert.Equal(t, float64(2), score)
  2353. common.AddDefenderEvent(ip, common.HostEventNoLoginTried)
  2354. response, _, err = httpdtest.GetBanTime(ip, http.StatusOK)
  2355. require.NoError(t, err)
  2356. banTime, ok = response["date_time"]
  2357. require.True(t, ok)
  2358. assert.NotNil(t, banTime)
  2359. err = httpdtest.UnbanIP(ip, http.StatusOK)
  2360. require.NoError(t, err)
  2361. err = httpdtest.UnbanIP(ip, http.StatusNotFound)
  2362. require.NoError(t, err)
  2363. err = common.Initialize(oldConfig)
  2364. require.NoError(t, err)
  2365. }
  2366. func TestDefenderAPIErrors(t *testing.T) {
  2367. _, _, err := httpdtest.GetBanTime("", http.StatusBadRequest)
  2368. require.NoError(t, err)
  2369. _, _, err = httpdtest.GetBanTime("invalid", http.StatusBadRequest)
  2370. require.NoError(t, err)
  2371. _, _, err = httpdtest.GetScore("", http.StatusBadRequest)
  2372. require.NoError(t, err)
  2373. err = httpdtest.UnbanIP("", http.StatusBadRequest)
  2374. require.NoError(t, err)
  2375. }
  2376. func TestLoaddataFromPostBody(t *testing.T) {
  2377. mappedPath := filepath.Join(os.TempDir(), "restored_folder")
  2378. folderName := filepath.Base(mappedPath)
  2379. user := getTestUser()
  2380. user.ID = 1
  2381. user.Username = "test_user_restored"
  2382. admin := getTestAdmin()
  2383. admin.ID = 1
  2384. admin.Username = "test_admin_restored"
  2385. backupData := dataprovider.BackupData{}
  2386. backupData.Users = append(backupData.Users, user)
  2387. backupData.Admins = append(backupData.Admins, admin)
  2388. backupData.Folders = []vfs.BaseVirtualFolder{
  2389. {
  2390. Name: folderName,
  2391. MappedPath: mappedPath,
  2392. UsedQuotaSize: 123,
  2393. UsedQuotaFiles: 456,
  2394. LastQuotaUpdate: 789,
  2395. Users: []string{"user"},
  2396. },
  2397. {
  2398. Name: folderName,
  2399. MappedPath: mappedPath + "1",
  2400. },
  2401. }
  2402. backupContent, err := json.Marshal(backupData)
  2403. assert.NoError(t, err)
  2404. _, _, err = httpdtest.LoaddataFromPostBody(nil, "0", "0", http.StatusBadRequest)
  2405. assert.NoError(t, err)
  2406. _, _, err = httpdtest.LoaddataFromPostBody(backupContent, "a", "0", http.StatusBadRequest)
  2407. assert.NoError(t, err)
  2408. _, _, err = httpdtest.LoaddataFromPostBody([]byte("invalid content"), "0", "0", http.StatusBadRequest)
  2409. assert.NoError(t, err)
  2410. _, _, err = httpdtest.LoaddataFromPostBody(backupContent, "0", "0", http.StatusOK)
  2411. assert.NoError(t, err)
  2412. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  2413. assert.NoError(t, err)
  2414. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  2415. assert.NoError(t, err)
  2416. admin, _, err = httpdtest.GetAdminByUsername(admin.Username, http.StatusOK)
  2417. assert.NoError(t, err)
  2418. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  2419. assert.NoError(t, err)
  2420. folder, _, err := httpdtest.GetFolderByName(folderName, http.StatusOK)
  2421. assert.NoError(t, err)
  2422. assert.Equal(t, mappedPath+"1", folder.MappedPath)
  2423. assert.Equal(t, int64(123), folder.UsedQuotaSize)
  2424. assert.Equal(t, 456, folder.UsedQuotaFiles)
  2425. assert.Equal(t, int64(789), folder.LastQuotaUpdate)
  2426. assert.Len(t, folder.Users, 0)
  2427. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  2428. assert.NoError(t, err)
  2429. }
  2430. func TestLoaddata(t *testing.T) {
  2431. mappedPath := filepath.Join(os.TempDir(), "restored_folder")
  2432. folderName := filepath.Base(mappedPath)
  2433. user := getTestUser()
  2434. user.ID = 1
  2435. user.Username = "test_user_restore"
  2436. admin := getTestAdmin()
  2437. admin.ID = 1
  2438. admin.Username = "test_admin_restore"
  2439. backupData := dataprovider.BackupData{}
  2440. backupData.Users = append(backupData.Users, user)
  2441. backupData.Admins = append(backupData.Admins, admin)
  2442. backupData.Folders = []vfs.BaseVirtualFolder{
  2443. {
  2444. Name: folderName,
  2445. MappedPath: mappedPath + "1",
  2446. UsedQuotaSize: 123,
  2447. UsedQuotaFiles: 456,
  2448. LastQuotaUpdate: 789,
  2449. Users: []string{"user"},
  2450. },
  2451. {
  2452. MappedPath: mappedPath,
  2453. Name: folderName,
  2454. },
  2455. }
  2456. backupContent, err := json.Marshal(backupData)
  2457. assert.NoError(t, err)
  2458. backupFilePath := filepath.Join(backupsPath, "backup.json")
  2459. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  2460. assert.NoError(t, err)
  2461. _, _, err = httpdtest.Loaddata(backupFilePath, "a", "", http.StatusBadRequest)
  2462. assert.NoError(t, err)
  2463. _, _, err = httpdtest.Loaddata(backupFilePath, "", "a", http.StatusBadRequest)
  2464. assert.NoError(t, err)
  2465. _, _, err = httpdtest.Loaddata("backup.json", "1", "", http.StatusBadRequest)
  2466. assert.NoError(t, err)
  2467. _, _, err = httpdtest.Loaddata(backupFilePath+"a", "1", "", http.StatusBadRequest)
  2468. assert.NoError(t, err)
  2469. if runtime.GOOS != "windows" {
  2470. err = os.Chmod(backupFilePath, 0111)
  2471. assert.NoError(t, err)
  2472. _, _, err = httpdtest.Loaddata(backupFilePath, "1", "", http.StatusInternalServerError)
  2473. assert.NoError(t, err)
  2474. err = os.Chmod(backupFilePath, 0644)
  2475. assert.NoError(t, err)
  2476. }
  2477. // add user, folder, admin from backup
  2478. _, _, err = httpdtest.Loaddata(backupFilePath, "1", "", http.StatusOK)
  2479. assert.NoError(t, err)
  2480. // update from backup
  2481. _, _, err = httpdtest.Loaddata(backupFilePath, "2", "", http.StatusOK)
  2482. assert.NoError(t, err)
  2483. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  2484. assert.NoError(t, err)
  2485. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  2486. assert.NoError(t, err)
  2487. admin, _, err = httpdtest.GetAdminByUsername(admin.Username, http.StatusOK)
  2488. assert.NoError(t, err)
  2489. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  2490. assert.NoError(t, err)
  2491. folder, _, err := httpdtest.GetFolderByName(folderName, http.StatusOK)
  2492. assert.NoError(t, err)
  2493. assert.Equal(t, mappedPath, folder.MappedPath)
  2494. assert.Equal(t, int64(123), folder.UsedQuotaSize)
  2495. assert.Equal(t, 456, folder.UsedQuotaFiles)
  2496. assert.Equal(t, int64(789), folder.LastQuotaUpdate)
  2497. assert.Len(t, folder.Users, 0)
  2498. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  2499. assert.NoError(t, err)
  2500. err = os.Remove(backupFilePath)
  2501. assert.NoError(t, err)
  2502. err = createTestFile(backupFilePath, 10485761)
  2503. assert.NoError(t, err)
  2504. _, _, err = httpdtest.Loaddata(backupFilePath, "1", "0", http.StatusBadRequest)
  2505. assert.NoError(t, err)
  2506. err = os.Remove(backupFilePath)
  2507. assert.NoError(t, err)
  2508. err = createTestFile(backupFilePath, 65535)
  2509. assert.NoError(t, err)
  2510. _, _, err = httpdtest.Loaddata(backupFilePath, "1", "0", http.StatusBadRequest)
  2511. assert.NoError(t, err)
  2512. err = os.Remove(backupFilePath)
  2513. assert.NoError(t, err)
  2514. }
  2515. func TestLoaddataMode(t *testing.T) {
  2516. mappedPath := filepath.Join(os.TempDir(), "restored_fold")
  2517. folderName := filepath.Base(mappedPath)
  2518. user := getTestUser()
  2519. user.ID = 1
  2520. user.Username = "test_user_restore"
  2521. admin := getTestAdmin()
  2522. admin.ID = 1
  2523. admin.Username = "test_admin_restore"
  2524. backupData := dataprovider.BackupData{}
  2525. backupData.Users = append(backupData.Users, user)
  2526. backupData.Admins = append(backupData.Admins, admin)
  2527. backupData.Folders = []vfs.BaseVirtualFolder{
  2528. {
  2529. Name: folderName,
  2530. MappedPath: mappedPath,
  2531. UsedQuotaSize: 123,
  2532. UsedQuotaFiles: 456,
  2533. LastQuotaUpdate: 789,
  2534. Users: []string{"user"},
  2535. },
  2536. {
  2537. MappedPath: mappedPath + "1",
  2538. Name: folderName,
  2539. },
  2540. }
  2541. backupContent, _ := json.Marshal(backupData)
  2542. backupFilePath := filepath.Join(backupsPath, "backup.json")
  2543. err := ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  2544. assert.NoError(t, err)
  2545. _, _, err = httpdtest.Loaddata(backupFilePath, "0", "0", http.StatusOK)
  2546. assert.NoError(t, err)
  2547. folder, _, err := httpdtest.GetFolderByName(folderName, http.StatusOK)
  2548. assert.NoError(t, err)
  2549. assert.Equal(t, mappedPath+"1", folder.MappedPath)
  2550. assert.Equal(t, int64(123), folder.UsedQuotaSize)
  2551. assert.Equal(t, 456, folder.UsedQuotaFiles)
  2552. assert.Equal(t, int64(789), folder.LastQuotaUpdate)
  2553. assert.Len(t, folder.Users, 0)
  2554. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  2555. assert.NoError(t, err)
  2556. oldUploadBandwidth := user.UploadBandwidth
  2557. user.UploadBandwidth = oldUploadBandwidth + 128
  2558. user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
  2559. assert.NoError(t, err)
  2560. admin, _, err = httpdtest.GetAdminByUsername(admin.Username, http.StatusOK)
  2561. assert.NoError(t, err)
  2562. oldInfo := admin.AdditionalInfo
  2563. admin.AdditionalInfo = "newInfo"
  2564. admin, _, err = httpdtest.UpdateAdmin(admin, http.StatusOK)
  2565. assert.NoError(t, err)
  2566. backupData.Folders = []vfs.BaseVirtualFolder{
  2567. {
  2568. MappedPath: mappedPath,
  2569. Name: folderName,
  2570. },
  2571. }
  2572. _, _, err = httpdtest.Loaddata(backupFilePath, "0", "1", http.StatusOK)
  2573. assert.NoError(t, err)
  2574. folder, _, err = httpdtest.GetFolderByName(folderName, http.StatusOK)
  2575. assert.NoError(t, err)
  2576. assert.Equal(t, mappedPath+"1", folder.MappedPath)
  2577. assert.Equal(t, int64(123), folder.UsedQuotaSize)
  2578. assert.Equal(t, 456, folder.UsedQuotaFiles)
  2579. assert.Equal(t, int64(789), folder.LastQuotaUpdate)
  2580. assert.Len(t, folder.Users, 0)
  2581. c := common.NewBaseConnection("connID", common.ProtocolFTP, user, nil)
  2582. fakeConn := &fakeConnection{
  2583. BaseConnection: c,
  2584. }
  2585. common.Connections.Add(fakeConn)
  2586. assert.Len(t, common.Connections.GetStats(), 1)
  2587. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  2588. assert.NoError(t, err)
  2589. assert.NotEqual(t, oldUploadBandwidth, user.UploadBandwidth)
  2590. admin, _, err = httpdtest.GetAdminByUsername(admin.Username, http.StatusOK)
  2591. assert.NoError(t, err)
  2592. assert.NotEqual(t, oldInfo, admin.AdditionalInfo)
  2593. _, _, err = httpdtest.Loaddata(backupFilePath, "0", "2", http.StatusOK)
  2594. assert.NoError(t, err)
  2595. // mode 2 will update the user and close the previous connection
  2596. assert.Len(t, common.Connections.GetStats(), 0)
  2597. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  2598. assert.NoError(t, err)
  2599. assert.Equal(t, oldUploadBandwidth, user.UploadBandwidth)
  2600. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  2601. assert.NoError(t, err)
  2602. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  2603. assert.NoError(t, err)
  2604. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  2605. assert.NoError(t, err)
  2606. err = os.Remove(backupFilePath)
  2607. assert.NoError(t, err)
  2608. }
  2609. func TestHTTPSConnection(t *testing.T) {
  2610. client := &http.Client{
  2611. Timeout: 5 * time.Second,
  2612. }
  2613. resp, err := client.Get("https://localhost:8443" + healthzPath)
  2614. if assert.Error(t, err) {
  2615. if !strings.Contains(err.Error(), "certificate is not valid") &&
  2616. !strings.Contains(err.Error(), "certificate signed by unknown authority") {
  2617. assert.Fail(t, err.Error())
  2618. }
  2619. } else {
  2620. resp.Body.Close()
  2621. }
  2622. }
  2623. // test using mock http server
  2624. func TestBasicUserHandlingMock(t *testing.T) {
  2625. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2626. assert.NoError(t, err)
  2627. user := getTestUser()
  2628. userAsJSON := getUserAsJSON(t, user)
  2629. req, err := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2630. assert.NoError(t, err)
  2631. setBearerForReq(req, token)
  2632. rr := executeRequest(req)
  2633. checkResponseCode(t, http.StatusCreated, rr)
  2634. err = render.DecodeJSON(rr.Body, &user)
  2635. assert.NoError(t, err)
  2636. req, err = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2637. assert.NoError(t, err)
  2638. setBearerForReq(req, token)
  2639. rr = executeRequest(req)
  2640. checkResponseCode(t, http.StatusInternalServerError, rr)
  2641. user.MaxSessions = 10
  2642. user.UploadBandwidth = 128
  2643. user.Permissions["/"] = []string{dataprovider.PermAny, dataprovider.PermDelete, dataprovider.PermDownload}
  2644. userAsJSON = getUserAsJSON(t, user)
  2645. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+user.Username, bytes.NewBuffer(userAsJSON))
  2646. setBearerForReq(req, token)
  2647. rr = executeRequest(req)
  2648. checkResponseCode(t, http.StatusOK, rr)
  2649. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+user.Username, nil)
  2650. setBearerForReq(req, token)
  2651. rr = executeRequest(req)
  2652. checkResponseCode(t, http.StatusOK, rr)
  2653. var updatedUser dataprovider.User
  2654. err = render.DecodeJSON(rr.Body, &updatedUser)
  2655. assert.NoError(t, err)
  2656. assert.Equal(t, user.MaxSessions, updatedUser.MaxSessions)
  2657. assert.Equal(t, user.UploadBandwidth, updatedUser.UploadBandwidth)
  2658. assert.Equal(t, 1, len(updatedUser.Permissions["/"]))
  2659. assert.True(t, utils.IsStringInSlice(dataprovider.PermAny, updatedUser.Permissions["/"]))
  2660. req, _ = http.NewRequest(http.MethodDelete, userPath+"/"+user.Username, nil)
  2661. setBearerForReq(req, token)
  2662. rr = executeRequest(req)
  2663. checkResponseCode(t, http.StatusOK, rr)
  2664. }
  2665. func TestAddUserNoUsernameMock(t *testing.T) {
  2666. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2667. assert.NoError(t, err)
  2668. user := getTestUser()
  2669. user.Username = ""
  2670. userAsJSON := getUserAsJSON(t, user)
  2671. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2672. setBearerForReq(req, token)
  2673. rr := executeRequest(req)
  2674. checkResponseCode(t, http.StatusBadRequest, rr)
  2675. }
  2676. func TestAddUserInvalidHomeDirMock(t *testing.T) {
  2677. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2678. assert.NoError(t, err)
  2679. user := getTestUser()
  2680. user.HomeDir = "relative_path"
  2681. userAsJSON := getUserAsJSON(t, user)
  2682. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2683. setBearerForReq(req, token)
  2684. rr := executeRequest(req)
  2685. checkResponseCode(t, http.StatusBadRequest, rr)
  2686. }
  2687. func TestAddUserInvalidPermsMock(t *testing.T) {
  2688. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2689. assert.NoError(t, err)
  2690. user := getTestUser()
  2691. user.Permissions["/"] = []string{}
  2692. userAsJSON := getUserAsJSON(t, user)
  2693. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2694. setBearerForReq(req, token)
  2695. rr := executeRequest(req)
  2696. checkResponseCode(t, http.StatusBadRequest, rr)
  2697. }
  2698. func TestAddFolderInvalidJsonMock(t *testing.T) {
  2699. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2700. assert.NoError(t, err)
  2701. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer([]byte("invalid json")))
  2702. setBearerForReq(req, token)
  2703. rr := executeRequest(req)
  2704. checkResponseCode(t, http.StatusBadRequest, rr)
  2705. }
  2706. func TestUpdateFolderInvalidJsonMock(t *testing.T) {
  2707. folder := vfs.BaseVirtualFolder{
  2708. Name: "name",
  2709. MappedPath: filepath.Clean(os.TempDir()),
  2710. }
  2711. folder, resp, err := httpdtest.AddFolder(folder, http.StatusCreated)
  2712. assert.NoError(t, err, string(resp))
  2713. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2714. assert.NoError(t, err)
  2715. req, _ := http.NewRequest(http.MethodPut, path.Join(folderPath, folder.Name), bytes.NewBuffer([]byte("not a json")))
  2716. setBearerForReq(req, token)
  2717. rr := executeRequest(req)
  2718. checkResponseCode(t, http.StatusBadRequest, rr)
  2719. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  2720. assert.NoError(t, err)
  2721. }
  2722. func TestUnbanInvalidJsonMock(t *testing.T) {
  2723. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2724. assert.NoError(t, err)
  2725. req, _ := http.NewRequest(http.MethodPost, defenderUnban, bytes.NewBuffer([]byte("invalid json")))
  2726. setBearerForReq(req, token)
  2727. rr := executeRequest(req)
  2728. checkResponseCode(t, http.StatusBadRequest, rr)
  2729. }
  2730. func TestAddUserInvalidJsonMock(t *testing.T) {
  2731. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2732. assert.NoError(t, err)
  2733. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer([]byte("invalid json")))
  2734. setBearerForReq(req, token)
  2735. rr := executeRequest(req)
  2736. checkResponseCode(t, http.StatusBadRequest, rr)
  2737. }
  2738. func TestAddAdminInvalidJsonMock(t *testing.T) {
  2739. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2740. assert.NoError(t, err)
  2741. req, _ := http.NewRequest(http.MethodPost, adminPath, bytes.NewBuffer([]byte("...")))
  2742. setBearerForReq(req, token)
  2743. rr := executeRequest(req)
  2744. checkResponseCode(t, http.StatusBadRequest, rr)
  2745. }
  2746. func TestAddAdminNoPasswordMock(t *testing.T) {
  2747. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2748. assert.NoError(t, err)
  2749. admin := getTestAdmin()
  2750. admin.Password = ""
  2751. asJSON, err := json.Marshal(admin)
  2752. assert.NoError(t, err)
  2753. req, _ := http.NewRequest(http.MethodPost, adminPath, bytes.NewBuffer(asJSON))
  2754. setBearerForReq(req, token)
  2755. rr := executeRequest(req)
  2756. checkResponseCode(t, http.StatusBadRequest, rr)
  2757. assert.Contains(t, rr.Body.String(), "please set a password")
  2758. }
  2759. func TestChangeAdminPwdInvalidJsonMock(t *testing.T) {
  2760. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2761. assert.NoError(t, err)
  2762. req, _ := http.NewRequest(http.MethodPut, adminPwdPath, bytes.NewBuffer([]byte("{")))
  2763. setBearerForReq(req, token)
  2764. rr := executeRequest(req)
  2765. checkResponseCode(t, http.StatusBadRequest, rr)
  2766. }
  2767. func TestLoginInvalidPasswordMock(t *testing.T) {
  2768. _, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass+"1")
  2769. assert.Error(t, err)
  2770. // now a login with no credentials
  2771. req, _ := http.NewRequest(http.MethodGet, "/api/v2/token", nil)
  2772. rr := executeRequest(req)
  2773. assert.Equal(t, http.StatusUnauthorized, rr.Code)
  2774. }
  2775. func TestChangeAdminPwdMock(t *testing.T) {
  2776. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2777. assert.NoError(t, err)
  2778. admin := getTestAdmin()
  2779. admin.Username = altAdminUsername
  2780. admin.Password = altAdminPassword
  2781. admin.Permissions = []string{dataprovider.PermAdminAddUsers, dataprovider.PermAdminDeleteUsers}
  2782. asJSON, err := json.Marshal(admin)
  2783. assert.NoError(t, err)
  2784. req, _ := http.NewRequest(http.MethodPost, adminPath, bytes.NewBuffer(asJSON))
  2785. setBearerForReq(req, token)
  2786. rr := executeRequest(req)
  2787. checkResponseCode(t, http.StatusCreated, rr)
  2788. altToken, err := getJWTAPITokenFromTestServer(altAdminUsername, altAdminPassword)
  2789. assert.NoError(t, err)
  2790. user := getTestUser()
  2791. userAsJSON := getUserAsJSON(t, user)
  2792. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2793. setBearerForReq(req, altToken)
  2794. rr = executeRequest(req)
  2795. checkResponseCode(t, http.StatusCreated, rr)
  2796. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer(userAsJSON))
  2797. setBearerForReq(req, altToken)
  2798. rr = executeRequest(req)
  2799. checkResponseCode(t, http.StatusForbidden, rr)
  2800. pwd := make(map[string]string)
  2801. pwd["current_password"] = altAdminPassword
  2802. pwd["new_password"] = defaultTokenAuthPass
  2803. asJSON, err = json.Marshal(pwd)
  2804. assert.NoError(t, err)
  2805. req, _ = http.NewRequest(http.MethodPut, adminPwdPath, bytes.NewBuffer(asJSON))
  2806. setBearerForReq(req, altToken)
  2807. rr = executeRequest(req)
  2808. checkResponseCode(t, http.StatusOK, rr)
  2809. _, err = getJWTAPITokenFromTestServer(altAdminUsername, altAdminPassword)
  2810. assert.Error(t, err)
  2811. altToken, err = getJWTAPITokenFromTestServer(altAdminUsername, defaultTokenAuthPass)
  2812. assert.NoError(t, err)
  2813. req, _ = http.NewRequest(http.MethodPut, adminPwdPath, bytes.NewBuffer(asJSON))
  2814. setBearerForReq(req, altToken)
  2815. rr = executeRequest(req)
  2816. checkResponseCode(t, http.StatusBadRequest, rr) // current password does not match
  2817. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  2818. setBearerForReq(req, altToken)
  2819. rr = executeRequest(req)
  2820. checkResponseCode(t, http.StatusOK, rr)
  2821. req, _ = http.NewRequest(http.MethodDelete, path.Join(adminPath, altAdminUsername), nil)
  2822. setBearerForReq(req, token)
  2823. rr = executeRequest(req)
  2824. checkResponseCode(t, http.StatusOK, rr)
  2825. }
  2826. func TestUpdateAdminMock(t *testing.T) {
  2827. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2828. assert.NoError(t, err)
  2829. admin := getTestAdmin()
  2830. admin.Username = altAdminUsername
  2831. admin.Permissions = []string{dataprovider.PermAdminManageAdmins}
  2832. asJSON, err := json.Marshal(admin)
  2833. assert.NoError(t, err)
  2834. req, _ := http.NewRequest(http.MethodPost, adminPath, bytes.NewBuffer(asJSON))
  2835. setBearerForReq(req, token)
  2836. rr := executeRequest(req)
  2837. checkResponseCode(t, http.StatusCreated, rr)
  2838. req, _ = http.NewRequest(http.MethodPut, path.Join(adminPath, "abc"), bytes.NewBuffer(asJSON))
  2839. setBearerForReq(req, token)
  2840. rr = executeRequest(req)
  2841. checkResponseCode(t, http.StatusNotFound, rr)
  2842. req, _ = http.NewRequest(http.MethodPut, path.Join(adminPath, altAdminUsername), bytes.NewBuffer([]byte("no json")))
  2843. setBearerForReq(req, token)
  2844. rr = executeRequest(req)
  2845. checkResponseCode(t, http.StatusBadRequest, rr)
  2846. admin.Permissions = nil
  2847. asJSON, err = json.Marshal(admin)
  2848. assert.NoError(t, err)
  2849. req, _ = http.NewRequest(http.MethodPut, path.Join(adminPath, altAdminUsername), bytes.NewBuffer(asJSON))
  2850. setBearerForReq(req, token)
  2851. rr = executeRequest(req)
  2852. checkResponseCode(t, http.StatusBadRequest, rr)
  2853. admin = getTestAdmin()
  2854. admin.Status = 0
  2855. asJSON, err = json.Marshal(admin)
  2856. assert.NoError(t, err)
  2857. req, _ = http.NewRequest(http.MethodPut, path.Join(adminPath, defaultTokenAuthUser), bytes.NewBuffer(asJSON))
  2858. setBearerForReq(req, token)
  2859. rr = executeRequest(req)
  2860. checkResponseCode(t, http.StatusBadRequest, rr)
  2861. admin.Status = 1
  2862. admin.Permissions = []string{dataprovider.PermAdminAddUsers}
  2863. asJSON, err = json.Marshal(admin)
  2864. assert.NoError(t, err)
  2865. req, _ = http.NewRequest(http.MethodPut, path.Join(adminPath, defaultTokenAuthUser), bytes.NewBuffer(asJSON))
  2866. setBearerForReq(req, token)
  2867. rr = executeRequest(req)
  2868. checkResponseCode(t, http.StatusBadRequest, rr)
  2869. altToken, err := getJWTAPITokenFromTestServer(altAdminUsername, defaultTokenAuthPass)
  2870. assert.NoError(t, err)
  2871. admin.Permissions = []string{dataprovider.PermAdminManageAdmins, dataprovider.PermAdminCloseConnections}
  2872. asJSON, err = json.Marshal(admin)
  2873. assert.NoError(t, err)
  2874. req, _ = http.NewRequest(http.MethodPut, path.Join(adminPath, altAdminUsername), bytes.NewBuffer(asJSON))
  2875. setBearerForReq(req, altToken)
  2876. rr = executeRequest(req)
  2877. checkResponseCode(t, http.StatusOK, rr)
  2878. req, _ = http.NewRequest(http.MethodDelete, path.Join(adminPath, altAdminUsername), nil)
  2879. setBearerForReq(req, token)
  2880. rr = executeRequest(req)
  2881. checkResponseCode(t, http.StatusOK, rr)
  2882. }
  2883. func TestUpdateUserMock(t *testing.T) {
  2884. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2885. assert.NoError(t, err)
  2886. user := getTestUser()
  2887. userAsJSON := getUserAsJSON(t, user)
  2888. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2889. setBearerForReq(req, token)
  2890. rr := executeRequest(req)
  2891. checkResponseCode(t, http.StatusCreated, rr)
  2892. err = render.DecodeJSON(rr.Body, &user)
  2893. assert.NoError(t, err)
  2894. // permissions should not change if empty or nil
  2895. permissions := user.Permissions
  2896. user.Permissions = make(map[string][]string)
  2897. userAsJSON = getUserAsJSON(t, user)
  2898. req, _ = http.NewRequest(http.MethodPut, userPath+"/"+user.Username, bytes.NewBuffer(userAsJSON))
  2899. setBearerForReq(req, token)
  2900. rr = executeRequest(req)
  2901. checkResponseCode(t, http.StatusOK, rr)
  2902. req, _ = http.NewRequest(http.MethodGet, userPath+"/"+user.Username, nil)
  2903. setBearerForReq(req, token)
  2904. rr = executeRequest(req)
  2905. checkResponseCode(t, http.StatusOK, rr)
  2906. var updatedUser dataprovider.User
  2907. err = render.DecodeJSON(rr.Body, &updatedUser)
  2908. assert.NoError(t, err)
  2909. for dir, perms := range permissions {
  2910. if actualPerms, ok := updatedUser.Permissions[dir]; ok {
  2911. for _, v := range actualPerms {
  2912. assert.True(t, utils.IsStringInSlice(v, perms))
  2913. }
  2914. } else {
  2915. assert.Fail(t, "Permissions directories mismatch")
  2916. }
  2917. }
  2918. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  2919. setBearerForReq(req, token)
  2920. rr = executeRequest(req)
  2921. checkResponseCode(t, http.StatusOK, rr)
  2922. }
  2923. func TestUpdateUserQuotaUsageMock(t *testing.T) {
  2924. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2925. assert.NoError(t, err)
  2926. var user dataprovider.User
  2927. u := getTestUser()
  2928. usedQuotaFiles := 1
  2929. usedQuotaSize := int64(65535)
  2930. u.UsedQuotaFiles = usedQuotaFiles
  2931. u.UsedQuotaSize = usedQuotaSize
  2932. userAsJSON := getUserAsJSON(t, u)
  2933. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2934. setBearerForReq(req, token)
  2935. rr := executeRequest(req)
  2936. checkResponseCode(t, http.StatusCreated, rr)
  2937. err = render.DecodeJSON(rr.Body, &user)
  2938. assert.NoError(t, err)
  2939. req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaPath, bytes.NewBuffer(userAsJSON))
  2940. setBearerForReq(req, token)
  2941. rr = executeRequest(req)
  2942. checkResponseCode(t, http.StatusOK, rr)
  2943. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  2944. setBearerForReq(req, token)
  2945. rr = executeRequest(req)
  2946. checkResponseCode(t, http.StatusOK, rr)
  2947. err = render.DecodeJSON(rr.Body, &user)
  2948. assert.NoError(t, err)
  2949. assert.Equal(t, usedQuotaFiles, user.UsedQuotaFiles)
  2950. assert.Equal(t, usedQuotaSize, user.UsedQuotaSize)
  2951. req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaPath, bytes.NewBuffer([]byte("string")))
  2952. setBearerForReq(req, token)
  2953. rr = executeRequest(req)
  2954. checkResponseCode(t, http.StatusBadRequest, rr)
  2955. assert.True(t, common.QuotaScans.AddUserQuotaScan(user.Username))
  2956. req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaPath, bytes.NewBuffer(userAsJSON))
  2957. setBearerForReq(req, token)
  2958. rr = executeRequest(req)
  2959. checkResponseCode(t, http.StatusConflict, rr)
  2960. assert.True(t, common.QuotaScans.RemoveUserQuotaScan(user.Username))
  2961. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  2962. setBearerForReq(req, token)
  2963. rr = executeRequest(req)
  2964. checkResponseCode(t, http.StatusOK, rr)
  2965. }
  2966. func TestUserPermissionsMock(t *testing.T) {
  2967. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  2968. assert.NoError(t, err)
  2969. user := getTestUser()
  2970. user.Permissions = make(map[string][]string)
  2971. user.Permissions["/somedir"] = []string{dataprovider.PermAny}
  2972. userAsJSON := getUserAsJSON(t, user)
  2973. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2974. setBearerForReq(req, token)
  2975. rr := executeRequest(req)
  2976. checkResponseCode(t, http.StatusBadRequest, rr)
  2977. user.Permissions = make(map[string][]string)
  2978. user.Permissions["/"] = []string{dataprovider.PermAny}
  2979. user.Permissions[".."] = []string{dataprovider.PermAny}
  2980. userAsJSON = getUserAsJSON(t, user)
  2981. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2982. setBearerForReq(req, token)
  2983. rr = executeRequest(req)
  2984. checkResponseCode(t, http.StatusBadRequest, rr)
  2985. user.Permissions = make(map[string][]string)
  2986. user.Permissions["/"] = []string{dataprovider.PermAny}
  2987. userAsJSON = getUserAsJSON(t, user)
  2988. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  2989. setBearerForReq(req, token)
  2990. rr = executeRequest(req)
  2991. checkResponseCode(t, http.StatusCreated, rr)
  2992. err = render.DecodeJSON(rr.Body, &user)
  2993. assert.NoError(t, err)
  2994. user.Permissions["/somedir"] = []string{"invalid"}
  2995. userAsJSON = getUserAsJSON(t, user)
  2996. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer(userAsJSON))
  2997. setBearerForReq(req, token)
  2998. rr = executeRequest(req)
  2999. checkResponseCode(t, http.StatusBadRequest, rr)
  3000. delete(user.Permissions, "/somedir")
  3001. user.Permissions["/somedir/.."] = []string{dataprovider.PermAny}
  3002. userAsJSON = getUserAsJSON(t, user)
  3003. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer(userAsJSON))
  3004. setBearerForReq(req, token)
  3005. rr = executeRequest(req)
  3006. checkResponseCode(t, http.StatusBadRequest, rr)
  3007. delete(user.Permissions, "/somedir/..")
  3008. user.Permissions["not_abs_path"] = []string{dataprovider.PermAny}
  3009. userAsJSON = getUserAsJSON(t, user)
  3010. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer(userAsJSON))
  3011. setBearerForReq(req, token)
  3012. rr = executeRequest(req)
  3013. checkResponseCode(t, http.StatusBadRequest, rr)
  3014. delete(user.Permissions, "not_abs_path")
  3015. user.Permissions["/somedir/../otherdir/"] = []string{dataprovider.PermListItems}
  3016. userAsJSON = getUserAsJSON(t, user)
  3017. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer(userAsJSON))
  3018. setBearerForReq(req, token)
  3019. rr = executeRequest(req)
  3020. checkResponseCode(t, http.StatusOK, rr)
  3021. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  3022. setBearerForReq(req, token)
  3023. rr = executeRequest(req)
  3024. checkResponseCode(t, http.StatusOK, rr)
  3025. var updatedUser dataprovider.User
  3026. err = render.DecodeJSON(rr.Body, &updatedUser)
  3027. assert.NoError(t, err)
  3028. if val, ok := updatedUser.Permissions["/otherdir"]; ok {
  3029. assert.True(t, utils.IsStringInSlice(dataprovider.PermListItems, val))
  3030. assert.Equal(t, 1, len(val))
  3031. } else {
  3032. assert.Fail(t, "expected dir not found in permissions")
  3033. }
  3034. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  3035. setBearerForReq(req, token)
  3036. rr = executeRequest(req)
  3037. checkResponseCode(t, http.StatusOK, rr)
  3038. }
  3039. func TestUpdateUserInvalidJsonMock(t *testing.T) {
  3040. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3041. assert.NoError(t, err)
  3042. user := getTestUser()
  3043. userAsJSON := getUserAsJSON(t, user)
  3044. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3045. setBearerForReq(req, token)
  3046. rr := executeRequest(req)
  3047. checkResponseCode(t, http.StatusCreated, rr)
  3048. err = render.DecodeJSON(rr.Body, &user)
  3049. assert.NoError(t, err)
  3050. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer([]byte("Invalid json")))
  3051. setBearerForReq(req, token)
  3052. rr = executeRequest(req)
  3053. checkResponseCode(t, http.StatusBadRequest, rr)
  3054. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  3055. setBearerForReq(req, token)
  3056. rr = executeRequest(req)
  3057. checkResponseCode(t, http.StatusOK, rr)
  3058. }
  3059. func TestUpdateUserInvalidParamsMock(t *testing.T) {
  3060. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3061. assert.NoError(t, err)
  3062. user := getTestUser()
  3063. userAsJSON := getUserAsJSON(t, user)
  3064. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3065. setBearerForReq(req, token)
  3066. rr := executeRequest(req)
  3067. checkResponseCode(t, http.StatusCreated, rr)
  3068. err = render.DecodeJSON(rr.Body, &user)
  3069. assert.NoError(t, err)
  3070. user.HomeDir = ""
  3071. userAsJSON = getUserAsJSON(t, user)
  3072. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer(userAsJSON))
  3073. setBearerForReq(req, token)
  3074. rr = executeRequest(req)
  3075. checkResponseCode(t, http.StatusBadRequest, rr)
  3076. userID := user.ID
  3077. user.ID = 0
  3078. userAsJSON = getUserAsJSON(t, user)
  3079. req, _ = http.NewRequest(http.MethodPut, path.Join(userPath, user.Username), bytes.NewBuffer(userAsJSON))
  3080. setBearerForReq(req, token)
  3081. rr = executeRequest(req)
  3082. checkResponseCode(t, http.StatusBadRequest, rr)
  3083. user.ID = userID
  3084. req, _ = http.NewRequest(http.MethodPut, userPath+"/0", bytes.NewBuffer(userAsJSON))
  3085. setBearerForReq(req, token)
  3086. rr = executeRequest(req)
  3087. checkResponseCode(t, http.StatusNotFound, rr)
  3088. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  3089. setBearerForReq(req, token)
  3090. rr = executeRequest(req)
  3091. checkResponseCode(t, http.StatusOK, rr)
  3092. }
  3093. func TestGetAdminsMock(t *testing.T) {
  3094. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3095. assert.NoError(t, err)
  3096. admin := getTestAdmin()
  3097. admin.Username = altAdminUsername
  3098. asJSON, err := json.Marshal(admin)
  3099. assert.NoError(t, err)
  3100. req, _ := http.NewRequest(http.MethodPost, adminPath, bytes.NewBuffer(asJSON))
  3101. setBearerForReq(req, token)
  3102. rr := executeRequest(req)
  3103. checkResponseCode(t, http.StatusCreated, rr)
  3104. req, _ = http.NewRequest(http.MethodGet, adminPath+"?limit=510&offset=0&order=ASC", nil)
  3105. setBearerForReq(req, token)
  3106. rr = executeRequest(req)
  3107. checkResponseCode(t, http.StatusOK, rr)
  3108. var admins []dataprovider.Admin
  3109. err = render.DecodeJSON(rr.Body, &admins)
  3110. assert.NoError(t, err)
  3111. assert.GreaterOrEqual(t, len(admins), 1)
  3112. firtAdmin := admins[0].Username
  3113. req, _ = http.NewRequest(http.MethodGet, adminPath+"?limit=510&offset=0&order=DESC", nil)
  3114. setBearerForReq(req, token)
  3115. rr = executeRequest(req)
  3116. checkResponseCode(t, http.StatusOK, rr)
  3117. admins = nil
  3118. err = render.DecodeJSON(rr.Body, &admins)
  3119. assert.NoError(t, err)
  3120. assert.GreaterOrEqual(t, len(admins), 1)
  3121. assert.NotEqual(t, firtAdmin, admins[0].Username)
  3122. req, _ = http.NewRequest(http.MethodGet, adminPath+"?limit=510&offset=1&order=ASC", nil)
  3123. setBearerForReq(req, token)
  3124. rr = executeRequest(req)
  3125. checkResponseCode(t, http.StatusOK, rr)
  3126. admins = nil
  3127. err = render.DecodeJSON(rr.Body, &admins)
  3128. assert.NoError(t, err)
  3129. assert.GreaterOrEqual(t, len(admins), 1)
  3130. assert.NotEqual(t, firtAdmin, admins[0].Username)
  3131. req, _ = http.NewRequest(http.MethodGet, adminPath+"?limit=a&offset=0&order=ASC", nil)
  3132. setBearerForReq(req, token)
  3133. rr = executeRequest(req)
  3134. checkResponseCode(t, http.StatusBadRequest, rr)
  3135. req, _ = http.NewRequest(http.MethodGet, adminPath+"?limit=1&offset=a&order=ASC", nil)
  3136. setBearerForReq(req, token)
  3137. rr = executeRequest(req)
  3138. checkResponseCode(t, http.StatusBadRequest, rr)
  3139. req, _ = http.NewRequest(http.MethodGet, adminPath+"?limit=1&offset=0&order=ASCa", nil)
  3140. setBearerForReq(req, token)
  3141. rr = executeRequest(req)
  3142. checkResponseCode(t, http.StatusBadRequest, rr)
  3143. req, _ = http.NewRequest(http.MethodDelete, path.Join(adminPath, admin.Username), nil)
  3144. setBearerForReq(req, token)
  3145. rr = executeRequest(req)
  3146. checkResponseCode(t, http.StatusOK, rr)
  3147. }
  3148. func TestGetUsersMock(t *testing.T) {
  3149. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3150. assert.NoError(t, err)
  3151. user := getTestUser()
  3152. userAsJSON := getUserAsJSON(t, user)
  3153. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3154. setBearerForReq(req, token)
  3155. rr := executeRequest(req)
  3156. checkResponseCode(t, http.StatusCreated, rr)
  3157. err = render.DecodeJSON(rr.Body, &user)
  3158. assert.NoError(t, err)
  3159. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=510&offset=0&order=ASC", nil)
  3160. setBearerForReq(req, token)
  3161. rr = executeRequest(req)
  3162. checkResponseCode(t, http.StatusOK, rr)
  3163. var users []dataprovider.User
  3164. err = render.DecodeJSON(rr.Body, &users)
  3165. assert.NoError(t, err)
  3166. assert.GreaterOrEqual(t, len(users), 1)
  3167. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=a&offset=0&order=ASC", nil)
  3168. setBearerForReq(req, token)
  3169. rr = executeRequest(req)
  3170. checkResponseCode(t, http.StatusBadRequest, rr)
  3171. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=a&order=ASC", nil)
  3172. setBearerForReq(req, token)
  3173. rr = executeRequest(req)
  3174. checkResponseCode(t, http.StatusBadRequest, rr)
  3175. req, _ = http.NewRequest(http.MethodGet, userPath+"?limit=1&offset=0&order=ASCa", nil)
  3176. setBearerForReq(req, token)
  3177. rr = executeRequest(req)
  3178. checkResponseCode(t, http.StatusBadRequest, rr)
  3179. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  3180. setBearerForReq(req, token)
  3181. rr = executeRequest(req)
  3182. checkResponseCode(t, http.StatusOK, rr)
  3183. }
  3184. func TestDeleteUserInvalidParamsMock(t *testing.T) {
  3185. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3186. assert.NoError(t, err)
  3187. req, _ := http.NewRequest(http.MethodDelete, userPath+"/0", nil)
  3188. setBearerForReq(req, token)
  3189. rr := executeRequest(req)
  3190. checkResponseCode(t, http.StatusNotFound, rr)
  3191. }
  3192. func TestGetQuotaScansMock(t *testing.T) {
  3193. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3194. assert.NoError(t, err)
  3195. req, err := http.NewRequest("GET", quotaScanPath, nil)
  3196. assert.NoError(t, err)
  3197. setBearerForReq(req, token)
  3198. rr := executeRequest(req)
  3199. checkResponseCode(t, http.StatusOK, rr)
  3200. }
  3201. func TestStartQuotaScanMock(t *testing.T) {
  3202. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3203. assert.NoError(t, err)
  3204. user := getTestUser()
  3205. userAsJSON := getUserAsJSON(t, user)
  3206. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3207. setBearerForReq(req, token)
  3208. rr := executeRequest(req)
  3209. checkResponseCode(t, http.StatusCreated, rr)
  3210. err = render.DecodeJSON(rr.Body, &user)
  3211. assert.NoError(t, err)
  3212. _, err = os.Stat(user.HomeDir)
  3213. if err == nil {
  3214. err = os.Remove(user.HomeDir)
  3215. assert.NoError(t, err)
  3216. }
  3217. // simulate a duplicate quota scan
  3218. userAsJSON = getUserAsJSON(t, user)
  3219. common.QuotaScans.AddUserQuotaScan(user.Username)
  3220. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  3221. setBearerForReq(req, token)
  3222. rr = executeRequest(req)
  3223. checkResponseCode(t, http.StatusConflict, rr)
  3224. assert.True(t, common.QuotaScans.RemoveUserQuotaScan(user.Username))
  3225. userAsJSON = getUserAsJSON(t, user)
  3226. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  3227. setBearerForReq(req, token)
  3228. rr = executeRequest(req)
  3229. checkResponseCode(t, http.StatusAccepted, rr)
  3230. for {
  3231. var scans []common.ActiveQuotaScan
  3232. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  3233. setBearerForReq(req, token)
  3234. rr = executeRequest(req)
  3235. checkResponseCode(t, http.StatusOK, rr)
  3236. err = render.DecodeJSON(rr.Body, &scans)
  3237. if !assert.NoError(t, err, "Error getting active scans") {
  3238. break
  3239. }
  3240. if len(scans) == 0 {
  3241. break
  3242. }
  3243. time.Sleep(100 * time.Millisecond)
  3244. }
  3245. _, err = os.Stat(user.HomeDir)
  3246. if err != nil && os.IsNotExist(err) {
  3247. err = os.MkdirAll(user.HomeDir, os.ModePerm)
  3248. assert.NoError(t, err)
  3249. }
  3250. req, _ = http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  3251. setBearerForReq(req, token)
  3252. rr = executeRequest(req)
  3253. checkResponseCode(t, http.StatusAccepted, rr)
  3254. for {
  3255. var scans []common.ActiveQuotaScan
  3256. req, _ = http.NewRequest(http.MethodGet, quotaScanPath, nil)
  3257. setBearerForReq(req, token)
  3258. rr = executeRequest(req)
  3259. checkResponseCode(t, http.StatusOK, rr)
  3260. err = render.DecodeJSON(rr.Body, &scans)
  3261. if !assert.NoError(t, err) {
  3262. assert.Fail(t, err.Error(), "Error getting active scans")
  3263. break
  3264. }
  3265. if len(scans) == 0 {
  3266. break
  3267. }
  3268. time.Sleep(100 * time.Millisecond)
  3269. }
  3270. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  3271. setBearerForReq(req, token)
  3272. rr = executeRequest(req)
  3273. checkResponseCode(t, http.StatusOK, rr)
  3274. err = os.RemoveAll(user.GetHomeDir())
  3275. assert.NoError(t, err)
  3276. }
  3277. func TestUpdateFolderQuotaUsageMock(t *testing.T) {
  3278. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3279. assert.NoError(t, err)
  3280. mappedPath := filepath.Join(os.TempDir(), "vfolder")
  3281. folderName := filepath.Base(mappedPath)
  3282. f := vfs.BaseVirtualFolder{
  3283. MappedPath: mappedPath,
  3284. Name: folderName,
  3285. }
  3286. usedQuotaFiles := 1
  3287. usedQuotaSize := int64(65535)
  3288. f.UsedQuotaFiles = usedQuotaFiles
  3289. f.UsedQuotaSize = usedQuotaSize
  3290. var folder vfs.BaseVirtualFolder
  3291. folderAsJSON, err := json.Marshal(f)
  3292. assert.NoError(t, err)
  3293. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  3294. setBearerForReq(req, token)
  3295. rr := executeRequest(req)
  3296. checkResponseCode(t, http.StatusCreated, rr)
  3297. err = render.DecodeJSON(rr.Body, &folder)
  3298. assert.NoError(t, err)
  3299. req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaPath, bytes.NewBuffer(folderAsJSON))
  3300. setBearerForReq(req, token)
  3301. rr = executeRequest(req)
  3302. checkResponseCode(t, http.StatusOK, rr)
  3303. var folderGet vfs.BaseVirtualFolder
  3304. req, _ = http.NewRequest(http.MethodGet, path.Join(folderPath, folderName), nil)
  3305. setBearerForReq(req, token)
  3306. rr = executeRequest(req)
  3307. checkResponseCode(t, http.StatusOK, rr)
  3308. err = render.DecodeJSON(rr.Body, &folderGet)
  3309. assert.NoError(t, err)
  3310. assert.Equal(t, usedQuotaFiles, folderGet.UsedQuotaFiles)
  3311. assert.Equal(t, usedQuotaSize, folderGet.UsedQuotaSize)
  3312. req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaPath, bytes.NewBuffer([]byte("string")))
  3313. setBearerForReq(req, token)
  3314. rr = executeRequest(req)
  3315. checkResponseCode(t, http.StatusBadRequest, rr)
  3316. assert.True(t, common.QuotaScans.AddVFolderQuotaScan(folderName))
  3317. req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaPath, bytes.NewBuffer(folderAsJSON))
  3318. setBearerForReq(req, token)
  3319. rr = executeRequest(req)
  3320. checkResponseCode(t, http.StatusConflict, rr)
  3321. assert.True(t, common.QuotaScans.RemoveVFolderQuotaScan(folderName))
  3322. req, _ = http.NewRequest(http.MethodDelete, path.Join(folderPath, folderName), nil)
  3323. setBearerForReq(req, token)
  3324. rr = executeRequest(req)
  3325. checkResponseCode(t, http.StatusOK, rr)
  3326. }
  3327. func TestStartFolderQuotaScanMock(t *testing.T) {
  3328. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3329. assert.NoError(t, err)
  3330. mappedPath := filepath.Join(os.TempDir(), "vfolder")
  3331. folderName := filepath.Base(mappedPath)
  3332. folder := vfs.BaseVirtualFolder{
  3333. Name: folderName,
  3334. MappedPath: mappedPath,
  3335. }
  3336. folderAsJSON, err := json.Marshal(folder)
  3337. assert.NoError(t, err)
  3338. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  3339. setBearerForReq(req, token)
  3340. rr := executeRequest(req)
  3341. checkResponseCode(t, http.StatusCreated, rr)
  3342. _, err = os.Stat(mappedPath)
  3343. if err == nil {
  3344. err = os.Remove(mappedPath)
  3345. assert.NoError(t, err)
  3346. }
  3347. // simulate a duplicate quota scan
  3348. common.QuotaScans.AddVFolderQuotaScan(folderName)
  3349. req, _ = http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer(folderAsJSON))
  3350. setBearerForReq(req, token)
  3351. rr = executeRequest(req)
  3352. checkResponseCode(t, http.StatusConflict, rr)
  3353. assert.True(t, common.QuotaScans.RemoveVFolderQuotaScan(folderName))
  3354. // and now a real quota scan
  3355. _, err = os.Stat(mappedPath)
  3356. if err != nil && os.IsNotExist(err) {
  3357. err = os.MkdirAll(mappedPath, os.ModePerm)
  3358. assert.NoError(t, err)
  3359. }
  3360. req, _ = http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer(folderAsJSON))
  3361. setBearerForReq(req, token)
  3362. rr = executeRequest(req)
  3363. checkResponseCode(t, http.StatusAccepted, rr)
  3364. var scans []common.ActiveVirtualFolderQuotaScan
  3365. for {
  3366. req, _ = http.NewRequest(http.MethodGet, quotaScanVFolderPath, nil)
  3367. setBearerForReq(req, token)
  3368. rr = executeRequest(req)
  3369. checkResponseCode(t, http.StatusOK, rr)
  3370. err = render.DecodeJSON(rr.Body, &scans)
  3371. if !assert.NoError(t, err, "Error getting active folders scans") {
  3372. break
  3373. }
  3374. if len(scans) == 0 {
  3375. break
  3376. }
  3377. time.Sleep(100 * time.Millisecond)
  3378. }
  3379. // cleanup
  3380. req, _ = http.NewRequest(http.MethodDelete, path.Join(folderPath, folderName), nil)
  3381. setBearerForReq(req, token)
  3382. rr = executeRequest(req)
  3383. checkResponseCode(t, http.StatusOK, rr)
  3384. err = os.RemoveAll(folderPath)
  3385. assert.NoError(t, err)
  3386. err = os.RemoveAll(mappedPath)
  3387. assert.NoError(t, err)
  3388. }
  3389. func TestStartQuotaScanNonExistentUserMock(t *testing.T) {
  3390. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3391. assert.NoError(t, err)
  3392. user := getTestUser()
  3393. userAsJSON := getUserAsJSON(t, user)
  3394. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer(userAsJSON))
  3395. setBearerForReq(req, token)
  3396. rr := executeRequest(req)
  3397. checkResponseCode(t, http.StatusNotFound, rr)
  3398. }
  3399. func TestStartQuotaScanBadUserMock(t *testing.T) {
  3400. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3401. assert.NoError(t, err)
  3402. req, _ := http.NewRequest(http.MethodPost, quotaScanPath, bytes.NewBuffer([]byte("invalid json")))
  3403. setBearerForReq(req, token)
  3404. rr := executeRequest(req)
  3405. checkResponseCode(t, http.StatusBadRequest, rr)
  3406. }
  3407. func TestStartQuotaScanBadFolderMock(t *testing.T) {
  3408. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3409. assert.NoError(t, err)
  3410. req, _ := http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer([]byte("invalid json")))
  3411. setBearerForReq(req, token)
  3412. rr := executeRequest(req)
  3413. checkResponseCode(t, http.StatusBadRequest, rr)
  3414. }
  3415. func TestStartQuotaScanNonExistentFolderMock(t *testing.T) {
  3416. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3417. assert.NoError(t, err)
  3418. folder := vfs.BaseVirtualFolder{
  3419. MappedPath: os.TempDir(),
  3420. Name: "afolder",
  3421. }
  3422. folderAsJSON, err := json.Marshal(folder)
  3423. assert.NoError(t, err)
  3424. req, _ := http.NewRequest(http.MethodPost, quotaScanVFolderPath, bytes.NewBuffer(folderAsJSON))
  3425. setBearerForReq(req, token)
  3426. rr := executeRequest(req)
  3427. checkResponseCode(t, http.StatusNotFound, rr)
  3428. }
  3429. func TestGetFoldersMock(t *testing.T) {
  3430. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3431. assert.NoError(t, err)
  3432. mappedPath := filepath.Join(os.TempDir(), "vfolder")
  3433. folderName := filepath.Base(mappedPath)
  3434. folder := vfs.BaseVirtualFolder{
  3435. Name: folderName,
  3436. MappedPath: mappedPath,
  3437. }
  3438. folderAsJSON, err := json.Marshal(folder)
  3439. assert.NoError(t, err)
  3440. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  3441. setBearerForReq(req, token)
  3442. rr := executeRequest(req)
  3443. checkResponseCode(t, http.StatusCreated, rr)
  3444. err = render.DecodeJSON(rr.Body, &folder)
  3445. assert.NoError(t, err)
  3446. var folders []vfs.BaseVirtualFolder
  3447. url, err := url.Parse(folderPath + "?limit=510&offset=0&order=DESC")
  3448. assert.NoError(t, err)
  3449. req, _ = http.NewRequest(http.MethodGet, url.String(), nil)
  3450. setBearerForReq(req, token)
  3451. rr = executeRequest(req)
  3452. checkResponseCode(t, http.StatusOK, rr)
  3453. err = render.DecodeJSON(rr.Body, &folders)
  3454. assert.NoError(t, err)
  3455. assert.GreaterOrEqual(t, len(folders), 1)
  3456. req, _ = http.NewRequest(http.MethodGet, folderPath+"?limit=a&offset=0&order=ASC", nil)
  3457. setBearerForReq(req, token)
  3458. rr = executeRequest(req)
  3459. checkResponseCode(t, http.StatusBadRequest, rr)
  3460. req, _ = http.NewRequest(http.MethodGet, folderPath+"?limit=1&offset=a&order=ASC", nil)
  3461. setBearerForReq(req, token)
  3462. rr = executeRequest(req)
  3463. checkResponseCode(t, http.StatusBadRequest, rr)
  3464. req, _ = http.NewRequest(http.MethodGet, folderPath+"?limit=1&offset=0&order=ASCa", nil)
  3465. setBearerForReq(req, token)
  3466. rr = executeRequest(req)
  3467. checkResponseCode(t, http.StatusBadRequest, rr)
  3468. req, _ = http.NewRequest(http.MethodDelete, path.Join(folderPath, folderName), nil)
  3469. setBearerForReq(req, token)
  3470. rr = executeRequest(req)
  3471. checkResponseCode(t, http.StatusOK, rr)
  3472. }
  3473. func TestGetVersionMock(t *testing.T) {
  3474. req, _ := http.NewRequest(http.MethodGet, versionPath, nil)
  3475. rr := executeRequest(req)
  3476. checkResponseCode(t, http.StatusUnauthorized, rr)
  3477. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3478. assert.NoError(t, err)
  3479. req, _ = http.NewRequest(http.MethodGet, versionPath, nil)
  3480. setBearerForReq(req, token)
  3481. rr = executeRequest(req)
  3482. checkResponseCode(t, http.StatusOK, rr)
  3483. req, _ = http.NewRequest(http.MethodGet, versionPath, nil)
  3484. setBearerForReq(req, "abcde")
  3485. rr = executeRequest(req)
  3486. checkResponseCode(t, http.StatusUnauthorized, rr)
  3487. }
  3488. func TestGetConnectionsMock(t *testing.T) {
  3489. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3490. assert.NoError(t, err)
  3491. req, _ := http.NewRequest(http.MethodGet, activeConnectionsPath, nil)
  3492. setBearerForReq(req, token)
  3493. rr := executeRequest(req)
  3494. checkResponseCode(t, http.StatusOK, rr)
  3495. }
  3496. func TestGetStatusMock(t *testing.T) {
  3497. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3498. assert.NoError(t, err)
  3499. req, _ := http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3500. setBearerForReq(req, token)
  3501. rr := executeRequest(req)
  3502. checkResponseCode(t, http.StatusOK, rr)
  3503. }
  3504. func TestDeleteActiveConnectionMock(t *testing.T) {
  3505. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3506. assert.NoError(t, err)
  3507. req, _ := http.NewRequest(http.MethodDelete, activeConnectionsPath+"/connectionID", nil)
  3508. setBearerForReq(req, token)
  3509. rr := executeRequest(req)
  3510. checkResponseCode(t, http.StatusNotFound, rr)
  3511. }
  3512. func TestNotFoundMock(t *testing.T) {
  3513. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3514. assert.NoError(t, err)
  3515. req, _ := http.NewRequest(http.MethodGet, "/non/existing/path", nil)
  3516. setBearerForReq(req, token)
  3517. rr := executeRequest(req)
  3518. checkResponseCode(t, http.StatusNotFound, rr)
  3519. }
  3520. func TestMethodNotAllowedMock(t *testing.T) {
  3521. req, _ := http.NewRequest(http.MethodPost, activeConnectionsPath, nil)
  3522. rr := executeRequest(req)
  3523. checkResponseCode(t, http.StatusMethodNotAllowed, rr)
  3524. }
  3525. func TestHealthCheck(t *testing.T) {
  3526. req, _ := http.NewRequest(http.MethodGet, "/healthz", nil)
  3527. rr := executeRequest(req)
  3528. checkResponseCode(t, http.StatusOK, rr)
  3529. assert.Equal(t, "ok", rr.Body.String())
  3530. }
  3531. func TestGetWebRootMock(t *testing.T) {
  3532. req, _ := http.NewRequest(http.MethodGet, "/", nil)
  3533. rr := executeRequest(req)
  3534. checkResponseCode(t, http.StatusMovedPermanently, rr)
  3535. req, _ = http.NewRequest(http.MethodGet, webBasePath, nil)
  3536. rr = executeRequest(req)
  3537. checkResponseCode(t, http.StatusMovedPermanently, rr)
  3538. }
  3539. func TestWebNotFoundURI(t *testing.T) {
  3540. urlString := httpBaseURL + webBasePath + "/a"
  3541. req, err := http.NewRequest(http.MethodGet, urlString, nil)
  3542. assert.NoError(t, err)
  3543. resp, err := httpclient.GetHTTPClient().Do(req)
  3544. require.NoError(t, err)
  3545. defer resp.Body.Close()
  3546. assert.Equal(t, http.StatusNotFound, resp.StatusCode)
  3547. req, err = http.NewRequest(http.MethodGet, urlString, nil)
  3548. assert.NoError(t, err)
  3549. setJWTCookieForReq(req, "invalid token")
  3550. resp, err = httpclient.GetHTTPClient().Do(req)
  3551. require.NoError(t, err)
  3552. defer resp.Body.Close()
  3553. assert.Equal(t, http.StatusNotFound, resp.StatusCode)
  3554. }
  3555. func TestLogout(t *testing.T) {
  3556. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3557. assert.NoError(t, err)
  3558. req, _ := http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3559. setBearerForReq(req, token)
  3560. rr := executeRequest(req)
  3561. checkResponseCode(t, http.StatusOK, rr)
  3562. req, _ = http.NewRequest(http.MethodGet, logoutPath, nil)
  3563. setBearerForReq(req, token)
  3564. rr = executeRequest(req)
  3565. checkResponseCode(t, http.StatusOK, rr)
  3566. req, _ = http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3567. setBearerForReq(req, token)
  3568. rr = executeRequest(req)
  3569. checkResponseCode(t, http.StatusUnauthorized, rr)
  3570. assert.Contains(t, rr.Body.String(), "Your token is no longer valid")
  3571. }
  3572. func TestTokenHeaderCookie(t *testing.T) {
  3573. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3574. assert.NoError(t, err)
  3575. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3576. assert.NoError(t, err)
  3577. req, _ := http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3578. setJWTCookieForReq(req, apiToken)
  3579. rr := executeRequest(req)
  3580. checkResponseCode(t, http.StatusUnauthorized, rr)
  3581. assert.Contains(t, rr.Body.String(), "no token found")
  3582. req, _ = http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3583. setBearerForReq(req, apiToken)
  3584. rr = executeRequest(req)
  3585. checkResponseCode(t, http.StatusOK, rr)
  3586. req, _ = http.NewRequest(http.MethodGet, webStatusPath, nil)
  3587. setBearerForReq(req, webToken)
  3588. rr = executeRequest(req)
  3589. checkResponseCode(t, http.StatusFound, rr)
  3590. assert.Equal(t, webLoginPath, rr.Header().Get("Location"))
  3591. req, _ = http.NewRequest(http.MethodGet, webStatusPath, nil)
  3592. setJWTCookieForReq(req, webToken)
  3593. rr = executeRequest(req)
  3594. checkResponseCode(t, http.StatusOK, rr)
  3595. }
  3596. func TestTokenAudience(t *testing.T) {
  3597. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3598. assert.NoError(t, err)
  3599. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3600. assert.NoError(t, err)
  3601. req, _ := http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3602. setBearerForReq(req, apiToken)
  3603. rr := executeRequest(req)
  3604. checkResponseCode(t, http.StatusOK, rr)
  3605. req, _ = http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3606. setBearerForReq(req, webToken)
  3607. rr = executeRequest(req)
  3608. checkResponseCode(t, http.StatusUnauthorized, rr)
  3609. assert.Contains(t, rr.Body.String(), "Your token audience is not valid")
  3610. req, _ = http.NewRequest(http.MethodGet, webStatusPath, nil)
  3611. setJWTCookieForReq(req, webToken)
  3612. rr = executeRequest(req)
  3613. checkResponseCode(t, http.StatusOK, rr)
  3614. req, _ = http.NewRequest(http.MethodGet, webStatusPath, nil)
  3615. setJWTCookieForReq(req, apiToken)
  3616. rr = executeRequest(req)
  3617. checkResponseCode(t, http.StatusFound, rr)
  3618. assert.Equal(t, webLoginPath, rr.Header().Get("Location"))
  3619. }
  3620. func TestWebLoginMock(t *testing.T) {
  3621. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3622. assert.NoError(t, err)
  3623. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3624. assert.NoError(t, err)
  3625. req, _ := http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3626. setBearerForReq(req, apiToken)
  3627. rr := executeRequest(req)
  3628. checkResponseCode(t, http.StatusOK, rr)
  3629. req, _ = http.NewRequest(http.MethodGet, webStatusPath+"notfound", nil)
  3630. req.RequestURI = webStatusPath + "notfound"
  3631. setJWTCookieForReq(req, webToken)
  3632. rr = executeRequest(req)
  3633. checkResponseCode(t, http.StatusNotFound, rr)
  3634. req, _ = http.NewRequest(http.MethodGet, webStatusPath, nil)
  3635. setJWTCookieForReq(req, webToken)
  3636. rr = executeRequest(req)
  3637. checkResponseCode(t, http.StatusOK, rr)
  3638. req, _ = http.NewRequest(http.MethodGet, webLogoutPath, nil)
  3639. setJWTCookieForReq(req, webToken)
  3640. rr = executeRequest(req)
  3641. checkResponseCode(t, http.StatusFound, rr)
  3642. cookie := rr.Header().Get("Cookie")
  3643. assert.Empty(t, cookie)
  3644. req, _ = http.NewRequest(http.MethodGet, logoutPath, nil)
  3645. setBearerForReq(req, apiToken)
  3646. rr = executeRequest(req)
  3647. checkResponseCode(t, http.StatusOK, rr)
  3648. req, _ = http.NewRequest(http.MethodGet, serverStatusPath, nil)
  3649. setBearerForReq(req, apiToken)
  3650. rr = executeRequest(req)
  3651. checkResponseCode(t, http.StatusUnauthorized, rr)
  3652. assert.Contains(t, rr.Body.String(), "Your token is no longer valid")
  3653. req, _ = http.NewRequest(http.MethodGet, webStatusPath, nil)
  3654. setJWTCookieForReq(req, webToken)
  3655. rr = executeRequest(req)
  3656. checkResponseCode(t, http.StatusFound, rr)
  3657. // now try using wrong credentials
  3658. form := getAdminLoginForm(defaultTokenAuthUser, "wrong pwd")
  3659. req, _ = http.NewRequest(http.MethodPost, webLoginPath, bytes.NewBuffer([]byte(form.Encode())))
  3660. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3661. rr = executeRequest(req)
  3662. checkResponseCode(t, http.StatusOK, rr)
  3663. // try from an ip not allowed
  3664. a := getTestAdmin()
  3665. a.Username = altAdminUsername
  3666. a.Password = altAdminPassword
  3667. a.Filters.AllowList = []string{"10.0.0.0/8"}
  3668. _, _, err = httpdtest.AddAdmin(a, http.StatusCreated)
  3669. assert.NoError(t, err)
  3670. form = getAdminLoginForm(altAdminUsername, altAdminPassword)
  3671. req, _ = http.NewRequest(http.MethodPost, webLoginPath, bytes.NewBuffer([]byte(form.Encode())))
  3672. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3673. req.RemoteAddr = "127.1.1.1:1234"
  3674. rr = executeRequest(req)
  3675. checkResponseCode(t, http.StatusOK, rr)
  3676. assert.Contains(t, rr.Body.String(), "login from IP 127.1.1.1 not allowed")
  3677. req, _ = http.NewRequest(http.MethodPost, webLoginPath, bytes.NewBuffer([]byte(form.Encode())))
  3678. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3679. req.RemoteAddr = "10.9.9.9:1234"
  3680. rr = executeRequest(req)
  3681. checkResponseCode(t, http.StatusFound, rr)
  3682. req, _ = http.NewRequest(http.MethodPost, webLoginPath, bytes.NewBuffer([]byte(form.Encode())))
  3683. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3684. req.RemoteAddr = "127.0.1.1:4567"
  3685. req.Header.Set("X-Forwarded-For", "10.9.9.9")
  3686. rr = executeRequest(req)
  3687. checkResponseCode(t, http.StatusOK, rr)
  3688. assert.Contains(t, rr.Body.String(), "Login from IP 127.0.1.1:4567 is not allowed")
  3689. req, _ = http.NewRequest(http.MethodGet, webLoginPath, nil)
  3690. rr = executeRequest(req)
  3691. checkResponseCode(t, http.StatusOK, rr)
  3692. _, err = httpdtest.RemoveAdmin(a, http.StatusOK)
  3693. assert.NoError(t, err)
  3694. }
  3695. func TestAdminNoToken(t *testing.T) {
  3696. req, _ := http.NewRequest(http.MethodGet, webChangeAdminPwdPath, nil)
  3697. rr := executeRequest(req)
  3698. checkResponseCode(t, http.StatusFound, rr)
  3699. assert.Equal(t, webLoginPath, rr.Header().Get("Location"))
  3700. req, _ = http.NewRequest(http.MethodGet, webUserPath, nil)
  3701. rr = executeRequest(req)
  3702. checkResponseCode(t, http.StatusFound, rr)
  3703. assert.Equal(t, webLoginPath, rr.Header().Get("Location"))
  3704. req, _ = http.NewRequest(http.MethodGet, userPath, nil)
  3705. rr = executeRequest(req)
  3706. checkResponseCode(t, http.StatusUnauthorized, rr)
  3707. req, _ = http.NewRequest(http.MethodGet, activeConnectionsPath, nil)
  3708. rr = executeRequest(req)
  3709. checkResponseCode(t, http.StatusUnauthorized, rr)
  3710. }
  3711. func TestWebAdminPwdChange(t *testing.T) {
  3712. admin := getTestAdmin()
  3713. admin.Username = altAdminUsername
  3714. admin.Password = altAdminPassword
  3715. admin, _, err := httpdtest.AddAdmin(admin, http.StatusCreated)
  3716. assert.NoError(t, err)
  3717. token, err := getJWTWebTokenFromTestServer(admin.Username, altAdminPassword)
  3718. assert.NoError(t, err)
  3719. req, _ := http.NewRequest(http.MethodGet, webChangeAdminPwdPath, nil)
  3720. setJWTCookieForReq(req, token)
  3721. rr := executeRequest(req)
  3722. checkResponseCode(t, http.StatusOK, rr)
  3723. form := make(url.Values)
  3724. form.Set("current_password", altAdminPassword)
  3725. form.Set("new_password1", altAdminPassword)
  3726. form.Set("new_password2", altAdminPassword)
  3727. req, _ = http.NewRequest(http.MethodPost, webChangeAdminPwdPath, bytes.NewBuffer([]byte(form.Encode())))
  3728. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3729. setJWTCookieForReq(req, token)
  3730. rr = executeRequest(req)
  3731. checkResponseCode(t, http.StatusOK, rr)
  3732. assert.Contains(t, rr.Body.String(), "the new password must be different from the current one")
  3733. form.Set("new_password1", altAdminPassword+"1")
  3734. form.Set("new_password2", altAdminPassword+"1")
  3735. req, _ = http.NewRequest(http.MethodPost, webChangeAdminPwdPath, bytes.NewBuffer([]byte(form.Encode())))
  3736. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3737. setJWTCookieForReq(req, token)
  3738. rr = executeRequest(req)
  3739. checkResponseCode(t, http.StatusFound, rr)
  3740. assert.Equal(t, webLoginPath, rr.Header().Get("Location"))
  3741. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  3742. assert.NoError(t, err)
  3743. }
  3744. func TestBasicWebUsersMock(t *testing.T) {
  3745. token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3746. assert.NoError(t, err)
  3747. user := getTestUser()
  3748. userAsJSON := getUserAsJSON(t, user)
  3749. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  3750. setBearerForReq(req, token)
  3751. rr := executeRequest(req)
  3752. checkResponseCode(t, http.StatusCreated, rr)
  3753. err = render.DecodeJSON(rr.Body, &user)
  3754. assert.NoError(t, err)
  3755. user1 := getTestUser()
  3756. user1.Username += "1"
  3757. user1AsJSON := getUserAsJSON(t, user1)
  3758. req, _ = http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(user1AsJSON))
  3759. setBearerForReq(req, token)
  3760. rr = executeRequest(req)
  3761. checkResponseCode(t, http.StatusCreated, rr)
  3762. err = render.DecodeJSON(rr.Body, &user1)
  3763. assert.NoError(t, err)
  3764. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3765. assert.NoError(t, err)
  3766. req, _ = http.NewRequest(http.MethodGet, webUsersPath, nil)
  3767. setJWTCookieForReq(req, webToken)
  3768. rr = executeRequest(req)
  3769. checkResponseCode(t, http.StatusOK, rr)
  3770. req, _ = http.NewRequest(http.MethodGet, webUsersPath+"?qlimit=a", nil)
  3771. setJWTCookieForReq(req, webToken)
  3772. rr = executeRequest(req)
  3773. checkResponseCode(t, http.StatusOK, rr)
  3774. req, _ = http.NewRequest(http.MethodGet, webUsersPath+"?qlimit=1", nil)
  3775. setJWTCookieForReq(req, webToken)
  3776. rr = executeRequest(req)
  3777. checkResponseCode(t, http.StatusOK, rr)
  3778. req, _ = http.NewRequest(http.MethodGet, webUserPath, nil)
  3779. setJWTCookieForReq(req, webToken)
  3780. rr = executeRequest(req)
  3781. checkResponseCode(t, http.StatusOK, rr)
  3782. req, _ = http.NewRequest(http.MethodGet, path.Join(webUserPath, user.Username), nil)
  3783. setJWTCookieForReq(req, webToken)
  3784. rr = executeRequest(req)
  3785. checkResponseCode(t, http.StatusOK, rr)
  3786. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/0", nil)
  3787. setJWTCookieForReq(req, webToken)
  3788. rr = executeRequest(req)
  3789. checkResponseCode(t, http.StatusNotFound, rr)
  3790. form := make(url.Values)
  3791. form.Set("username", user.Username)
  3792. b, contentType, _ := getMultipartFormData(form, "", "")
  3793. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  3794. setJWTCookieForReq(req, webToken)
  3795. req.Header.Set("Content-Type", contentType)
  3796. rr = executeRequest(req)
  3797. checkResponseCode(t, http.StatusOK, rr)
  3798. b, contentType, _ = getMultipartFormData(form, "", "")
  3799. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  3800. setJWTCookieForReq(req, webToken)
  3801. req.Header.Set("Content-Type", contentType)
  3802. rr = executeRequest(req)
  3803. checkResponseCode(t, http.StatusOK, rr)
  3804. b, contentType, _ = getMultipartFormData(form, "", "")
  3805. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/0", &b)
  3806. setJWTCookieForReq(req, webToken)
  3807. req.Header.Set("Content-Type", contentType)
  3808. rr = executeRequest(req)
  3809. checkResponseCode(t, http.StatusNotFound, rr)
  3810. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/aaa", &b)
  3811. setJWTCookieForReq(req, webToken)
  3812. req.Header.Set("Content-Type", contentType)
  3813. rr = executeRequest(req)
  3814. checkResponseCode(t, http.StatusNotFound, rr)
  3815. req, _ = http.NewRequest(http.MethodDelete, path.Join(webUserPath, user.Username), nil)
  3816. setJWTCookieForReq(req, webToken)
  3817. rr = executeRequest(req)
  3818. checkResponseCode(t, http.StatusOK, rr)
  3819. req, _ = http.NewRequest(http.MethodDelete, path.Join(webUserPath, user1.Username), nil)
  3820. setJWTCookieForReq(req, webToken)
  3821. rr = executeRequest(req)
  3822. checkResponseCode(t, http.StatusOK, rr)
  3823. }
  3824. func TestWebAdminBasicMock(t *testing.T) {
  3825. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3826. assert.NoError(t, err)
  3827. admin := getTestAdmin()
  3828. admin.Username = altAdminUsername
  3829. admin.Password = altAdminPassword
  3830. form := make(url.Values)
  3831. form.Set("username", admin.Username)
  3832. form.Set("password", "")
  3833. form.Set("status", "a") // invalid status
  3834. form.Set("permissions", "*")
  3835. req, _ := http.NewRequest(http.MethodPost, webAdminPath, bytes.NewBuffer([]byte(form.Encode())))
  3836. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3837. setJWTCookieForReq(req, token)
  3838. rr := executeRequest(req)
  3839. checkResponseCode(t, http.StatusOK, rr)
  3840. form.Set("status", "1")
  3841. req, _ = http.NewRequest(http.MethodPost, webAdminPath, bytes.NewBuffer([]byte(form.Encode())))
  3842. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3843. setJWTCookieForReq(req, token)
  3844. rr = executeRequest(req)
  3845. checkResponseCode(t, http.StatusOK, rr)
  3846. form.Set("password", admin.Password)
  3847. req, _ = http.NewRequest(http.MethodPost, webAdminPath, bytes.NewBuffer([]byte(form.Encode())))
  3848. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3849. setJWTCookieForReq(req, token)
  3850. rr = executeRequest(req)
  3851. checkResponseCode(t, http.StatusSeeOther, rr)
  3852. _, _, err = httpdtest.GetAdminByUsername(altAdminUsername, http.StatusOK)
  3853. assert.NoError(t, err)
  3854. req, _ = http.NewRequest(http.MethodGet, webAdminsPath+"?qlimit=a", nil)
  3855. setJWTCookieForReq(req, token)
  3856. rr = executeRequest(req)
  3857. checkResponseCode(t, http.StatusOK, rr)
  3858. req, _ = http.NewRequest(http.MethodGet, webAdminsPath+"?qlimit=1", nil)
  3859. setJWTCookieForReq(req, token)
  3860. rr = executeRequest(req)
  3861. checkResponseCode(t, http.StatusOK, rr)
  3862. req, _ = http.NewRequest(http.MethodGet, webAdminPath, nil)
  3863. setJWTCookieForReq(req, token)
  3864. rr = executeRequest(req)
  3865. checkResponseCode(t, http.StatusOK, rr)
  3866. form.Set("password", "")
  3867. req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
  3868. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3869. setJWTCookieForReq(req, token)
  3870. rr = executeRequest(req)
  3871. checkResponseCode(t, http.StatusSeeOther, rr)
  3872. form.Set("email", "not-an-email")
  3873. req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
  3874. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3875. setJWTCookieForReq(req, token)
  3876. rr = executeRequest(req)
  3877. checkResponseCode(t, http.StatusOK, rr)
  3878. form.Set("email", "")
  3879. form.Set("status", "b")
  3880. req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
  3881. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3882. setJWTCookieForReq(req, token)
  3883. rr = executeRequest(req)
  3884. checkResponseCode(t, http.StatusOK, rr)
  3885. form.Set("email", "[email protected]")
  3886. form.Set("status", "0")
  3887. req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
  3888. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3889. setJWTCookieForReq(req, token)
  3890. rr = executeRequest(req)
  3891. checkResponseCode(t, http.StatusSeeOther, rr)
  3892. req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername+"1"), bytes.NewBuffer([]byte(form.Encode())))
  3893. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3894. setJWTCookieForReq(req, token)
  3895. rr = executeRequest(req)
  3896. checkResponseCode(t, http.StatusNotFound, rr)
  3897. req, _ = http.NewRequest(http.MethodGet, path.Join(webAdminPath, altAdminUsername), nil)
  3898. setJWTCookieForReq(req, token)
  3899. rr = executeRequest(req)
  3900. checkResponseCode(t, http.StatusOK, rr)
  3901. req, _ = http.NewRequest(http.MethodGet, path.Join(webAdminPath, altAdminUsername+"1"), nil)
  3902. setJWTCookieForReq(req, token)
  3903. rr = executeRequest(req)
  3904. checkResponseCode(t, http.StatusNotFound, rr)
  3905. req, _ = http.NewRequest(http.MethodDelete, path.Join(webAdminPath, altAdminUsername), nil)
  3906. setJWTCookieForReq(req, token)
  3907. rr = executeRequest(req)
  3908. checkResponseCode(t, http.StatusOK, rr)
  3909. _, err = httpdtest.RemoveAdmin(admin, http.StatusNotFound)
  3910. assert.NoError(t, err)
  3911. req, _ = http.NewRequest(http.MethodDelete, path.Join(webAdminPath, defaultTokenAuthUser), nil)
  3912. setJWTCookieForReq(req, token)
  3913. rr = executeRequest(req)
  3914. checkResponseCode(t, http.StatusBadRequest, rr)
  3915. assert.Contains(t, rr.Body.String(), "You cannot delete yourself")
  3916. }
  3917. func TestWebAdminPermissions(t *testing.T) {
  3918. admin := getTestAdmin()
  3919. admin.Username = altAdminUsername
  3920. admin.Password = altAdminPassword
  3921. admin.Permissions = []string{dataprovider.PermAdminAddUsers}
  3922. _, _, err := httpdtest.AddAdmin(admin, http.StatusCreated)
  3923. assert.NoError(t, err)
  3924. token, err := getJWTWebToken(altAdminUsername, altAdminPassword)
  3925. require.NoError(t, err)
  3926. req, err := http.NewRequest(http.MethodGet, httpBaseURL+webUserPath, nil)
  3927. assert.NoError(t, err)
  3928. setJWTCookieForReq(req, token)
  3929. resp, err := httpclient.GetHTTPClient().Do(req)
  3930. require.NoError(t, err)
  3931. defer resp.Body.Close()
  3932. assert.Equal(t, http.StatusOK, resp.StatusCode)
  3933. req, err = http.NewRequest(http.MethodGet, httpBaseURL+path.Join(webUserPath, "auser"), nil)
  3934. assert.NoError(t, err)
  3935. setJWTCookieForReq(req, token)
  3936. resp, err = httpclient.GetHTTPClient().Do(req)
  3937. require.NoError(t, err)
  3938. defer resp.Body.Close()
  3939. assert.Equal(t, http.StatusForbidden, resp.StatusCode)
  3940. req, err = http.NewRequest(http.MethodGet, httpBaseURL+webFolderPath, nil)
  3941. assert.NoError(t, err)
  3942. setJWTCookieForReq(req, token)
  3943. resp, err = httpclient.GetHTTPClient().Do(req)
  3944. require.NoError(t, err)
  3945. defer resp.Body.Close()
  3946. assert.Equal(t, http.StatusOK, resp.StatusCode)
  3947. req, err = http.NewRequest(http.MethodGet, httpBaseURL+webStatusPath, nil)
  3948. assert.NoError(t, err)
  3949. setJWTCookieForReq(req, token)
  3950. resp, err = httpclient.GetHTTPClient().Do(req)
  3951. require.NoError(t, err)
  3952. defer resp.Body.Close()
  3953. assert.Equal(t, http.StatusForbidden, resp.StatusCode)
  3954. req, err = http.NewRequest(http.MethodGet, httpBaseURL+webConnectionsPath, nil)
  3955. assert.NoError(t, err)
  3956. setJWTCookieForReq(req, token)
  3957. resp, err = httpclient.GetHTTPClient().Do(req)
  3958. require.NoError(t, err)
  3959. defer resp.Body.Close()
  3960. assert.Equal(t, http.StatusForbidden, resp.StatusCode)
  3961. req, err = http.NewRequest(http.MethodGet, httpBaseURL+webAdminPath, nil)
  3962. assert.NoError(t, err)
  3963. setJWTCookieForReq(req, token)
  3964. resp, err = httpclient.GetHTTPClient().Do(req)
  3965. require.NoError(t, err)
  3966. defer resp.Body.Close()
  3967. assert.Equal(t, http.StatusForbidden, resp.StatusCode)
  3968. req, err = http.NewRequest(http.MethodGet, httpBaseURL+path.Join(webAdminPath, "a"), nil)
  3969. assert.NoError(t, err)
  3970. setJWTCookieForReq(req, token)
  3971. resp, err = httpclient.GetHTTPClient().Do(req)
  3972. require.NoError(t, err)
  3973. defer resp.Body.Close()
  3974. assert.Equal(t, http.StatusForbidden, resp.StatusCode)
  3975. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  3976. assert.NoError(t, err)
  3977. }
  3978. func TestAdminUpdateSelfMock(t *testing.T) {
  3979. admin, _, err := httpdtest.GetAdminByUsername(defaultTokenAuthUser, http.StatusOK)
  3980. assert.NoError(t, err)
  3981. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  3982. assert.NoError(t, err)
  3983. form := make(url.Values)
  3984. form.Set("username", admin.Username)
  3985. form.Set("password", admin.Password)
  3986. form.Set("status", "0")
  3987. form.Set("permissions", dataprovider.PermAdminAddUsers)
  3988. form.Set("permissions", dataprovider.PermAdminCloseConnections)
  3989. req, _ := http.NewRequest(http.MethodPost, path.Join(webAdminPath, defaultTokenAuthUser), bytes.NewBuffer([]byte(form.Encode())))
  3990. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3991. setJWTCookieForReq(req, token)
  3992. rr := executeRequest(req)
  3993. checkResponseCode(t, http.StatusOK, rr)
  3994. assert.Contains(t, rr.Body.String(), "You cannot remove these permissions to yourself")
  3995. form.Set("permissions", dataprovider.PermAdminAny)
  3996. req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, defaultTokenAuthUser), bytes.NewBuffer([]byte(form.Encode())))
  3997. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  3998. setJWTCookieForReq(req, token)
  3999. rr = executeRequest(req)
  4000. checkResponseCode(t, http.StatusOK, rr)
  4001. assert.Contains(t, rr.Body.String(), "You cannot disable yourself")
  4002. }
  4003. func TestWebMaintenanceMock(t *testing.T) {
  4004. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4005. assert.NoError(t, err)
  4006. req, _ := http.NewRequest(http.MethodGet, webMaintenancePath, nil)
  4007. setJWTCookieForReq(req, token)
  4008. rr := executeRequest(req)
  4009. checkResponseCode(t, http.StatusOK, rr)
  4010. form := make(url.Values)
  4011. form.Set("mode", "a")
  4012. b, contentType, _ := getMultipartFormData(form, "", "")
  4013. req, _ = http.NewRequest(http.MethodPost, webRestorePath, &b)
  4014. setJWTCookieForReq(req, token)
  4015. req.Header.Set("Content-Type", contentType)
  4016. rr = executeRequest(req)
  4017. checkResponseCode(t, http.StatusOK, rr)
  4018. form.Set("mode", "0")
  4019. form.Set("quota", "a")
  4020. b, contentType, _ = getMultipartFormData(form, "", "")
  4021. req, _ = http.NewRequest(http.MethodPost, webRestorePath, &b)
  4022. setJWTCookieForReq(req, token)
  4023. req.Header.Set("Content-Type", contentType)
  4024. rr = executeRequest(req)
  4025. checkResponseCode(t, http.StatusOK, rr)
  4026. form.Set("quota", "0")
  4027. b, contentType, _ = getMultipartFormData(form, "", "")
  4028. req, _ = http.NewRequest(http.MethodPost, webRestorePath, &b)
  4029. setJWTCookieForReq(req, token)
  4030. req.Header.Set("Content-Type", contentType)
  4031. rr = executeRequest(req)
  4032. checkResponseCode(t, http.StatusOK, rr)
  4033. req, _ = http.NewRequest(http.MethodPost, webRestorePath+"?a=%3", &b)
  4034. setJWTCookieForReq(req, token)
  4035. req.Header.Set("Content-Type", contentType)
  4036. rr = executeRequest(req)
  4037. checkResponseCode(t, http.StatusOK, rr)
  4038. backupFilePath := filepath.Join(os.TempDir(), "backup.json")
  4039. err = createTestFile(backupFilePath, 0)
  4040. assert.NoError(t, err)
  4041. b, contentType, _ = getMultipartFormData(form, "backup_file", backupFilePath)
  4042. req, _ = http.NewRequest(http.MethodPost, webRestorePath, &b)
  4043. setJWTCookieForReq(req, token)
  4044. req.Header.Set("Content-Type", contentType)
  4045. rr = executeRequest(req)
  4046. checkResponseCode(t, http.StatusOK, rr)
  4047. err = createTestFile(backupFilePath, 10)
  4048. assert.NoError(t, err)
  4049. b, contentType, _ = getMultipartFormData(form, "backup_file", backupFilePath)
  4050. req, _ = http.NewRequest(http.MethodPost, webRestorePath, &b)
  4051. setJWTCookieForReq(req, token)
  4052. req.Header.Set("Content-Type", contentType)
  4053. rr = executeRequest(req)
  4054. checkResponseCode(t, http.StatusOK, rr)
  4055. user := getTestUser()
  4056. user.ID = 1
  4057. user.Username = "test_user_web_restore"
  4058. admin := getTestAdmin()
  4059. admin.ID = 1
  4060. admin.Username = "test_admin_web_restore"
  4061. backupData := dataprovider.BackupData{}
  4062. backupData.Users = append(backupData.Users, user)
  4063. backupData.Admins = append(backupData.Admins, admin)
  4064. backupContent, err := json.Marshal(backupData)
  4065. assert.NoError(t, err)
  4066. err = ioutil.WriteFile(backupFilePath, backupContent, os.ModePerm)
  4067. assert.NoError(t, err)
  4068. b, contentType, _ = getMultipartFormData(form, "backup_file", backupFilePath)
  4069. req, _ = http.NewRequest(http.MethodPost, webRestorePath, &b)
  4070. setJWTCookieForReq(req, token)
  4071. req.Header.Set("Content-Type", contentType)
  4072. rr = executeRequest(req)
  4073. checkResponseCode(t, http.StatusOK, rr)
  4074. assert.Contains(t, rr.Body.String(), "Your backup was successfully restored")
  4075. user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
  4076. assert.NoError(t, err)
  4077. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  4078. assert.NoError(t, err)
  4079. admin, _, err = httpdtest.GetAdminByUsername(admin.Username, http.StatusOK)
  4080. assert.NoError(t, err)
  4081. _, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
  4082. assert.NoError(t, err)
  4083. }
  4084. func TestWebUserAddMock(t *testing.T) {
  4085. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4086. assert.NoError(t, err)
  4087. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4088. assert.NoError(t, err)
  4089. user := getTestUser()
  4090. user.UploadBandwidth = 32
  4091. user.DownloadBandwidth = 64
  4092. user.UID = 1000
  4093. user.AdditionalInfo = "info"
  4094. mappedDir := filepath.Join(os.TempDir(), "mapped")
  4095. folderName := filepath.Base(mappedDir)
  4096. f := vfs.BaseVirtualFolder{
  4097. Name: folderName,
  4098. MappedPath: mappedDir,
  4099. }
  4100. folderAsJSON, err := json.Marshal(f)
  4101. assert.NoError(t, err)
  4102. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  4103. setBearerForReq(req, apiToken)
  4104. rr := executeRequest(req)
  4105. checkResponseCode(t, http.StatusCreated, rr)
  4106. form := make(url.Values)
  4107. form.Set("username", user.Username)
  4108. form.Set("home_dir", user.HomeDir)
  4109. form.Set("password", user.Password)
  4110. form.Set("status", strconv.Itoa(user.Status))
  4111. form.Set("expiration_date", "")
  4112. form.Set("permissions", "*")
  4113. form.Set("sub_dirs_permissions", " /subdir::list ,download ")
  4114. form.Set("virtual_folders", fmt.Sprintf(" /vdir:: %v :: 2 :: 1024", folderName))
  4115. form.Set("allowed_extensions", "/dir2::.jpg,.png\n/dir2::.ico\n/dir1::.rar")
  4116. form.Set("denied_extensions", "/dir2::.webp,.webp\n/dir2::.tiff\n/dir1::.zip")
  4117. form.Set("allowed_patterns", "/dir2::*.jpg,*.png\n/dir1::*.png")
  4118. form.Set("denied_patterns", "/dir1::*.zip\n/dir3::*.rar\n/dir2::*.mkv")
  4119. form.Set("additional_info", user.AdditionalInfo)
  4120. b, contentType, _ := getMultipartFormData(form, "", "")
  4121. // test invalid url escape
  4122. req, _ = http.NewRequest(http.MethodPost, webUserPath+"?a=%2", &b)
  4123. setJWTCookieForReq(req, webToken)
  4124. req.Header.Set("Content-Type", contentType)
  4125. rr = executeRequest(req)
  4126. checkResponseCode(t, http.StatusOK, rr)
  4127. form.Set("public_keys", testPubKey)
  4128. form.Set("uid", strconv.FormatInt(int64(user.UID), 10))
  4129. form.Set("gid", "a")
  4130. b, contentType, _ = getMultipartFormData(form, "", "")
  4131. // test invalid gid
  4132. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4133. setJWTCookieForReq(req, webToken)
  4134. req.Header.Set("Content-Type", contentType)
  4135. rr = executeRequest(req)
  4136. checkResponseCode(t, http.StatusOK, rr)
  4137. form.Set("gid", "0")
  4138. form.Set("max_sessions", "a")
  4139. b, contentType, _ = getMultipartFormData(form, "", "")
  4140. // test invalid max sessions
  4141. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4142. setJWTCookieForReq(req, webToken)
  4143. req.Header.Set("Content-Type", contentType)
  4144. rr = executeRequest(req)
  4145. checkResponseCode(t, http.StatusOK, rr)
  4146. form.Set("max_sessions", "0")
  4147. form.Set("quota_size", "a")
  4148. b, contentType, _ = getMultipartFormData(form, "", "")
  4149. // test invalid quota size
  4150. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4151. setJWTCookieForReq(req, webToken)
  4152. req.Header.Set("Content-Type", contentType)
  4153. rr = executeRequest(req)
  4154. checkResponseCode(t, http.StatusOK, rr)
  4155. form.Set("quota_size", "0")
  4156. form.Set("quota_files", "a")
  4157. b, contentType, _ = getMultipartFormData(form, "", "")
  4158. // test invalid quota files
  4159. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4160. setJWTCookieForReq(req, webToken)
  4161. req.Header.Set("Content-Type", contentType)
  4162. rr = executeRequest(req)
  4163. checkResponseCode(t, http.StatusOK, rr)
  4164. form.Set("quota_files", "0")
  4165. form.Set("upload_bandwidth", "a")
  4166. b, contentType, _ = getMultipartFormData(form, "", "")
  4167. // test invalid upload bandwidth
  4168. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4169. setJWTCookieForReq(req, webToken)
  4170. req.Header.Set("Content-Type", contentType)
  4171. rr = executeRequest(req)
  4172. checkResponseCode(t, http.StatusOK, rr)
  4173. form.Set("upload_bandwidth", strconv.FormatInt(user.UploadBandwidth, 10))
  4174. form.Set("download_bandwidth", "a")
  4175. b, contentType, _ = getMultipartFormData(form, "", "")
  4176. // test invalid download bandwidth
  4177. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4178. setJWTCookieForReq(req, webToken)
  4179. req.Header.Set("Content-Type", contentType)
  4180. rr = executeRequest(req)
  4181. checkResponseCode(t, http.StatusOK, rr)
  4182. form.Set("download_bandwidth", strconv.FormatInt(user.DownloadBandwidth, 10))
  4183. form.Set("status", "a")
  4184. b, contentType, _ = getMultipartFormData(form, "", "")
  4185. // test invalid status
  4186. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4187. setJWTCookieForReq(req, webToken)
  4188. req.Header.Set("Content-Type", contentType)
  4189. rr = executeRequest(req)
  4190. checkResponseCode(t, http.StatusOK, rr)
  4191. form.Set("status", strconv.Itoa(user.Status))
  4192. form.Set("expiration_date", "123")
  4193. b, contentType, _ = getMultipartFormData(form, "", "")
  4194. // test invalid expiration date
  4195. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4196. setJWTCookieForReq(req, webToken)
  4197. req.Header.Set("Content-Type", contentType)
  4198. rr = executeRequest(req)
  4199. checkResponseCode(t, http.StatusOK, rr)
  4200. form.Set("expiration_date", "")
  4201. form.Set("allowed_ip", "invalid,ip")
  4202. b, contentType, _ = getMultipartFormData(form, "", "")
  4203. // test invalid allowed_ip
  4204. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4205. setJWTCookieForReq(req, webToken)
  4206. req.Header.Set("Content-Type", contentType)
  4207. rr = executeRequest(req)
  4208. checkResponseCode(t, http.StatusOK, rr)
  4209. form.Set("allowed_ip", "")
  4210. form.Set("denied_ip", "192.168.1.2") // it should be 192.168.1.2/32
  4211. b, contentType, _ = getMultipartFormData(form, "", "")
  4212. // test invalid denied_ip
  4213. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4214. setJWTCookieForReq(req, webToken)
  4215. req.Header.Set("Content-Type", contentType)
  4216. rr = executeRequest(req)
  4217. checkResponseCode(t, http.StatusOK, rr)
  4218. form.Set("denied_ip", "")
  4219. // test invalid max file upload size
  4220. form.Set("max_upload_file_size", "a")
  4221. b, contentType, _ = getMultipartFormData(form, "", "")
  4222. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4223. setJWTCookieForReq(req, webToken)
  4224. req.Header.Set("Content-Type", contentType)
  4225. rr = executeRequest(req)
  4226. checkResponseCode(t, http.StatusOK, rr)
  4227. form.Set("max_upload_file_size", "1000")
  4228. b, contentType, _ = getMultipartFormData(form, "", "")
  4229. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4230. setJWTCookieForReq(req, webToken)
  4231. req.Header.Set("Content-Type", contentType)
  4232. rr = executeRequest(req)
  4233. checkResponseCode(t, http.StatusSeeOther, rr)
  4234. // the user already exists, was created with the above request
  4235. b, contentType, _ = getMultipartFormData(form, "", "")
  4236. req, _ = http.NewRequest(http.MethodPost, webUserPath, &b)
  4237. setJWTCookieForReq(req, webToken)
  4238. req.Header.Set("Content-Type", contentType)
  4239. rr = executeRequest(req)
  4240. checkResponseCode(t, http.StatusOK, rr)
  4241. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4242. setBearerForReq(req, apiToken)
  4243. rr = executeRequest(req)
  4244. checkResponseCode(t, http.StatusOK, rr)
  4245. newUser := dataprovider.User{}
  4246. err = render.DecodeJSON(rr.Body, &newUser)
  4247. assert.NoError(t, err)
  4248. assert.Equal(t, user.UID, newUser.UID)
  4249. assert.Equal(t, user.UploadBandwidth, newUser.UploadBandwidth)
  4250. assert.Equal(t, user.DownloadBandwidth, newUser.DownloadBandwidth)
  4251. assert.Equal(t, int64(1000), newUser.Filters.MaxUploadFileSize)
  4252. assert.Equal(t, user.AdditionalInfo, newUser.AdditionalInfo)
  4253. assert.True(t, utils.IsStringInSlice(testPubKey, newUser.PublicKeys))
  4254. if val, ok := newUser.Permissions["/subdir"]; ok {
  4255. assert.True(t, utils.IsStringInSlice(dataprovider.PermListItems, val))
  4256. assert.True(t, utils.IsStringInSlice(dataprovider.PermDownload, val))
  4257. } else {
  4258. assert.Fail(t, "user permissions must contain /somedir", "actual: %v", newUser.Permissions)
  4259. }
  4260. assert.Len(t, newUser.VirtualFolders, 1)
  4261. for _, v := range newUser.VirtualFolders {
  4262. assert.Equal(t, v.VirtualPath, "/vdir")
  4263. assert.Equal(t, v.Name, folderName)
  4264. assert.Equal(t, v.MappedPath, mappedDir)
  4265. assert.Equal(t, v.QuotaFiles, 2)
  4266. assert.Equal(t, v.QuotaSize, int64(1024))
  4267. }
  4268. assert.Len(t, newUser.Filters.FileExtensions, 2)
  4269. for _, filter := range newUser.Filters.FileExtensions {
  4270. if filter.Path == "/dir1" {
  4271. assert.Len(t, filter.DeniedExtensions, 1)
  4272. assert.Len(t, filter.AllowedExtensions, 1)
  4273. assert.True(t, utils.IsStringInSlice(".zip", filter.DeniedExtensions))
  4274. assert.True(t, utils.IsStringInSlice(".rar", filter.AllowedExtensions))
  4275. }
  4276. if filter.Path == "/dir2" {
  4277. assert.Len(t, filter.DeniedExtensions, 2)
  4278. assert.Len(t, filter.AllowedExtensions, 3)
  4279. assert.True(t, utils.IsStringInSlice(".jpg", filter.AllowedExtensions))
  4280. assert.True(t, utils.IsStringInSlice(".png", filter.AllowedExtensions))
  4281. assert.True(t, utils.IsStringInSlice(".ico", filter.AllowedExtensions))
  4282. assert.True(t, utils.IsStringInSlice(".webp", filter.DeniedExtensions))
  4283. assert.True(t, utils.IsStringInSlice(".tiff", filter.DeniedExtensions))
  4284. }
  4285. }
  4286. assert.Len(t, newUser.Filters.FilePatterns, 3)
  4287. for _, filter := range newUser.Filters.FilePatterns {
  4288. if filter.Path == "/dir1" {
  4289. assert.Len(t, filter.DeniedPatterns, 1)
  4290. assert.Len(t, filter.AllowedPatterns, 1)
  4291. assert.True(t, utils.IsStringInSlice("*.png", filter.AllowedPatterns))
  4292. assert.True(t, utils.IsStringInSlice("*.zip", filter.DeniedPatterns))
  4293. }
  4294. if filter.Path == "/dir2" {
  4295. assert.Len(t, filter.DeniedPatterns, 1)
  4296. assert.Len(t, filter.AllowedPatterns, 2)
  4297. assert.True(t, utils.IsStringInSlice("*.jpg", filter.AllowedPatterns))
  4298. assert.True(t, utils.IsStringInSlice("*.png", filter.AllowedPatterns))
  4299. assert.True(t, utils.IsStringInSlice("*.mkv", filter.DeniedPatterns))
  4300. }
  4301. if filter.Path == "/dir3" {
  4302. assert.Len(t, filter.DeniedPatterns, 1)
  4303. assert.Len(t, filter.AllowedPatterns, 0)
  4304. assert.True(t, utils.IsStringInSlice("*.rar", filter.DeniedPatterns))
  4305. }
  4306. }
  4307. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, newUser.Username), nil)
  4308. setBearerForReq(req, apiToken)
  4309. rr = executeRequest(req)
  4310. checkResponseCode(t, http.StatusOK, rr)
  4311. req, _ = http.NewRequest(http.MethodDelete, path.Join(folderPath, folderName), nil)
  4312. setBearerForReq(req, apiToken)
  4313. rr = executeRequest(req)
  4314. checkResponseCode(t, http.StatusOK, rr)
  4315. }
  4316. func TestWebUserUpdateMock(t *testing.T) {
  4317. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4318. assert.NoError(t, err)
  4319. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4320. assert.NoError(t, err)
  4321. user := getTestUser()
  4322. userAsJSON := getUserAsJSON(t, user)
  4323. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  4324. setBearerForReq(req, apiToken)
  4325. rr := executeRequest(req)
  4326. checkResponseCode(t, http.StatusCreated, rr)
  4327. err = render.DecodeJSON(rr.Body, &user)
  4328. assert.NoError(t, err)
  4329. user.MaxSessions = 1
  4330. user.QuotaFiles = 2
  4331. user.QuotaSize = 3
  4332. user.GID = 1000
  4333. user.AdditionalInfo = "new additional info"
  4334. form := make(url.Values)
  4335. form.Set("username", user.Username)
  4336. form.Set("home_dir", user.HomeDir)
  4337. form.Set("uid", "0")
  4338. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  4339. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  4340. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  4341. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  4342. form.Set("upload_bandwidth", "0")
  4343. form.Set("download_bandwidth", "0")
  4344. form.Set("permissions", "*")
  4345. form.Set("sub_dirs_permissions", "/otherdir :: list ,upload ")
  4346. form.Set("status", strconv.Itoa(user.Status))
  4347. form.Set("expiration_date", "2020-01-01 00:00:00")
  4348. form.Set("allowed_ip", " 192.168.1.3/32, 192.168.2.0/24 ")
  4349. form.Set("denied_ip", " 10.0.0.2/32 ")
  4350. form.Set("denied_extensions", "/dir1::.zip")
  4351. form.Set("ssh_login_methods", dataprovider.SSHLoginMethodKeyboardInteractive)
  4352. form.Set("denied_protocols", common.ProtocolFTP)
  4353. form.Set("max_upload_file_size", "100")
  4354. form.Set("disconnect", "1")
  4355. form.Set("additional_info", user.AdditionalInfo)
  4356. b, contentType, _ := getMultipartFormData(form, "", "")
  4357. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4358. setJWTCookieForReq(req, webToken)
  4359. req.Header.Set("Content-Type", contentType)
  4360. rr = executeRequest(req)
  4361. checkResponseCode(t, http.StatusSeeOther, rr)
  4362. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4363. setBearerForReq(req, apiToken)
  4364. rr = executeRequest(req)
  4365. checkResponseCode(t, http.StatusOK, rr)
  4366. var updateUser dataprovider.User
  4367. err = render.DecodeJSON(rr.Body, &updateUser)
  4368. assert.NoError(t, err)
  4369. assert.Equal(t, user.HomeDir, updateUser.HomeDir)
  4370. assert.Equal(t, user.MaxSessions, updateUser.MaxSessions)
  4371. assert.Equal(t, user.QuotaFiles, updateUser.QuotaFiles)
  4372. assert.Equal(t, user.QuotaSize, updateUser.QuotaSize)
  4373. assert.Equal(t, user.UID, updateUser.UID)
  4374. assert.Equal(t, user.GID, updateUser.GID)
  4375. assert.Equal(t, user.AdditionalInfo, updateUser.AdditionalInfo)
  4376. assert.Equal(t, int64(100), updateUser.Filters.MaxUploadFileSize)
  4377. if val, ok := updateUser.Permissions["/otherdir"]; ok {
  4378. assert.True(t, utils.IsStringInSlice(dataprovider.PermListItems, val))
  4379. assert.True(t, utils.IsStringInSlice(dataprovider.PermUpload, val))
  4380. } else {
  4381. assert.Fail(t, "user permissions must contains /otherdir", "actual: %v", updateUser.Permissions)
  4382. }
  4383. assert.True(t, utils.IsStringInSlice("192.168.1.3/32", updateUser.Filters.AllowedIP))
  4384. assert.True(t, utils.IsStringInSlice("10.0.0.2/32", updateUser.Filters.DeniedIP))
  4385. assert.True(t, utils.IsStringInSlice(dataprovider.SSHLoginMethodKeyboardInteractive, updateUser.Filters.DeniedLoginMethods))
  4386. assert.True(t, utils.IsStringInSlice(common.ProtocolFTP, updateUser.Filters.DeniedProtocols))
  4387. assert.True(t, utils.IsStringInSlice(".zip", updateUser.Filters.FileExtensions[0].DeniedExtensions))
  4388. req, err = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  4389. assert.NoError(t, err)
  4390. setBearerForReq(req, apiToken)
  4391. rr = executeRequest(req)
  4392. checkResponseCode(t, http.StatusOK, rr)
  4393. }
  4394. func TestRenderUserTemplateMock(t *testing.T) {
  4395. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4396. assert.NoError(t, err)
  4397. req, err := http.NewRequest(http.MethodGet, webTemplateUser, nil)
  4398. assert.NoError(t, err)
  4399. setJWTCookieForReq(req, token)
  4400. rr := executeRequest(req)
  4401. checkResponseCode(t, http.StatusOK, rr)
  4402. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  4403. assert.NoError(t, err)
  4404. req, err = http.NewRequest(http.MethodGet, webTemplateUser+fmt.Sprintf("?from=%v", user.Username), nil)
  4405. assert.NoError(t, err)
  4406. setJWTCookieForReq(req, token)
  4407. rr = executeRequest(req)
  4408. checkResponseCode(t, http.StatusOK, rr)
  4409. req, err = http.NewRequest(http.MethodGet, webTemplateUser+"?from=unknown", nil)
  4410. assert.NoError(t, err)
  4411. setJWTCookieForReq(req, token)
  4412. rr = executeRequest(req)
  4413. checkResponseCode(t, http.StatusNotFound, rr)
  4414. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  4415. assert.NoError(t, err)
  4416. }
  4417. func TestRenderWebCloneUserMock(t *testing.T) {
  4418. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4419. assert.NoError(t, err)
  4420. user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
  4421. assert.NoError(t, err)
  4422. req, err := http.NewRequest(http.MethodGet, webUserPath+fmt.Sprintf("?clone-from=%v", user.Username), nil)
  4423. assert.NoError(t, err)
  4424. setJWTCookieForReq(req, token)
  4425. rr := executeRequest(req)
  4426. checkResponseCode(t, http.StatusOK, rr)
  4427. req, err = http.NewRequest(http.MethodGet, webUserPath+fmt.Sprintf("?clone-from=%v", altAdminPassword), nil)
  4428. assert.NoError(t, err)
  4429. setJWTCookieForReq(req, token)
  4430. rr = executeRequest(req)
  4431. checkResponseCode(t, http.StatusNotFound, rr)
  4432. _, err = httpdtest.RemoveUser(user, http.StatusOK)
  4433. assert.NoError(t, err)
  4434. }
  4435. func TestUserTemplateWithFoldersMock(t *testing.T) {
  4436. folder := vfs.BaseVirtualFolder{
  4437. Name: "vfolder",
  4438. MappedPath: filepath.Join(os.TempDir(), "mapped"),
  4439. }
  4440. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4441. assert.NoError(t, err)
  4442. user := getTestUser()
  4443. form := make(url.Values)
  4444. form.Set("username", user.Username)
  4445. form.Set("home_dir", filepath.Join(os.TempDir(), "%username%"))
  4446. form.Set("uid", strconv.FormatInt(int64(user.UID), 10))
  4447. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  4448. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  4449. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  4450. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  4451. form.Set("upload_bandwidth", "0")
  4452. form.Set("download_bandwidth", "0")
  4453. form.Set("permissions", "*")
  4454. form.Set("sub_dirs_permissions", "")
  4455. form.Set("status", strconv.Itoa(user.Status))
  4456. form.Set("expiration_date", "2020-01-01 00:00:00")
  4457. form.Set("fs_provider", "0")
  4458. form.Set("max_upload_file_size", "0")
  4459. form.Set("virtual_folders", "/vdir%username%::"+folder.Name+"::-1::-1")
  4460. form.Set("users", "auser1::password1\nauser2::password2::"+testPubKey+"\nauser1::password")
  4461. b, contentType, _ := getMultipartFormData(form, "", "")
  4462. req, _ := http.NewRequest(http.MethodPost, path.Join(webTemplateUser), &b)
  4463. setJWTCookieForReq(req, token)
  4464. req.Header.Set("Content-Type", contentType)
  4465. rr := executeRequest(req)
  4466. checkResponseCode(t, http.StatusBadRequest, rr)
  4467. require.Contains(t, rr.Body.String(), "invalid folder mapped path")
  4468. folder, resp, err := httpdtest.AddFolder(folder, http.StatusCreated)
  4469. assert.NoError(t, err, string(resp))
  4470. b, contentType, _ = getMultipartFormData(form, "", "")
  4471. req, _ = http.NewRequest(http.MethodPost, path.Join(webTemplateUser), &b)
  4472. setJWTCookieForReq(req, token)
  4473. req.Header.Set("Content-Type", contentType)
  4474. rr = executeRequest(req)
  4475. checkResponseCode(t, http.StatusOK, rr)
  4476. var dump dataprovider.BackupData
  4477. err = json.Unmarshal(rr.Body.Bytes(), &dump)
  4478. assert.NoError(t, err)
  4479. assert.Len(t, dump.Users, 2)
  4480. assert.Len(t, dump.Folders, 1)
  4481. user1 := dump.Users[0]
  4482. user2 := dump.Users[1]
  4483. folder1 := dump.Folders[0]
  4484. assert.Equal(t, "auser1", user1.Username)
  4485. assert.Equal(t, "auser2", user2.Username)
  4486. assert.Equal(t, filepath.Join(os.TempDir(), user1.Username), user1.HomeDir)
  4487. assert.Equal(t, filepath.Join(os.TempDir(), user2.Username), user2.HomeDir)
  4488. assert.Equal(t, folder.Name, folder1.Name)
  4489. assert.Equal(t, folder.MappedPath, folder1.MappedPath)
  4490. assert.Len(t, user1.PublicKeys, 0)
  4491. assert.Len(t, user2.PublicKeys, 1)
  4492. assert.Len(t, user1.VirtualFolders, 1)
  4493. assert.Len(t, user2.VirtualFolders, 1)
  4494. assert.Equal(t, "/vdirauser1", user1.VirtualFolders[0].VirtualPath)
  4495. assert.Equal(t, "/vdirauser2", user2.VirtualFolders[0].VirtualPath)
  4496. _, err = httpdtest.RemoveFolder(folder, http.StatusOK)
  4497. assert.NoError(t, err)
  4498. }
  4499. func TestUserTemplateMock(t *testing.T) {
  4500. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4501. assert.NoError(t, err)
  4502. user := getTestUser()
  4503. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  4504. user.FsConfig.S3Config.Bucket = "test"
  4505. user.FsConfig.S3Config.Region = "eu-central-1"
  4506. user.FsConfig.S3Config.AccessKey = "%username%"
  4507. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir/"
  4508. user.FsConfig.S3Config.UploadPartSize = 5
  4509. user.FsConfig.S3Config.UploadConcurrency = 4
  4510. form := make(url.Values)
  4511. form.Set("username", user.Username)
  4512. form.Set("home_dir", filepath.Join(os.TempDir(), "%username%"))
  4513. form.Set("uid", "0")
  4514. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  4515. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  4516. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  4517. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  4518. form.Set("upload_bandwidth", "0")
  4519. form.Set("download_bandwidth", "0")
  4520. form.Set("permissions", "*")
  4521. form.Set("sub_dirs_permissions", "")
  4522. form.Set("status", strconv.Itoa(user.Status))
  4523. form.Set("expiration_date", "2020-01-01 00:00:00")
  4524. form.Set("allowed_ip", "")
  4525. form.Set("denied_ip", "")
  4526. form.Set("fs_provider", "1")
  4527. form.Set("s3_bucket", user.FsConfig.S3Config.Bucket)
  4528. form.Set("s3_region", user.FsConfig.S3Config.Region)
  4529. form.Set("s3_access_key", "%username%")
  4530. form.Set("s3_access_secret", "%password%")
  4531. form.Set("s3_key_prefix", "base/%username%")
  4532. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  4533. form.Set("denied_extensions", "/dir2::.zip")
  4534. form.Set("max_upload_file_size", "0")
  4535. // test invalid s3_upload_part_size
  4536. form.Set("s3_upload_part_size", "a")
  4537. b, contentType, _ := getMultipartFormData(form, "", "")
  4538. req, _ := http.NewRequest(http.MethodPost, path.Join(webTemplateUser), &b)
  4539. setJWTCookieForReq(req, token)
  4540. req.Header.Set("Content-Type", contentType)
  4541. rr := executeRequest(req)
  4542. checkResponseCode(t, http.StatusBadRequest, rr)
  4543. form.Set("s3_upload_part_size", strconv.FormatInt(user.FsConfig.S3Config.UploadPartSize, 10))
  4544. form.Set("s3_upload_concurrency", strconv.Itoa(user.FsConfig.S3Config.UploadConcurrency))
  4545. b, contentType, _ = getMultipartFormData(form, "", "")
  4546. req, _ = http.NewRequest(http.MethodPost, path.Join(webTemplateUser), &b)
  4547. setJWTCookieForReq(req, token)
  4548. req.Header.Set("Content-Type", contentType)
  4549. rr = executeRequest(req)
  4550. checkResponseCode(t, http.StatusBadRequest, rr)
  4551. form.Set("users", "user1::password1::invalid-pkey")
  4552. b, contentType, _ = getMultipartFormData(form, "", "")
  4553. req, _ = http.NewRequest(http.MethodPost, path.Join(webTemplateUser), &b)
  4554. setJWTCookieForReq(req, token)
  4555. req.Header.Set("Content-Type", contentType)
  4556. rr = executeRequest(req)
  4557. checkResponseCode(t, http.StatusBadRequest, rr)
  4558. require.Contains(t, rr.Body.String(), "Error validating user")
  4559. form.Set("users", "user1:password1")
  4560. b, contentType, _ = getMultipartFormData(form, "", "")
  4561. req, _ = http.NewRequest(http.MethodPost, path.Join(webTemplateUser), &b)
  4562. setJWTCookieForReq(req, token)
  4563. req.Header.Set("Content-Type", contentType)
  4564. rr = executeRequest(req)
  4565. checkResponseCode(t, http.StatusBadRequest, rr)
  4566. require.Contains(t, rr.Body.String(), "No valid users found, export is not possible")
  4567. form.Set("users", "user1::password1\nuser2::password2::"+testPubKey+"\nuser3::::")
  4568. b, contentType, _ = getMultipartFormData(form, "", "")
  4569. req, _ = http.NewRequest(http.MethodPost, path.Join(webTemplateUser), &b)
  4570. setJWTCookieForReq(req, token)
  4571. req.Header.Set("Content-Type", contentType)
  4572. rr = executeRequest(req)
  4573. checkResponseCode(t, http.StatusOK, rr)
  4574. var dump dataprovider.BackupData
  4575. err = json.Unmarshal(rr.Body.Bytes(), &dump)
  4576. require.NoError(t, err)
  4577. require.Len(t, dump.Users, 2)
  4578. user1 := dump.Users[0]
  4579. user2 := dump.Users[1]
  4580. require.Equal(t, "user1", user1.Username)
  4581. require.Equal(t, dataprovider.S3FilesystemProvider, user1.FsConfig.Provider)
  4582. require.Equal(t, "user2", user2.Username)
  4583. require.Equal(t, dataprovider.S3FilesystemProvider, user2.FsConfig.Provider)
  4584. require.Len(t, user2.PublicKeys, 1)
  4585. require.Equal(t, filepath.Join(os.TempDir(), user1.Username), user1.HomeDir)
  4586. require.Equal(t, filepath.Join(os.TempDir(), user2.Username), user2.HomeDir)
  4587. require.Equal(t, user1.Username, user1.FsConfig.S3Config.AccessKey)
  4588. require.Equal(t, user2.Username, user2.FsConfig.S3Config.AccessKey)
  4589. require.Equal(t, path.Join("base", user1.Username)+"/", user1.FsConfig.S3Config.KeyPrefix)
  4590. require.Equal(t, path.Join("base", user2.Username)+"/", user2.FsConfig.S3Config.KeyPrefix)
  4591. require.True(t, user1.FsConfig.S3Config.AccessSecret.IsEncrypted())
  4592. err = user1.FsConfig.S3Config.AccessSecret.Decrypt()
  4593. require.NoError(t, err)
  4594. require.Equal(t, "password1", user1.FsConfig.S3Config.AccessSecret.GetPayload())
  4595. require.True(t, user2.FsConfig.S3Config.AccessSecret.IsEncrypted())
  4596. err = user2.FsConfig.S3Config.AccessSecret.Decrypt()
  4597. require.NoError(t, err)
  4598. require.Equal(t, "password2", user2.FsConfig.S3Config.AccessSecret.GetPayload())
  4599. }
  4600. func TestWebUserS3Mock(t *testing.T) {
  4601. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4602. assert.NoError(t, err)
  4603. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4604. assert.NoError(t, err)
  4605. user := getTestUser()
  4606. userAsJSON := getUserAsJSON(t, user)
  4607. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  4608. setBearerForReq(req, apiToken)
  4609. rr := executeRequest(req)
  4610. checkResponseCode(t, http.StatusCreated, rr)
  4611. err = render.DecodeJSON(rr.Body, &user)
  4612. assert.NoError(t, err)
  4613. user.FsConfig.Provider = dataprovider.S3FilesystemProvider
  4614. user.FsConfig.S3Config.Bucket = "test"
  4615. user.FsConfig.S3Config.Region = "eu-west-1"
  4616. user.FsConfig.S3Config.AccessKey = "access-key"
  4617. user.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("access-secret")
  4618. user.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/path?a=b"
  4619. user.FsConfig.S3Config.StorageClass = "Standard"
  4620. user.FsConfig.S3Config.KeyPrefix = "somedir/subdir/"
  4621. user.FsConfig.S3Config.UploadPartSize = 5
  4622. user.FsConfig.S3Config.UploadConcurrency = 4
  4623. form := make(url.Values)
  4624. form.Set("username", user.Username)
  4625. form.Set("home_dir", user.HomeDir)
  4626. form.Set("uid", "0")
  4627. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  4628. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  4629. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  4630. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  4631. form.Set("upload_bandwidth", "0")
  4632. form.Set("download_bandwidth", "0")
  4633. form.Set("permissions", "*")
  4634. form.Set("sub_dirs_permissions", "")
  4635. form.Set("status", strconv.Itoa(user.Status))
  4636. form.Set("expiration_date", "2020-01-01 00:00:00")
  4637. form.Set("allowed_ip", "")
  4638. form.Set("denied_ip", "")
  4639. form.Set("fs_provider", "1")
  4640. form.Set("s3_bucket", user.FsConfig.S3Config.Bucket)
  4641. form.Set("s3_region", user.FsConfig.S3Config.Region)
  4642. form.Set("s3_access_key", user.FsConfig.S3Config.AccessKey)
  4643. form.Set("s3_access_secret", user.FsConfig.S3Config.AccessSecret.GetPayload())
  4644. form.Set("s3_storage_class", user.FsConfig.S3Config.StorageClass)
  4645. form.Set("s3_endpoint", user.FsConfig.S3Config.Endpoint)
  4646. form.Set("s3_key_prefix", user.FsConfig.S3Config.KeyPrefix)
  4647. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  4648. form.Set("denied_extensions", "/dir2::.zip")
  4649. form.Set("max_upload_file_size", "0")
  4650. // test invalid s3_upload_part_size
  4651. form.Set("s3_upload_part_size", "a")
  4652. b, contentType, _ := getMultipartFormData(form, "", "")
  4653. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4654. setJWTCookieForReq(req, webToken)
  4655. req.Header.Set("Content-Type", contentType)
  4656. rr = executeRequest(req)
  4657. checkResponseCode(t, http.StatusOK, rr)
  4658. // test invalid s3_concurrency
  4659. form.Set("s3_upload_part_size", strconv.FormatInt(user.FsConfig.S3Config.UploadPartSize, 10))
  4660. form.Set("s3_upload_concurrency", "a")
  4661. b, contentType, _ = getMultipartFormData(form, "", "")
  4662. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4663. setJWTCookieForReq(req, webToken)
  4664. req.Header.Set("Content-Type", contentType)
  4665. rr = executeRequest(req)
  4666. checkResponseCode(t, http.StatusOK, rr)
  4667. // now add the user
  4668. form.Set("s3_upload_concurrency", strconv.Itoa(user.FsConfig.S3Config.UploadConcurrency))
  4669. b, contentType, _ = getMultipartFormData(form, "", "")
  4670. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4671. setJWTCookieForReq(req, webToken)
  4672. req.Header.Set("Content-Type", contentType)
  4673. rr = executeRequest(req)
  4674. checkResponseCode(t, http.StatusSeeOther, rr)
  4675. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4676. setBearerForReq(req, apiToken)
  4677. rr = executeRequest(req)
  4678. checkResponseCode(t, http.StatusOK, rr)
  4679. var updateUser dataprovider.User
  4680. err = render.DecodeJSON(rr.Body, &updateUser)
  4681. assert.NoError(t, err)
  4682. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  4683. assert.Equal(t, updateUser.FsConfig.S3Config.Bucket, user.FsConfig.S3Config.Bucket)
  4684. assert.Equal(t, updateUser.FsConfig.S3Config.Region, user.FsConfig.S3Config.Region)
  4685. assert.Equal(t, updateUser.FsConfig.S3Config.AccessKey, user.FsConfig.S3Config.AccessKey)
  4686. assert.Equal(t, updateUser.FsConfig.S3Config.StorageClass, user.FsConfig.S3Config.StorageClass)
  4687. assert.Equal(t, updateUser.FsConfig.S3Config.Endpoint, user.FsConfig.S3Config.Endpoint)
  4688. assert.Equal(t, updateUser.FsConfig.S3Config.KeyPrefix, user.FsConfig.S3Config.KeyPrefix)
  4689. assert.Equal(t, updateUser.FsConfig.S3Config.UploadPartSize, user.FsConfig.S3Config.UploadPartSize)
  4690. assert.Equal(t, updateUser.FsConfig.S3Config.UploadConcurrency, user.FsConfig.S3Config.UploadConcurrency)
  4691. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  4692. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.S3Config.AccessSecret.GetStatus())
  4693. assert.NotEmpty(t, updateUser.FsConfig.S3Config.AccessSecret.GetPayload())
  4694. assert.Empty(t, updateUser.FsConfig.S3Config.AccessSecret.GetKey())
  4695. assert.Empty(t, updateUser.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  4696. // now check that a redacted password is not saved
  4697. form.Set("s3_access_secret", "[**redacted**] ")
  4698. b, contentType, _ = getMultipartFormData(form, "", "")
  4699. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4700. setJWTCookieForReq(req, webToken)
  4701. req.Header.Set("Content-Type", contentType)
  4702. rr = executeRequest(req)
  4703. checkResponseCode(t, http.StatusSeeOther, rr)
  4704. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4705. setBearerForReq(req, apiToken)
  4706. rr = executeRequest(req)
  4707. checkResponseCode(t, http.StatusOK, rr)
  4708. var lastUpdatedUser dataprovider.User
  4709. err = render.DecodeJSON(rr.Body, &lastUpdatedUser)
  4710. assert.NoError(t, err)
  4711. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetStatus())
  4712. assert.Equal(t, updateUser.FsConfig.S3Config.AccessSecret.GetPayload(), lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetPayload())
  4713. assert.Empty(t, lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetKey())
  4714. assert.Empty(t, lastUpdatedUser.FsConfig.S3Config.AccessSecret.GetAdditionalData())
  4715. // now clear credentials
  4716. form.Set("s3_access_key", "")
  4717. form.Set("s3_access_secret", "")
  4718. b, contentType, _ = getMultipartFormData(form, "", "")
  4719. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4720. setJWTCookieForReq(req, webToken)
  4721. req.Header.Set("Content-Type", contentType)
  4722. rr = executeRequest(req)
  4723. checkResponseCode(t, http.StatusSeeOther, rr)
  4724. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4725. setBearerForReq(req, apiToken)
  4726. rr = executeRequest(req)
  4727. checkResponseCode(t, http.StatusOK, rr)
  4728. var userGet dataprovider.User
  4729. err = render.DecodeJSON(rr.Body, &userGet)
  4730. assert.NoError(t, err)
  4731. assert.True(t, userGet.FsConfig.S3Config.AccessSecret.IsEmpty())
  4732. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  4733. setBearerForReq(req, apiToken)
  4734. rr = executeRequest(req)
  4735. checkResponseCode(t, http.StatusOK, rr)
  4736. }
  4737. func TestWebUserGCSMock(t *testing.T) {
  4738. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4739. assert.NoError(t, err)
  4740. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4741. assert.NoError(t, err)
  4742. user := getTestUser()
  4743. userAsJSON := getUserAsJSON(t, user)
  4744. req, err := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  4745. assert.NoError(t, err)
  4746. setBearerForReq(req, apiToken)
  4747. rr := executeRequest(req)
  4748. checkResponseCode(t, http.StatusCreated, rr)
  4749. err = render.DecodeJSON(rr.Body, &user)
  4750. assert.NoError(t, err)
  4751. credentialsFilePath := filepath.Join(os.TempDir(), "gcs.json")
  4752. err = createTestFile(credentialsFilePath, 0)
  4753. assert.NoError(t, err)
  4754. user.FsConfig.Provider = dataprovider.GCSFilesystemProvider
  4755. user.FsConfig.GCSConfig.Bucket = "test"
  4756. user.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir/"
  4757. user.FsConfig.GCSConfig.StorageClass = "standard"
  4758. form := make(url.Values)
  4759. form.Set("username", user.Username)
  4760. form.Set("home_dir", user.HomeDir)
  4761. form.Set("uid", "0")
  4762. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  4763. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  4764. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  4765. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  4766. form.Set("upload_bandwidth", "0")
  4767. form.Set("download_bandwidth", "0")
  4768. form.Set("permissions", "*")
  4769. form.Set("sub_dirs_permissions", "")
  4770. form.Set("status", strconv.Itoa(user.Status))
  4771. form.Set("expiration_date", "2020-01-01 00:00:00")
  4772. form.Set("allowed_ip", "")
  4773. form.Set("denied_ip", "")
  4774. form.Set("fs_provider", "2")
  4775. form.Set("gcs_bucket", user.FsConfig.GCSConfig.Bucket)
  4776. form.Set("gcs_storage_class", user.FsConfig.GCSConfig.StorageClass)
  4777. form.Set("gcs_key_prefix", user.FsConfig.GCSConfig.KeyPrefix)
  4778. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  4779. form.Set("max_upload_file_size", "0")
  4780. b, contentType, _ := getMultipartFormData(form, "", "")
  4781. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4782. setJWTCookieForReq(req, webToken)
  4783. req.Header.Set("Content-Type", contentType)
  4784. rr = executeRequest(req)
  4785. checkResponseCode(t, http.StatusOK, rr)
  4786. b, contentType, _ = getMultipartFormData(form, "gcs_credential_file", credentialsFilePath)
  4787. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4788. setJWTCookieForReq(req, webToken)
  4789. req.Header.Set("Content-Type", contentType)
  4790. rr = executeRequest(req)
  4791. checkResponseCode(t, http.StatusOK, rr)
  4792. err = createTestFile(credentialsFilePath, 4096)
  4793. assert.NoError(t, err)
  4794. b, contentType, _ = getMultipartFormData(form, "gcs_credential_file", credentialsFilePath)
  4795. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4796. setJWTCookieForReq(req, webToken)
  4797. req.Header.Set("Content-Type", contentType)
  4798. rr = executeRequest(req)
  4799. checkResponseCode(t, http.StatusSeeOther, rr)
  4800. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4801. setBearerForReq(req, apiToken)
  4802. rr = executeRequest(req)
  4803. checkResponseCode(t, http.StatusOK, rr)
  4804. var updateUser dataprovider.User
  4805. err = render.DecodeJSON(rr.Body, &updateUser)
  4806. assert.NoError(t, err)
  4807. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  4808. assert.Equal(t, user.FsConfig.Provider, updateUser.FsConfig.Provider)
  4809. assert.Equal(t, user.FsConfig.GCSConfig.Bucket, updateUser.FsConfig.GCSConfig.Bucket)
  4810. assert.Equal(t, user.FsConfig.GCSConfig.StorageClass, updateUser.FsConfig.GCSConfig.StorageClass)
  4811. assert.Equal(t, user.FsConfig.GCSConfig.KeyPrefix, updateUser.FsConfig.GCSConfig.KeyPrefix)
  4812. assert.Equal(t, "/dir1", updateUser.Filters.FileExtensions[0].Path)
  4813. form.Set("gcs_auto_credentials", "on")
  4814. b, contentType, _ = getMultipartFormData(form, "", "")
  4815. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4816. setJWTCookieForReq(req, webToken)
  4817. req.Header.Set("Content-Type", contentType)
  4818. rr = executeRequest(req)
  4819. checkResponseCode(t, http.StatusSeeOther, rr)
  4820. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4821. setBearerForReq(req, apiToken)
  4822. rr = executeRequest(req)
  4823. checkResponseCode(t, http.StatusOK, rr)
  4824. updateUser = dataprovider.User{}
  4825. err = render.DecodeJSON(rr.Body, &updateUser)
  4826. assert.NoError(t, err)
  4827. assert.Equal(t, 1, updateUser.FsConfig.GCSConfig.AutomaticCredentials)
  4828. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  4829. setBearerForReq(req, apiToken)
  4830. rr = executeRequest(req)
  4831. checkResponseCode(t, http.StatusOK, rr)
  4832. err = os.Remove(credentialsFilePath)
  4833. assert.NoError(t, err)
  4834. }
  4835. func TestWebUserAzureBlobMock(t *testing.T) {
  4836. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4837. assert.NoError(t, err)
  4838. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4839. assert.NoError(t, err)
  4840. user := getTestUser()
  4841. userAsJSON := getUserAsJSON(t, user)
  4842. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  4843. setBearerForReq(req, apiToken)
  4844. rr := executeRequest(req)
  4845. checkResponseCode(t, http.StatusCreated, rr)
  4846. err = render.DecodeJSON(rr.Body, &user)
  4847. assert.NoError(t, err)
  4848. user.FsConfig.Provider = dataprovider.AzureBlobFilesystemProvider
  4849. user.FsConfig.AzBlobConfig.Container = "container"
  4850. user.FsConfig.AzBlobConfig.AccountName = "aname"
  4851. user.FsConfig.AzBlobConfig.AccountKey = kms.NewPlainSecret("access-skey")
  4852. user.FsConfig.AzBlobConfig.Endpoint = "http://127.0.0.1:9000/path?b=c"
  4853. user.FsConfig.AzBlobConfig.KeyPrefix = "somedir/subdir/"
  4854. user.FsConfig.AzBlobConfig.UploadPartSize = 5
  4855. user.FsConfig.AzBlobConfig.UploadConcurrency = 4
  4856. user.FsConfig.AzBlobConfig.UseEmulator = true
  4857. form := make(url.Values)
  4858. form.Set("username", user.Username)
  4859. form.Set("home_dir", user.HomeDir)
  4860. form.Set("uid", "0")
  4861. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  4862. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  4863. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  4864. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  4865. form.Set("upload_bandwidth", "0")
  4866. form.Set("download_bandwidth", "0")
  4867. form.Set("permissions", "*")
  4868. form.Set("sub_dirs_permissions", "")
  4869. form.Set("status", strconv.Itoa(user.Status))
  4870. form.Set("expiration_date", "2020-01-01 00:00:00")
  4871. form.Set("allowed_ip", "")
  4872. form.Set("denied_ip", "")
  4873. form.Set("fs_provider", "3")
  4874. form.Set("az_container", user.FsConfig.AzBlobConfig.Container)
  4875. form.Set("az_account_name", user.FsConfig.AzBlobConfig.AccountName)
  4876. form.Set("az_account_key", user.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  4877. form.Set("az_sas_url", user.FsConfig.AzBlobConfig.SASURL)
  4878. form.Set("az_endpoint", user.FsConfig.AzBlobConfig.Endpoint)
  4879. form.Set("az_key_prefix", user.FsConfig.AzBlobConfig.KeyPrefix)
  4880. form.Set("az_use_emulator", "checked")
  4881. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  4882. form.Set("denied_extensions", "/dir2::.zip")
  4883. form.Set("max_upload_file_size", "0")
  4884. // test invalid az_upload_part_size
  4885. form.Set("az_upload_part_size", "a")
  4886. b, contentType, _ := getMultipartFormData(form, "", "")
  4887. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4888. setJWTCookieForReq(req, webToken)
  4889. req.Header.Set("Content-Type", contentType)
  4890. rr = executeRequest(req)
  4891. checkResponseCode(t, http.StatusOK, rr)
  4892. // test invalid az_upload_concurrency
  4893. form.Set("az_upload_part_size", strconv.FormatInt(user.FsConfig.AzBlobConfig.UploadPartSize, 10))
  4894. form.Set("az_upload_concurrency", "a")
  4895. b, contentType, _ = getMultipartFormData(form, "", "")
  4896. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4897. setJWTCookieForReq(req, webToken)
  4898. req.Header.Set("Content-Type", contentType)
  4899. rr = executeRequest(req)
  4900. checkResponseCode(t, http.StatusOK, rr)
  4901. // now add the user
  4902. form.Set("az_upload_concurrency", strconv.Itoa(user.FsConfig.AzBlobConfig.UploadConcurrency))
  4903. b, contentType, _ = getMultipartFormData(form, "", "")
  4904. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4905. setJWTCookieForReq(req, webToken)
  4906. req.Header.Set("Content-Type", contentType)
  4907. rr = executeRequest(req)
  4908. checkResponseCode(t, http.StatusSeeOther, rr)
  4909. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4910. setBearerForReq(req, apiToken)
  4911. rr = executeRequest(req)
  4912. checkResponseCode(t, http.StatusOK, rr)
  4913. var updateUser dataprovider.User
  4914. err = render.DecodeJSON(rr.Body, &updateUser)
  4915. assert.NoError(t, err)
  4916. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  4917. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.Container, user.FsConfig.AzBlobConfig.Container)
  4918. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.AccountName, user.FsConfig.AzBlobConfig.AccountName)
  4919. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.Endpoint, user.FsConfig.AzBlobConfig.Endpoint)
  4920. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.SASURL, user.FsConfig.AzBlobConfig.SASURL)
  4921. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.KeyPrefix, user.FsConfig.AzBlobConfig.KeyPrefix)
  4922. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.UploadPartSize, user.FsConfig.AzBlobConfig.UploadPartSize)
  4923. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.UploadConcurrency, user.FsConfig.AzBlobConfig.UploadConcurrency)
  4924. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  4925. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  4926. assert.NotEmpty(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  4927. assert.Empty(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetKey())
  4928. assert.Empty(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  4929. // now check that a redacted password is not saved
  4930. form.Set("az_account_key", "[**redacted**] ")
  4931. b, contentType, _ = getMultipartFormData(form, "", "")
  4932. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4933. setJWTCookieForReq(req, webToken)
  4934. req.Header.Set("Content-Type", contentType)
  4935. rr = executeRequest(req)
  4936. checkResponseCode(t, http.StatusSeeOther, rr)
  4937. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  4938. setBearerForReq(req, apiToken)
  4939. rr = executeRequest(req)
  4940. checkResponseCode(t, http.StatusOK, rr)
  4941. var lastUpdatedUser dataprovider.User
  4942. err = render.DecodeJSON(rr.Body, &lastUpdatedUser)
  4943. assert.NoError(t, err)
  4944. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetStatus())
  4945. assert.Equal(t, updateUser.FsConfig.AzBlobConfig.AccountKey.GetPayload(), lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetPayload())
  4946. assert.Empty(t, lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetKey())
  4947. assert.Empty(t, lastUpdatedUser.FsConfig.AzBlobConfig.AccountKey.GetAdditionalData())
  4948. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  4949. setBearerForReq(req, apiToken)
  4950. rr = executeRequest(req)
  4951. checkResponseCode(t, http.StatusOK, rr)
  4952. }
  4953. func TestWebUserCryptMock(t *testing.T) {
  4954. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4955. assert.NoError(t, err)
  4956. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  4957. assert.NoError(t, err)
  4958. user := getTestUser()
  4959. userAsJSON := getUserAsJSON(t, user)
  4960. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  4961. setBearerForReq(req, apiToken)
  4962. rr := executeRequest(req)
  4963. checkResponseCode(t, http.StatusCreated, rr)
  4964. err = render.DecodeJSON(rr.Body, &user)
  4965. assert.NoError(t, err)
  4966. user.FsConfig.Provider = dataprovider.CryptedFilesystemProvider
  4967. user.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("crypted passphrase")
  4968. form := make(url.Values)
  4969. form.Set("username", user.Username)
  4970. form.Set("home_dir", user.HomeDir)
  4971. form.Set("uid", "0")
  4972. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  4973. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  4974. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  4975. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  4976. form.Set("upload_bandwidth", "0")
  4977. form.Set("download_bandwidth", "0")
  4978. form.Set("permissions", "*")
  4979. form.Set("sub_dirs_permissions", "")
  4980. form.Set("status", strconv.Itoa(user.Status))
  4981. form.Set("expiration_date", "2020-01-01 00:00:00")
  4982. form.Set("allowed_ip", "")
  4983. form.Set("denied_ip", "")
  4984. form.Set("fs_provider", "4")
  4985. form.Set("crypt_passphrase", "")
  4986. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  4987. form.Set("denied_extensions", "/dir2::.zip")
  4988. form.Set("max_upload_file_size", "0")
  4989. // passphrase cannot be empty
  4990. b, contentType, _ := getMultipartFormData(form, "", "")
  4991. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4992. setJWTCookieForReq(req, webToken)
  4993. req.Header.Set("Content-Type", contentType)
  4994. rr = executeRequest(req)
  4995. checkResponseCode(t, http.StatusOK, rr)
  4996. form.Set("crypt_passphrase", user.FsConfig.CryptConfig.Passphrase.GetPayload())
  4997. b, contentType, _ = getMultipartFormData(form, "", "")
  4998. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  4999. setJWTCookieForReq(req, webToken)
  5000. req.Header.Set("Content-Type", contentType)
  5001. rr = executeRequest(req)
  5002. checkResponseCode(t, http.StatusSeeOther, rr)
  5003. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  5004. setBearerForReq(req, apiToken)
  5005. rr = executeRequest(req)
  5006. checkResponseCode(t, http.StatusOK, rr)
  5007. var updateUser dataprovider.User
  5008. err = render.DecodeJSON(rr.Body, &updateUser)
  5009. assert.NoError(t, err)
  5010. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  5011. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  5012. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.CryptConfig.Passphrase.GetStatus())
  5013. assert.NotEmpty(t, updateUser.FsConfig.CryptConfig.Passphrase.GetPayload())
  5014. assert.Empty(t, updateUser.FsConfig.CryptConfig.Passphrase.GetKey())
  5015. assert.Empty(t, updateUser.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  5016. // now check that a redacted password is not saved
  5017. form.Set("crypt_passphrase", "[**redacted**] ")
  5018. b, contentType, _ = getMultipartFormData(form, "", "")
  5019. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  5020. setJWTCookieForReq(req, webToken)
  5021. req.Header.Set("Content-Type", contentType)
  5022. rr = executeRequest(req)
  5023. checkResponseCode(t, http.StatusSeeOther, rr)
  5024. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  5025. setBearerForReq(req, apiToken)
  5026. rr = executeRequest(req)
  5027. checkResponseCode(t, http.StatusOK, rr)
  5028. var lastUpdatedUser dataprovider.User
  5029. err = render.DecodeJSON(rr.Body, &lastUpdatedUser)
  5030. assert.NoError(t, err)
  5031. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetStatus())
  5032. assert.Equal(t, updateUser.FsConfig.CryptConfig.Passphrase.GetPayload(), lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetPayload())
  5033. assert.Empty(t, lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetKey())
  5034. assert.Empty(t, lastUpdatedUser.FsConfig.CryptConfig.Passphrase.GetAdditionalData())
  5035. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  5036. setBearerForReq(req, apiToken)
  5037. rr = executeRequest(req)
  5038. checkResponseCode(t, http.StatusOK, rr)
  5039. }
  5040. func TestWebUserSFTPFsMock(t *testing.T) {
  5041. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5042. assert.NoError(t, err)
  5043. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5044. assert.NoError(t, err)
  5045. user := getTestUser()
  5046. userAsJSON := getUserAsJSON(t, user)
  5047. req, _ := http.NewRequest(http.MethodPost, userPath, bytes.NewBuffer(userAsJSON))
  5048. setBearerForReq(req, apiToken)
  5049. rr := executeRequest(req)
  5050. checkResponseCode(t, http.StatusCreated, rr)
  5051. err = render.DecodeJSON(rr.Body, &user)
  5052. assert.NoError(t, err)
  5053. user.FsConfig.Provider = dataprovider.SFTPFilesystemProvider
  5054. user.FsConfig.SFTPConfig.Endpoint = "127.0.0.1"
  5055. user.FsConfig.SFTPConfig.Username = "sftpuser"
  5056. user.FsConfig.SFTPConfig.Password = kms.NewPlainSecret("pwd")
  5057. user.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret(sftpPrivateKey)
  5058. user.FsConfig.SFTPConfig.Fingerprints = []string{sftpPkeyFingerprint}
  5059. user.FsConfig.SFTPConfig.Prefix = "/home/sftpuser"
  5060. form := make(url.Values)
  5061. form.Set("username", user.Username)
  5062. form.Set("home_dir", user.HomeDir)
  5063. form.Set("uid", "0")
  5064. form.Set("gid", strconv.FormatInt(int64(user.GID), 10))
  5065. form.Set("max_sessions", strconv.FormatInt(int64(user.MaxSessions), 10))
  5066. form.Set("quota_size", strconv.FormatInt(user.QuotaSize, 10))
  5067. form.Set("quota_files", strconv.FormatInt(int64(user.QuotaFiles), 10))
  5068. form.Set("upload_bandwidth", "0")
  5069. form.Set("download_bandwidth", "0")
  5070. form.Set("permissions", "*")
  5071. form.Set("sub_dirs_permissions", "")
  5072. form.Set("status", strconv.Itoa(user.Status))
  5073. form.Set("expiration_date", "2020-01-01 00:00:00")
  5074. form.Set("allowed_ip", "")
  5075. form.Set("denied_ip", "")
  5076. form.Set("fs_provider", "5")
  5077. form.Set("crypt_passphrase", "")
  5078. form.Set("allowed_extensions", "/dir1::.jpg,.png")
  5079. form.Set("denied_extensions", "/dir2::.zip")
  5080. form.Set("max_upload_file_size", "0")
  5081. // empty sftpconfig
  5082. b, contentType, _ := getMultipartFormData(form, "", "")
  5083. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  5084. setJWTCookieForReq(req, webToken)
  5085. req.Header.Set("Content-Type", contentType)
  5086. rr = executeRequest(req)
  5087. checkResponseCode(t, http.StatusOK, rr)
  5088. form.Set("sftp_endpoint", user.FsConfig.SFTPConfig.Endpoint)
  5089. form.Set("sftp_username", user.FsConfig.SFTPConfig.Username)
  5090. form.Set("sftp_password", user.FsConfig.SFTPConfig.Password.GetPayload())
  5091. form.Set("sftp_private_key", user.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  5092. form.Set("sftp_fingerprints", user.FsConfig.SFTPConfig.Fingerprints[0])
  5093. form.Set("sftp_prefix", user.FsConfig.SFTPConfig.Prefix)
  5094. b, contentType, _ = getMultipartFormData(form, "", "")
  5095. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  5096. setJWTCookieForReq(req, webToken)
  5097. req.Header.Set("Content-Type", contentType)
  5098. rr = executeRequest(req)
  5099. checkResponseCode(t, http.StatusSeeOther, rr)
  5100. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  5101. setBearerForReq(req, apiToken)
  5102. rr = executeRequest(req)
  5103. checkResponseCode(t, http.StatusOK, rr)
  5104. var updateUser dataprovider.User
  5105. err = render.DecodeJSON(rr.Body, &updateUser)
  5106. assert.NoError(t, err)
  5107. assert.Equal(t, int64(1577836800000), updateUser.ExpirationDate)
  5108. assert.Equal(t, 2, len(updateUser.Filters.FileExtensions))
  5109. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.SFTPConfig.Password.GetStatus())
  5110. assert.NotEmpty(t, updateUser.FsConfig.SFTPConfig.Password.GetPayload())
  5111. assert.Empty(t, updateUser.FsConfig.SFTPConfig.Password.GetKey())
  5112. assert.Empty(t, updateUser.FsConfig.SFTPConfig.Password.GetAdditionalData())
  5113. assert.Equal(t, kms.SecretStatusSecretBox, updateUser.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  5114. assert.NotEmpty(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  5115. assert.Empty(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetKey())
  5116. assert.Empty(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  5117. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Prefix, user.FsConfig.SFTPConfig.Prefix)
  5118. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Username, user.FsConfig.SFTPConfig.Username)
  5119. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Endpoint, user.FsConfig.SFTPConfig.Endpoint)
  5120. assert.Len(t, updateUser.FsConfig.SFTPConfig.Fingerprints, 1)
  5121. assert.Contains(t, updateUser.FsConfig.SFTPConfig.Fingerprints, sftpPkeyFingerprint)
  5122. // now check that a redacted credentials are not saved
  5123. form.Set("sftp_password", "[**redacted**] ")
  5124. form.Set("sftp_private_key", "[**redacted**]")
  5125. b, contentType, _ = getMultipartFormData(form, "", "")
  5126. req, _ = http.NewRequest(http.MethodPost, path.Join(webUserPath, user.Username), &b)
  5127. setJWTCookieForReq(req, webToken)
  5128. req.Header.Set("Content-Type", contentType)
  5129. rr = executeRequest(req)
  5130. checkResponseCode(t, http.StatusSeeOther, rr)
  5131. req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
  5132. setBearerForReq(req, apiToken)
  5133. rr = executeRequest(req)
  5134. checkResponseCode(t, http.StatusOK, rr)
  5135. var lastUpdatedUser dataprovider.User
  5136. err = render.DecodeJSON(rr.Body, &lastUpdatedUser)
  5137. assert.NoError(t, err)
  5138. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.SFTPConfig.Password.GetStatus())
  5139. assert.Equal(t, updateUser.FsConfig.SFTPConfig.Password.GetPayload(), lastUpdatedUser.FsConfig.SFTPConfig.Password.GetPayload())
  5140. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.Password.GetKey())
  5141. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.Password.GetAdditionalData())
  5142. assert.Equal(t, kms.SecretStatusSecretBox, lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetStatus())
  5143. assert.Equal(t, updateUser.FsConfig.SFTPConfig.PrivateKey.GetPayload(), lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetPayload())
  5144. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetKey())
  5145. assert.Empty(t, lastUpdatedUser.FsConfig.SFTPConfig.PrivateKey.GetAdditionalData())
  5146. req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
  5147. setBearerForReq(req, apiToken)
  5148. rr = executeRequest(req)
  5149. checkResponseCode(t, http.StatusOK, rr)
  5150. }
  5151. func TestAddWebFoldersMock(t *testing.T) {
  5152. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5153. assert.NoError(t, err)
  5154. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5155. assert.NoError(t, err)
  5156. mappedPath := filepath.Clean(os.TempDir())
  5157. folderName := filepath.Base(mappedPath)
  5158. form := make(url.Values)
  5159. form.Set("mapped_path", mappedPath)
  5160. form.Set("name", folderName)
  5161. req, err := http.NewRequest(http.MethodPost, webFolderPath, strings.NewReader(form.Encode()))
  5162. assert.NoError(t, err)
  5163. setJWTCookieForReq(req, webToken)
  5164. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5165. rr := executeRequest(req)
  5166. checkResponseCode(t, http.StatusSeeOther, rr)
  5167. // adding the same folder will fail since the name must be unique
  5168. req, err = http.NewRequest(http.MethodPost, webFolderPath, strings.NewReader(form.Encode()))
  5169. assert.NoError(t, err)
  5170. setJWTCookieForReq(req, webToken)
  5171. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5172. rr = executeRequest(req)
  5173. checkResponseCode(t, http.StatusOK, rr)
  5174. // invalid form
  5175. req, err = http.NewRequest(http.MethodPost, webFolderPath, strings.NewReader(form.Encode()))
  5176. assert.NoError(t, err)
  5177. setJWTCookieForReq(req, webToken)
  5178. req.Header.Set("Content-Type", "text/plain; boundary=")
  5179. rr = executeRequest(req)
  5180. checkResponseCode(t, http.StatusOK, rr)
  5181. // now render the add folder page
  5182. req, err = http.NewRequest(http.MethodGet, webFolderPath, nil)
  5183. assert.NoError(t, err)
  5184. setJWTCookieForReq(req, webToken)
  5185. rr = executeRequest(req)
  5186. checkResponseCode(t, http.StatusOK, rr)
  5187. var folder vfs.BaseVirtualFolder
  5188. req, _ = http.NewRequest(http.MethodGet, path.Join(folderPath, folderName), nil)
  5189. setBearerForReq(req, apiToken)
  5190. rr = executeRequest(req)
  5191. checkResponseCode(t, http.StatusOK, rr)
  5192. err = render.DecodeJSON(rr.Body, &folder)
  5193. assert.NoError(t, err)
  5194. assert.Equal(t, mappedPath, folder.MappedPath)
  5195. assert.Equal(t, folderName, folder.Name)
  5196. // cleanup
  5197. req, _ = http.NewRequest(http.MethodDelete, path.Join(folderPath, folderName), nil)
  5198. setBearerForReq(req, apiToken)
  5199. rr = executeRequest(req)
  5200. checkResponseCode(t, http.StatusOK, rr)
  5201. }
  5202. func TestUpdateWebFolderMock(t *testing.T) {
  5203. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5204. assert.NoError(t, err)
  5205. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5206. assert.NoError(t, err)
  5207. folderName := "vfolderupdate"
  5208. folder := vfs.BaseVirtualFolder{
  5209. Name: folderName,
  5210. MappedPath: filepath.Join(os.TempDir(), "folderupdate"),
  5211. }
  5212. _, _, err = httpdtest.AddFolder(folder, http.StatusCreated)
  5213. newMappedPath := folder.MappedPath + "1"
  5214. assert.NoError(t, err)
  5215. form := make(url.Values)
  5216. form.Set("mapped_path", newMappedPath)
  5217. form.Set("name", folderName)
  5218. req, err := http.NewRequest(http.MethodPost, path.Join(webFolderPath, folderName), strings.NewReader(form.Encode()))
  5219. assert.NoError(t, err)
  5220. setJWTCookieForReq(req, webToken)
  5221. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5222. rr := executeRequest(req)
  5223. checkResponseCode(t, http.StatusSeeOther, rr)
  5224. // parse form error
  5225. req, err = http.NewRequest(http.MethodPost, path.Join(webFolderPath, folderName)+"??a=a%B3%A2%G3", strings.NewReader(form.Encode()))
  5226. assert.NoError(t, err)
  5227. setJWTCookieForReq(req, webToken)
  5228. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5229. rr = executeRequest(req)
  5230. checkResponseCode(t, http.StatusOK, rr)
  5231. assert.Contains(t, rr.Body.String(), "invalid URL escape")
  5232. req, err = http.NewRequest(http.MethodPost, path.Join(webFolderPath, folderName+"1"), strings.NewReader(form.Encode()))
  5233. assert.NoError(t, err)
  5234. setJWTCookieForReq(req, webToken)
  5235. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5236. rr = executeRequest(req)
  5237. checkResponseCode(t, http.StatusNotFound, rr)
  5238. form.Set("mapped_path", "arelative/path")
  5239. req, err = http.NewRequest(http.MethodPost, path.Join(webFolderPath, folderName), strings.NewReader(form.Encode()))
  5240. assert.NoError(t, err)
  5241. setJWTCookieForReq(req, webToken)
  5242. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5243. rr = executeRequest(req)
  5244. checkResponseCode(t, http.StatusOK, rr)
  5245. // render update folder page
  5246. req, err = http.NewRequest(http.MethodGet, path.Join(webFolderPath, folderName), nil)
  5247. assert.NoError(t, err)
  5248. setJWTCookieForReq(req, webToken)
  5249. rr = executeRequest(req)
  5250. checkResponseCode(t, http.StatusOK, rr)
  5251. req, err = http.NewRequest(http.MethodGet, path.Join(webFolderPath, folderName+"1"), nil)
  5252. assert.NoError(t, err)
  5253. setJWTCookieForReq(req, webToken)
  5254. rr = executeRequest(req)
  5255. checkResponseCode(t, http.StatusNotFound, rr)
  5256. req, _ = http.NewRequest(http.MethodDelete, path.Join(folderPath, folderName), nil)
  5257. setBearerForReq(req, apiToken)
  5258. rr = executeRequest(req)
  5259. checkResponseCode(t, http.StatusOK, rr)
  5260. }
  5261. func TestWebFoldersMock(t *testing.T) {
  5262. webToken, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5263. assert.NoError(t, err)
  5264. apiToken, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5265. assert.NoError(t, err)
  5266. mappedPath1 := filepath.Join(os.TempDir(), "vfolder1")
  5267. mappedPath2 := filepath.Join(os.TempDir(), "vfolder2")
  5268. folderName1 := filepath.Base(mappedPath1)
  5269. folderName2 := filepath.Base(mappedPath2)
  5270. folders := []vfs.BaseVirtualFolder{
  5271. {
  5272. Name: folderName1,
  5273. MappedPath: mappedPath1,
  5274. },
  5275. {
  5276. Name: folderName2,
  5277. MappedPath: mappedPath2,
  5278. },
  5279. }
  5280. for _, folder := range folders {
  5281. folderAsJSON, err := json.Marshal(folder)
  5282. assert.NoError(t, err)
  5283. req, _ := http.NewRequest(http.MethodPost, folderPath, bytes.NewBuffer(folderAsJSON))
  5284. setBearerForReq(req, apiToken)
  5285. rr := executeRequest(req)
  5286. checkResponseCode(t, http.StatusCreated, rr)
  5287. }
  5288. req, err := http.NewRequest(http.MethodGet, webFoldersPath, nil)
  5289. assert.NoError(t, err)
  5290. setJWTCookieForReq(req, webToken)
  5291. rr := executeRequest(req)
  5292. checkResponseCode(t, http.StatusOK, rr)
  5293. req, err = http.NewRequest(http.MethodGet, webFoldersPath+"?qlimit=a", nil)
  5294. assert.NoError(t, err)
  5295. setJWTCookieForReq(req, webToken)
  5296. rr = executeRequest(req)
  5297. checkResponseCode(t, http.StatusOK, rr)
  5298. req, err = http.NewRequest(http.MethodGet, webFoldersPath+"?qlimit=1", nil)
  5299. assert.NoError(t, err)
  5300. setJWTCookieForReq(req, webToken)
  5301. rr = executeRequest(req)
  5302. checkResponseCode(t, http.StatusOK, rr)
  5303. for _, folder := range folders {
  5304. req, _ := http.NewRequest(http.MethodDelete, path.Join(folderPath, folder.Name), nil)
  5305. setBearerForReq(req, apiToken)
  5306. rr := executeRequest(req)
  5307. checkResponseCode(t, http.StatusOK, rr)
  5308. }
  5309. }
  5310. func TestProviderClosedMock(t *testing.T) {
  5311. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5312. assert.NoError(t, err)
  5313. dataprovider.Close()
  5314. req, _ := http.NewRequest(http.MethodGet, webFoldersPath, nil)
  5315. setJWTCookieForReq(req, token)
  5316. rr := executeRequest(req)
  5317. checkResponseCode(t, http.StatusInternalServerError, rr)
  5318. req, _ = http.NewRequest(http.MethodGet, webUsersPath, nil)
  5319. setJWTCookieForReq(req, token)
  5320. rr = executeRequest(req)
  5321. checkResponseCode(t, http.StatusInternalServerError, rr)
  5322. req, _ = http.NewRequest(http.MethodGet, webUserPath+"/0", nil)
  5323. setJWTCookieForReq(req, token)
  5324. rr = executeRequest(req)
  5325. checkResponseCode(t, http.StatusInternalServerError, rr)
  5326. form := make(url.Values)
  5327. form.Set("username", "test")
  5328. req, _ = http.NewRequest(http.MethodPost, webUserPath+"/0", strings.NewReader(form.Encode()))
  5329. setJWTCookieForReq(req, token)
  5330. rr = executeRequest(req)
  5331. checkResponseCode(t, http.StatusInternalServerError, rr)
  5332. req, _ = http.NewRequest(http.MethodGet, path.Join(webAdminPath, defaultTokenAuthUser), nil)
  5333. setJWTCookieForReq(req, token)
  5334. rr = executeRequest(req)
  5335. checkResponseCode(t, http.StatusInternalServerError, rr)
  5336. req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, defaultTokenAuthUser), strings.NewReader(form.Encode()))
  5337. setJWTCookieForReq(req, token)
  5338. rr = executeRequest(req)
  5339. checkResponseCode(t, http.StatusInternalServerError, rr)
  5340. req, _ = http.NewRequest(http.MethodGet, webAdminsPath, nil)
  5341. setJWTCookieForReq(req, token)
  5342. rr = executeRequest(req)
  5343. checkResponseCode(t, http.StatusInternalServerError, rr)
  5344. req, _ = http.NewRequest(http.MethodGet, path.Join(webFolderPath, defaultTokenAuthUser), nil)
  5345. setJWTCookieForReq(req, token)
  5346. rr = executeRequest(req)
  5347. checkResponseCode(t, http.StatusInternalServerError, rr)
  5348. req, _ = http.NewRequest(http.MethodPost, path.Join(webFolderPath, defaultTokenAuthUser), strings.NewReader(form.Encode()))
  5349. setJWTCookieForReq(req, token)
  5350. rr = executeRequest(req)
  5351. checkResponseCode(t, http.StatusInternalServerError, rr)
  5352. err = config.LoadConfig(configDir, "")
  5353. assert.NoError(t, err)
  5354. providerConf := config.GetProviderConf()
  5355. providerConf.CredentialsPath = credentialsPath
  5356. err = os.RemoveAll(credentialsPath)
  5357. assert.NoError(t, err)
  5358. err = dataprovider.Initialize(providerConf, configDir, true)
  5359. assert.NoError(t, err)
  5360. }
  5361. func TestGetWebConnectionsMock(t *testing.T) {
  5362. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5363. assert.NoError(t, err)
  5364. req, _ := http.NewRequest(http.MethodGet, webConnectionsPath, nil)
  5365. setJWTCookieForReq(req, token)
  5366. rr := executeRequest(req)
  5367. checkResponseCode(t, http.StatusOK, rr)
  5368. }
  5369. func TestGetWebStatusMock(t *testing.T) {
  5370. token, err := getJWTWebTokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
  5371. assert.NoError(t, err)
  5372. req, _ := http.NewRequest(http.MethodGet, webStatusPath, nil)
  5373. setJWTCookieForReq(req, token)
  5374. rr := executeRequest(req)
  5375. checkResponseCode(t, http.StatusOK, rr)
  5376. }
  5377. func TestStaticFilesMock(t *testing.T) {
  5378. req, _ := http.NewRequest(http.MethodGet, "/static/favicon.ico", nil)
  5379. rr := executeRequest(req)
  5380. checkResponseCode(t, http.StatusOK, rr)
  5381. }
  5382. func waitTCPListening(address string) {
  5383. for {
  5384. conn, err := net.Dial("tcp", address)
  5385. if err != nil {
  5386. logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
  5387. time.Sleep(100 * time.Millisecond)
  5388. continue
  5389. }
  5390. logger.InfoToConsole("tcp server %v now listening\n", address)
  5391. conn.Close()
  5392. break
  5393. }
  5394. }
  5395. func getTestAdmin() dataprovider.Admin {
  5396. return dataprovider.Admin{
  5397. Username: defaultTokenAuthUser,
  5398. Password: defaultTokenAuthPass,
  5399. Status: 1,
  5400. Permissions: []string{dataprovider.PermAdminAny},
  5401. Email: "[email protected]",
  5402. }
  5403. }
  5404. func getTestUser() dataprovider.User {
  5405. user := dataprovider.User{
  5406. Username: defaultUsername,
  5407. Password: defaultPassword,
  5408. HomeDir: filepath.Join(homeBasePath, defaultUsername),
  5409. Status: 1,
  5410. }
  5411. user.Permissions = make(map[string][]string)
  5412. user.Permissions["/"] = defaultPerms
  5413. return user
  5414. }
  5415. func getUserAsJSON(t *testing.T, user dataprovider.User) []byte {
  5416. json, err := json.Marshal(user)
  5417. assert.NoError(t, err)
  5418. return json
  5419. }
  5420. func getAdminLoginForm(username, password string) url.Values {
  5421. form := make(url.Values)
  5422. form.Set("username", username)
  5423. form.Set("password", password)
  5424. return form
  5425. }
  5426. func setBearerForReq(req *http.Request, jwtToken string) {
  5427. req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", jwtToken))
  5428. }
  5429. func setJWTCookieForReq(req *http.Request, jwtToken string) {
  5430. req.Header.Set("Cookie", fmt.Sprintf("jwt=%v", jwtToken))
  5431. }
  5432. func getJWTAPITokenFromTestServer(username, password string) (string, error) {
  5433. req, _ := http.NewRequest(http.MethodGet, "/api/v2/token", nil)
  5434. req.SetBasicAuth(username, password)
  5435. rr := executeRequest(req)
  5436. if rr.Code != http.StatusOK {
  5437. return "", fmt.Errorf("unexpected status code %v", rr)
  5438. }
  5439. responseHolder := make(map[string]interface{})
  5440. err := render.DecodeJSON(rr.Body, &responseHolder)
  5441. if err != nil {
  5442. return "", err
  5443. }
  5444. return responseHolder["access_token"].(string), nil
  5445. }
  5446. func getJWTWebToken(username, password string) (string, error) {
  5447. form := getAdminLoginForm(username, password)
  5448. req, _ := http.NewRequest(http.MethodPost, httpBaseURL+webLoginPath,
  5449. bytes.NewBuffer([]byte(form.Encode())))
  5450. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5451. client := &http.Client{
  5452. Timeout: 10 * time.Second,
  5453. CheckRedirect: func(req *http.Request, via []*http.Request) error {
  5454. return http.ErrUseLastResponse
  5455. },
  5456. }
  5457. resp, err := client.Do(req)
  5458. if err != nil {
  5459. return "", err
  5460. }
  5461. defer resp.Body.Close()
  5462. if resp.StatusCode != http.StatusFound {
  5463. return "", fmt.Errorf("unexpected status code %v", resp.StatusCode)
  5464. }
  5465. cookie := resp.Header.Get("Set-Cookie")
  5466. if strings.HasPrefix(cookie, "jwt=") {
  5467. return cookie[4:], nil
  5468. }
  5469. return "", errors.New("no cookie found")
  5470. }
  5471. func getJWTWebTokenFromTestServer(username, password string) (string, error) {
  5472. form := getAdminLoginForm(username, password)
  5473. req, _ := http.NewRequest(http.MethodPost, webLoginPath, bytes.NewBuffer([]byte(form.Encode())))
  5474. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  5475. rr := executeRequest(req)
  5476. if rr.Code != http.StatusFound {
  5477. return "", fmt.Errorf("unexpected status code %v", rr)
  5478. }
  5479. cookie := strings.Split(rr.Header().Get("Set-Cookie"), ";")
  5480. if strings.HasPrefix(cookie[0], "jwt=") {
  5481. return cookie[0][4:], nil
  5482. }
  5483. return "", errors.New("no cookie found")
  5484. }
  5485. func executeRequest(req *http.Request) *httptest.ResponseRecorder {
  5486. rr := httptest.NewRecorder()
  5487. testServer.Config.Handler.ServeHTTP(rr, req)
  5488. return rr
  5489. }
  5490. func checkResponseCode(t *testing.T, expected int, rr *httptest.ResponseRecorder) {
  5491. assert.Equal(t, expected, rr.Code, rr.Body.String())
  5492. }
  5493. func createTestFile(path string, size int64) error {
  5494. baseDir := filepath.Dir(path)
  5495. if _, err := os.Stat(baseDir); os.IsNotExist(err) {
  5496. err = os.MkdirAll(baseDir, os.ModePerm)
  5497. if err != nil {
  5498. return err
  5499. }
  5500. }
  5501. content := make([]byte, size)
  5502. if size > 0 {
  5503. _, err := rand.Read(content)
  5504. if err != nil {
  5505. return err
  5506. }
  5507. }
  5508. return ioutil.WriteFile(path, content, os.ModePerm)
  5509. }
  5510. func getMultipartFormData(values url.Values, fileFieldName, filePath string) (bytes.Buffer, string, error) {
  5511. var b bytes.Buffer
  5512. w := multipart.NewWriter(&b)
  5513. for k, v := range values {
  5514. for _, s := range v {
  5515. if err := w.WriteField(k, s); err != nil {
  5516. return b, "", err
  5517. }
  5518. }
  5519. }
  5520. if len(fileFieldName) > 0 && len(filePath) > 0 {
  5521. fw, err := w.CreateFormFile(fileFieldName, filepath.Base(filePath))
  5522. if err != nil {
  5523. return b, "", err
  5524. }
  5525. f, err := os.Open(filePath)
  5526. if err != nil {
  5527. return b, "", err
  5528. }
  5529. defer f.Close()
  5530. if _, err = io.Copy(fw, f); err != nil {
  5531. return b, "", err
  5532. }
  5533. }
  5534. err := w.Close()
  5535. return b, w.FormDataContentType(), err
  5536. }
  5537. func BenchmarkSecretDecryption(b *testing.B) {
  5538. s := kms.NewPlainSecret("test data")
  5539. s.SetAdditionalData("username")
  5540. err := s.Encrypt()
  5541. require.NoError(b, err)
  5542. for i := 0; i < b.N; i++ {
  5543. err = s.Clone().Decrypt()
  5544. require.NoError(b, err)
  5545. }
  5546. }