internal_test.go 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731
  1. // Copyright (C) 2019 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package webdavd
  15. import (
  16. "context"
  17. "crypto/tls"
  18. "crypto/x509"
  19. "encoding/xml"
  20. "fmt"
  21. "io"
  22. "net/http"
  23. "net/http/httptest"
  24. "os"
  25. "path"
  26. "path/filepath"
  27. "runtime"
  28. "testing"
  29. "time"
  30. "github.com/drakkan/webdav"
  31. "github.com/eikenb/pipeat"
  32. "github.com/sftpgo/sdk"
  33. "github.com/stretchr/testify/assert"
  34. "github.com/stretchr/testify/require"
  35. "github.com/drakkan/sftpgo/v2/internal/common"
  36. "github.com/drakkan/sftpgo/v2/internal/dataprovider"
  37. "github.com/drakkan/sftpgo/v2/internal/kms"
  38. "github.com/drakkan/sftpgo/v2/internal/util"
  39. "github.com/drakkan/sftpgo/v2/internal/vfs"
  40. )
  41. const (
  42. testFile = "test_dav_file"
  43. webDavCert = `-----BEGIN CERTIFICATE-----
  44. MIICHTCCAaKgAwIBAgIUHnqw7QnB1Bj9oUsNpdb+ZkFPOxMwCgYIKoZIzj0EAwIw
  45. RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
  46. dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDAyMDQwOTUzMDRaFw0zMDAyMDEw
  47. OTUzMDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
  48. VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
  49. IgNiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVqWvrJ51t5OxV0v25NsOgR82CA
  50. NXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIVCzgWkxiz7XE4lgUwX44FCXZM
  51. 3+JeUbKjUzBRMB0GA1UdDgQWBBRhLw+/o3+Z02MI/d4tmaMui9W16jAfBgNVHSME
  52. GDAWgBRhLw+/o3+Z02MI/d4tmaMui9W16jAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
  53. SM49BAMCA2kAMGYCMQDqLt2lm8mE+tGgtjDmtFgdOcI72HSbRQ74D5rYTzgST1rY
  54. /8wTi5xl8TiFUyLMUsICMQC5ViVxdXbhuG7gX6yEqSkMKZICHpO8hqFwOD/uaFVI
  55. dV4vKmHUzwK/eIx+8Ay3neE=
  56. -----END CERTIFICATE-----`
  57. webDavKey = `-----BEGIN EC PARAMETERS-----
  58. BgUrgQQAIg==
  59. -----END EC PARAMETERS-----
  60. -----BEGIN EC PRIVATE KEY-----
  61. MIGkAgEBBDCfMNsN6miEE3rVyUPwElfiJSWaR5huPCzUenZOfJT04GAcQdWvEju3
  62. UM2lmBLIXpGgBwYFK4EEACKhZANiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVq
  63. WvrJ51t5OxV0v25NsOgR82CANXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIV
  64. CzgWkxiz7XE4lgUwX44FCXZM3+JeUbI=
  65. -----END EC PRIVATE KEY-----`
  66. caCRT = `-----BEGIN CERTIFICATE-----
  67. MIIE5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhDZXJ0
  68. QXV0aDAeFw0yNDAxMTAxODEyMDRaFw0zNDAxMTAxODIxNTRaMBMxETAPBgNVBAMT
  69. CENlcnRBdXRoMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7WHW216m
  70. fi4uF8cx6HWf8wvAxaEWgCHTOi2MwFIzOrOtuT7xb64rkpdzx1aWetSiCrEyc3D1
  71. v03k0Akvlz1gtnDtO64+MA8bqlTnCydZJY4cCTvDOBUYZgtMqHZzpE6xRrqQ84zh
  72. yzjKQ5bR0st+XGfIkuhjSuf2n/ZPS37fge9j6AKzn/2uEVt33qmO85WtN3RzbSqL
  73. CdOJ6cQ216j3la1C5+NWvzIKC7t6NE1bBGI4+tRj7B5P5MeamkkogwbExUjdHp3U
  74. 4yasvoGcCHUQDoa4Dej1faywz6JlwB6rTV4ys4aZDe67V/Q8iB2May1k7zBz1Ztb
  75. KF5Em3xewP1LqPEowF1uc4KtPGcP4bxdaIpSpmObcn8AIfH6smLQrn0C3cs7CYfo
  76. NlFuTbwzENUhjz0X6EsoM4w4c87lO+dRNR7YpHLqR/BJTbbyXUB0imne1u00fuzb
  77. S7OtweiA9w7DRCkr2gU4lmHe7l0T+SA9pxIeVLb78x7ivdyXSF5LVQJ1JvhhWu6i
  78. M6GQdLHat/0fpRFUbEe34RQSDJ2eOBifMJqvsvpBP8d2jcRZVUVrSXGc2mAGuGOY
  79. /tmnCJGW8Fd+sgpCVAqM0pxCM+apqrvJYUqqQZ2ZxugCXULtRWJ9p4C9zUl40HEy
  80. OQ+AaiiwFll/doXELglcJdNg8AZPGhugfxMCAwEAAaNFMEMwDgYDVR0PAQH/BAQD
  81. AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFNoJhIvDZQrEf/VQbWuu
  82. XgNnt2m5MA0GCSqGSIb3DQEBCwUAA4ICAQCYhT5SRqk19hGrQ09hVSZOzynXAa5F
  83. sYkEWJzFyLg9azhnTPE1bFM18FScnkd+dal6mt+bQiJvdh24NaVkDghVB7GkmXki
  84. pAiZwEDHMqtbhiPxY8LtSeCBAz5JqXVU2Q0TpAgNSH4W7FbGWNThhxcJVOoIrXKE
  85. jbzhwl1Etcaf0DBKWliUbdlxQQs65DLy+rNBYtOeK0pzhzn1vpehUlJ4eTFzP9KX
  86. y2Mksuq9AspPbqnqpWW645MdTxMb5T57MCrY3GDKw63z5z3kz88LWJF3nOxZmgQy
  87. WFUhbLmZm7x6N5eiu6Wk8/B4yJ/n5UArD4cEP1i7nqu+mbbM/SZlq1wnGpg/sbRV
  88. oUF+a7pRcSbfxEttle4pLFhS+ErKatjGcNEab2OlU3bX5UoBs+TYodnCWGKOuBKV
  89. L/CYc65QyeYZ+JiwYn9wC8YkzOnnVIQjiCEkLgSL30h9dxpnTZDLrdAA8ItelDn5
  90. DvjuQq58CGDsaVqpSobiSC1DMXYWot4Ets1wwovUNEq1l0MERB+2olE+JU/8E23E
  91. eL1/aA7Kw/JibkWz1IyzClpFDKXf6kR2onJyxerdwUL+is7tqYFLysiHxZDL1bli
  92. SXbW8hMa5gvo0IilFP9Rznn8PplIfCsvBDVv6xsRr5nTAFtwKaMBVgznE2ghs69w
  93. kK8u1YiiVenmoQ==
  94. -----END CERTIFICATE-----`
  95. caKey = `-----BEGIN RSA PRIVATE KEY-----
  96. MIIJKgIBAAKCAgEA7WHW216mfi4uF8cx6HWf8wvAxaEWgCHTOi2MwFIzOrOtuT7x
  97. b64rkpdzx1aWetSiCrEyc3D1v03k0Akvlz1gtnDtO64+MA8bqlTnCydZJY4cCTvD
  98. OBUYZgtMqHZzpE6xRrqQ84zhyzjKQ5bR0st+XGfIkuhjSuf2n/ZPS37fge9j6AKz
  99. n/2uEVt33qmO85WtN3RzbSqLCdOJ6cQ216j3la1C5+NWvzIKC7t6NE1bBGI4+tRj
  100. 7B5P5MeamkkogwbExUjdHp3U4yasvoGcCHUQDoa4Dej1faywz6JlwB6rTV4ys4aZ
  101. De67V/Q8iB2May1k7zBz1ZtbKF5Em3xewP1LqPEowF1uc4KtPGcP4bxdaIpSpmOb
  102. cn8AIfH6smLQrn0C3cs7CYfoNlFuTbwzENUhjz0X6EsoM4w4c87lO+dRNR7YpHLq
  103. R/BJTbbyXUB0imne1u00fuzbS7OtweiA9w7DRCkr2gU4lmHe7l0T+SA9pxIeVLb7
  104. 8x7ivdyXSF5LVQJ1JvhhWu6iM6GQdLHat/0fpRFUbEe34RQSDJ2eOBifMJqvsvpB
  105. P8d2jcRZVUVrSXGc2mAGuGOY/tmnCJGW8Fd+sgpCVAqM0pxCM+apqrvJYUqqQZ2Z
  106. xugCXULtRWJ9p4C9zUl40HEyOQ+AaiiwFll/doXELglcJdNg8AZPGhugfxMCAwEA
  107. AQKCAgEA4x0OoceG54ZrVxifqVaQd8qw3uRmUKUMIMdfuMlsdideeLO97ynmSlRY
  108. 00kGo/I4Lp6mNEjI9gUie9+uBrcUhri4YLcujHCH+YlNnCBDbGjwbe0ds9SLCWaa
  109. KztZHMSlW5Q4Bqytgu+MpOnxSgqjlOk+vz9TcGFKVnUkHIkAcqKFJX8gOFxPZA/t
  110. Ob1kJaz4kuv5W2Kur/ISKvQtvFvOtQeV0aJyZm8LqXnvS4cPI7yN4329NDU0HyDR
  111. y/deqS2aqV4zII3FFqbz8zix/m1xtVQzWCugZGMKrz0iuJMfNeCABb8rRGc6GsZz
  112. +465v/kobqgeyyneJ1s5rMFrLp2o+dwmnIVMNsFDUiN1lIZDHLvlgonaUO3IdTZc
  113. 9asamFWKFKUMgWqM4zB1vmUO12CKowLNIIKb0L+kf1ixaLLDRGf/f9vLtSHE+oyx
  114. lATiS18VNA8+CGsHF6uXMRwf2auZdRI9+s6AAeyRISSbO1khyWKHo+bpOvmPAkDR
  115. nknTjbYgkoZOV+mrsU5oxV8s6vMkuvA3rwFhT2gie8pokuACFcCRrZi9MVs4LmUQ
  116. u0GYTHvp2WJUjMWBm6XX7Hk3g2HV842qpk/mdtTjNsXws81djtJPn4I/soIXSgXz
  117. pY3SvKTuOckP9OZVF0yqKGeZXKpD288PKpC+MAg3GvEJaednagECggEBAPsfLwuP
  118. L1kiDjXyMcRoKlrQ6Q/zBGyBmJbZ5uVGa02+XtYtDAzLoVupPESXL0E7+r8ZpZ39
  119. 0dV4CEJKpbVS/BBtTEkPpTK5kz778Ib04TAyj+YLhsZjsnuja3T5bIBZXFDeDVDM
  120. 0ZaoFoKpIjTu2aO6pzngsgXs6EYbo2MTuJD3h0nkGZsICL7xvT9Mw0P1p2Ftt/hN
  121. +jKk3vN220wTWUsq43AePi45VwK+PNP12ZXv9HpWDxlPo3j0nXtgYXittYNAT92u
  122. BZbFAzldEIX9WKKZgsWtIzLaASjVRntpxDCTby/nlzQ5dw3DHU1DV3PIqxZS2+Oe
  123. KV+7XFWgZ44YjYECggEBAPH+VDu3QSrqSahkZLkgBtGRkiZPkZFXYvU6kL8qf5wO
  124. Z/uXMeqHtznAupLea8I4YZLfQim/NfC0v1cAcFa9Ckt9g3GwTSirVcN0AC1iOyv3
  125. /hMZCA1zIyIcuUplNr8qewoX71uPOvCNH0dix77423mKFkJmNwzy4Q+rV+qkRdLn
  126. v+AAgh7g5N91pxNd6LQJjoyfi1Ka6rRP2yGXM5v7QOwD16eN4JmExUxX1YQ7uNuX
  127. pVS+HRxnBquA+3/DB1LtBX6pa2cUa+LRUmE/NCPHMvJcyuNkYpJKlNTd9vnbfo0H
  128. RNSJSWm+aGxDFMjuPjV3JLj2OdKMPwpnXdh2vBZCPpMCggEAM+yTvrEhmi2HgLIO
  129. hkz/jP2rYyfdn04ArhhqPLgd0dpuI5z24+Jq/9fzZT9ZfwSW6VK1QwDLlXcXRhXH
  130. Q8Hf6smev3CjuORURO61IkKaGWwrAucZPAY7ToNQ4cP9ImDXzMTNPgrLv3oMBYJR
  131. V16X09nxX+9NABqnQG/QjdjzDc6Qw7+NZ9f2bvzvI5qMuY2eyW91XbtJ45ThoLfP
  132. ymAp03gPxQwL0WT7z85kJ3OrROxzwaPvxU0JQSZbNbqNDPXmFTiECxNDhpRAAWlz
  133. 1DC5Vg2l05fkMkyPdtD6nOQWs/CYSfB5/EtxiX/xnBszhvZUIe6KFvuKFIhaJD5h
  134. iykagQKCAQEAoBRm8k3KbTIo4ZzvyEq4V/+dF3zBRczx6FkCkYLygXBCNvsQiR2Y
  135. BjtI8Ijz7bnQShEoOmeDriRTAqGGrspEuiVgQ1+l2wZkKHRe/aaij/Zv+4AuhH8q
  136. uZEYvW7w5Uqbs9SbgQzhp2kjTNy6V8lVnjPLf8cQGZ+9Y9krwktC6T5m/i435WdN
  137. 38h7amNP4XEE/F86Eb3rDrZYtgLIoCF4E+iCyxMehU+AGH1uABhls9XAB6vvo+8/
  138. SUp8lEqWWLP0U5KNOtYWfCeOAEiIHDbUq+DYUc4BKtbtV1cx3pzlPTOWw6XBi5Lq
  139. jttdL4HyYvnasAQpwe8GcMJqIRyCVZMiwwKCAQEAhQTTS3CC8PwcoYrpBdTjW1ck
  140. vVFeF1YbfqPZfYxASCOtdx6wRnnEJ+bjqntagns9e88muxj9UhxSL6q9XaXQBD8+
  141. 2AmKUxphCZQiYFZcTucjQEQEI2nN+nAKgRrUSMMGiR8Ekc2iFrcxBU0dnSohw+aB
  142. PbMKVypQCREu9PcDFIp9rXQTeElbaNsIg1C1w/SQjODbmN/QFHTVbRODYqLeX1J/
  143. VcGsykSIq7hv6bjn7JGkr2JTdANbjk9LnMjMdJFsKRYxPKkOQfYred6Hiojp5Sor
  144. PW5am8ejnNSPhIfqQp3uV3KhwPDKIeIpzvrB4uPfTjQWhekHCb8cKSWux3flqw==
  145. -----END RSA PRIVATE KEY-----`
  146. caCRL = `-----BEGIN X509 CRL-----
  147. MIICpzCBkAIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhDZXJ0QXV0aBcN
  148. MjQwMTEwMTgyMjU4WhcNMjYwMTA5MTgyMjU4WjAkMCICEQDOaeHbjY4pEj8WBmqg
  149. ZuRRFw0yNDAxMTAxODIyNThaoCMwITAfBgNVHSMEGDAWgBTaCYSLw2UKxH/1UG1r
  150. rl4DZ7dpuTANBgkqhkiG9w0BAQsFAAOCAgEAZzZ4aBqCcAJigR9e/mqKpJa4B6FV
  151. +jZmnWXolGeUuVkjdiG9w614x7mB2S768iioJyALejjCZjqsp6ydxtn0epQw4199
  152. XSfPIxA9lxc7w79GLe0v3ztojvxDPh5V1+lwPzGf9i8AsGqb2BrcBqgxDeatndnE
  153. jF+18bY1saXOBpukNLjtRScUXzy5YcSuO6mwz4548v+1ebpF7W4Yh+yh0zldJKcF
  154. DouuirZWujJwTwxxfJ+2+yP7GAuefXUOhYs/1y9ylvUgvKFqSyokv6OaVgTooKYD
  155. MSADzmNcbRvwyAC5oL2yJTVVoTFeP6fXl/BdFH3sO/hlKXGy4Wh1AjcVE6T0CSJ4
  156. iYFX3gLFh6dbP9IQWMlIM5DKtAKSjmgOywEaWii3e4M0NFSf/Cy17p2E5/jXSLlE
  157. ypDileK0aALkx2twGWwogh6sY1dQ6R3GpKSRPD2muQxVOG6wXvuJce0E9WLx1Ud4
  158. hVUdUEMlKUvm77/15U5awarH2cCJQxzS/GMeIintQiG7hUlgRzRdmWVe3vOOvt94
  159. cp8+ZUH/QSDOo41ATTHpFeC/XqF5E2G/ahXqra+O5my52V/FP0bSJnkorJ8apy67
  160. sn6DFbkqX9khTXGtacczh2PcqVjcQjBniYl2sPO3qIrrrY3tic96tMnM/u3JRdcn
  161. w7bXJGfJcIMrrKs=
  162. -----END X509 CRL-----`
  163. client1Crt = `-----BEGIN CERTIFICATE-----
  164. MIIEITCCAgmgAwIBAgIRAJr32nHRlhyPiS7IfZ/ZWYowDQYJKoZIhvcNAQELBQAw
  165. EzERMA8GA1UEAxMIQ2VydEF1dGgwHhcNMjQwMTEwMTgxMjM3WhcNMzQwMTEwMTgy
  166. MTUzWjASMRAwDgYDVQQDEwdjbGllbnQxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
  167. MIIBCgKCAQEAtuQFiqvdjd8WLxP0FgPDyDEJ1/uJ+Aoj6QllNV7svWxwW+kiJ3X6
  168. HUVNWhhCsNfly4pGW4erF4fZzmesElGx1PoWgQCWZKsa/N08bznelWgdmkyi85xE
  169. OkTj6e/cTWHFSOBURNJaXkGHZ0ROSh7qu0Ld+eqNo3k9W+NqZaqYvs2K7MLWeYl7
  170. Qie8Ctuq5Qaz/jm0XwR2PFBROVQSaCPCukancPQ21ftqHPhAbjxoxvvN5QP4ZdRf
  171. XlH/LDLhlFnJzPZdHnVy9xisSPPRfFApJiwyfjRYdtslpJOcNgP6oPlpX/dybbhO
  172. c9FEUgj/Q90Je8EfioBYFYsqVD6/dFv9SwIDAQABo3EwbzAOBgNVHQ8BAf8EBAMC
  173. A7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBRUh5Xo
  174. Gzjh6iReaPSOgGatqOw9bDAfBgNVHSMEGDAWgBTaCYSLw2UKxH/1UG1rrl4DZ7dp
  175. uTANBgkqhkiG9w0BAQsFAAOCAgEAyAK7cOTWqjyLgFM0kyyx1fNPvm2GwKep3MuU
  176. OrSnLuWjoxzb7WcbKNVMlnvnmSUAWuErxsY0PUJNfcuqWiGmEp4d/SWfWPigG6DC
  177. sDej35BlSfX8FCufYrfC74VNk4yBS2LVYmIqcpqUrfay0I2oZA8+ToLEpdUvEv2I
  178. l59eOhJO2jsC3JbOyZZmK2Kv7d94fR+1tg2Rq1Wbnmc9AZKq7KDReAlIJh4u2KHb
  179. BbtF79idusMwZyP777tqSQ4THBMa+VAEc2UrzdZqTIAwqlKQOvO2fRz2P+ARR+Tz
  180. MYJMdCdmPZ9qAc8U1OcFBG6qDDltO8wf/Nu/PsSI5LGCIhIuPPIuKfm0rRfTqCG7
  181. QPQPWjRoXtGGhwjdIuWbX9fIB+c+NpAEKHgLtV+Rxj8s5IVxqG9a5TtU9VkfVXJz
  182. J20naoz/G+vDsVINpd3kH0ziNvdrKfGRM5UgtnUOPCXB22fVmkIsMH2knI10CKK+
  183. offI56NTkLRu00xvg98/wdukhkwIAxg6PQI/BHY5mdvoacEHHHdOhMq+GSAh7DDX
  184. G8+HdbABM1ExkPnZLat15q706ztiuUpQv1C2DI8YviUVkMqCslj4cD4F8EFPo4kr
  185. kvme0Cuc9Qlf7N5rjdV3cjwavhFx44dyXj9aesft2Q1okPiIqbGNpcjHcIRlj4Au
  186. MU3Bo0A=
  187. -----END CERTIFICATE-----`
  188. client1Key = `-----BEGIN RSA PRIVATE KEY-----
  189. MIIEpAIBAAKCAQEAtuQFiqvdjd8WLxP0FgPDyDEJ1/uJ+Aoj6QllNV7svWxwW+ki
  190. J3X6HUVNWhhCsNfly4pGW4erF4fZzmesElGx1PoWgQCWZKsa/N08bznelWgdmkyi
  191. 85xEOkTj6e/cTWHFSOBURNJaXkGHZ0ROSh7qu0Ld+eqNo3k9W+NqZaqYvs2K7MLW
  192. eYl7Qie8Ctuq5Qaz/jm0XwR2PFBROVQSaCPCukancPQ21ftqHPhAbjxoxvvN5QP4
  193. ZdRfXlH/LDLhlFnJzPZdHnVy9xisSPPRfFApJiwyfjRYdtslpJOcNgP6oPlpX/dy
  194. bbhOc9FEUgj/Q90Je8EfioBYFYsqVD6/dFv9SwIDAQABAoIBAFjSHK7gENVZxphO
  195. hHg8k9ShnDo8eyDvK8l9Op3U3/yOsXKxolivvyx//7UFmz3vXDahjNHe7YScAXdw
  196. eezbqBXa7xrvghqZzp2HhFYwMJ0210mcdncBKVFzK4ztZHxgQ0PFTqet0R19jZjl
  197. X3A325/eNZeuBeOied4qb/24AD6JGc6A0J55f5/QUQtdwYwrL15iC/KZXDL90PPJ
  198. CFJyrSzcXvOMEvOfXIFxhDVKRCppyIYXG7c80gtNC37I6rxxMNQ4mxjwUI2IVhxL
  199. j+nZDu0JgRZ4NaGjOq2e79QxUVm/GG3z25XgmBFBrXkEVV+sCZE1VDyj6kQfv9FU
  200. NhOrwGECgYEAzq47r/HwXifuGYBV/mvInFw3BNLrKry+iUZrJ4ms4g+LfOi0BAgf
  201. sXsWXulpBo2YgYjFdO8G66f69GlB4B7iLscpABXbRtpDZEnchQpaF36/+4g3i8gB
  202. Z29XHNDB8+7t4wbXvlSnLv1tZWey2fS4hPosc2YlvS87DMmnJMJqhs8CgYEA4oiB
  203. LGQP6VNdX0Uigmh5fL1g1k95eC8GP1ylczCcIwsb2OkAq0MT7SHRXOlg3leEq4+g
  204. mCHk1NdjkSYxDL2ZeTKTS/gy4p1jlcDa6Ilwi4pVvatNvu4o80EYWxRNNb1mAn67
  205. T8TN9lzc6mEi+LepQM3nYJ3F+ZWTKgxH8uoJwMUCgYEArpumE1vbjUBAuEyi2eGn
  206. RunlFW83fBCfDAxw5KM8anNlja5uvuU6GU/6s06QCxg+2lh5MPPrLdXpfukZ3UVa
  207. Itjg+5B7gx1MSALaiY8YU7cibFdFThM3lHIM72wyH2ogkWcrh0GvSFSUQlJcWCSW
  208. asmMGiYXBgBL697FFZomMyMCgYEAkAnp0JcDQwHd4gDsk2zoqnckBsDb5J5J46n+
  209. DYNAFEww9bgZ08u/9MzG+cPu8xFE621U2MbcYLVfuuBE2ewIlPaij/COMmeO9Z59
  210. 0tPpOuDH6eTtd1SptxqR6P+8pEn8feOlKHBj4Z1kXqdK/EiTlwAVeep4Al2oCFls
  211. ujkz4F0CgYAe8vHnVFHlWi16zAqZx4ZZZhNuqPtgFkvPg9LfyNTA4dz7F9xgtUaY
  212. nXBPyCe/8NtgBfT79HkPiG3TM0xRZY9UZgsJKFtqAu5u4ManuWDnsZI9RK2QTLHe
  213. yEbH5r3Dg3n9k/3GbjXFIWdU9UaYsdnSKHHtMw9ZODc14LaAogEQug==
  214. -----END RSA PRIVATE KEY-----`
  215. // client 2 crt is revoked
  216. client2Crt = `-----BEGIN CERTIFICATE-----
  217. MIIEITCCAgmgAwIBAgIRAM5p4duNjikSPxYGaqBm5FEwDQYJKoZIhvcNAQELBQAw
  218. EzERMA8GA1UEAxMIQ2VydEF1dGgwHhcNMjQwMTEwMTgxMjUyWhcNMzQwMTEwMTgy
  219. MTUzWjASMRAwDgYDVQQDEwdjbGllbnQyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
  220. MIIBCgKCAQEApNYpNZVmXZtAObpRRIuP2o/7z04H2E161vKZvJ3LSLlUTImVjm/b
  221. Qe6DTNCUVLnzQuanmUlu2rUnN3lDSfYoBcJWbvC3y1OCPRkCjDV6KiYMA9TPkZua
  222. eq6y3+bFFfEmyumsVEe0bSuzNHXCOIBT7PqYMdovECcwBh/RZCA5mqO5omEKh4LQ
  223. cr6+sVVkvD3nsyx0Alz/kTLFqc0mVflmpJq+0BpdetHRg4n5vy/I/08jZ81PQAmT
  224. A0kyl0Jh132JBGFdA8eyugPPP8n5edU4f3HXV/nR7XLwBrpSt8KgEg8cwfAu4Ic0
  225. 6tGzB0CH8lSGtU0tH2/cOlDuguDD7VvokQIDAQABo3EwbzAOBgNVHQ8BAf8EBAMC
  226. A7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBR5mf0f
  227. Zjf8ZCGXqU2+45th7VkkLDAfBgNVHSMEGDAWgBTaCYSLw2UKxH/1UG1rrl4DZ7dp
  228. uTANBgkqhkiG9w0BAQsFAAOCAgEARhFxNAouwbpEfN1M90+ao5rwyxEewerSoCCz
  229. PQzeUZ66MA/FkS/tFUGgGGG+wERN+WLbe1cN6q/XFr0FSMLuUxLXDNV02oUL/FnY
  230. xcyNLaZUZ0pP7sA+Hmx2AdTA6baIwQbyIY9RLAaz6hzo1YbI8yeis645F1bxgL2D
  231. EP5kXa3Obv0tqWByMZtrmJPv3p0W5GJKXVDn51GR/E5KI7pliZX2e0LmMX9mxfPB
  232. 4sXFUggMHXxWMMSAmXPVsxC2KX6gMnajO7JUraTwuGm+6V371FzEX+UKXHI+xSvO
  233. 78TseTIYsBGLjeiA8UjkKlD3T9qsQm2mb2PlKyqjvIm4i2ilM0E2w4JZmd45b925
  234. 7q/QLV3NZ/zZMi6AMyULu28DWKfAx3RLKwnHWSFcR4lVkxQrbDhEUMhAhLAX+2+e
  235. qc7qZm3dTabi7ZJiiOvYK/yNgFHa/XtZp5uKPB5tigPIa+34hbZF7s2/ty5X3O1N
  236. f5Ardz7KNsxJjZIt6HvB28E/PPOvBqCKJc1Y08J9JbZi8p6QS1uarGoR7l7rT1Hv
  237. /ZXkNTw2bw1VpcWdzDBLLVHYNnJmS14189LVk11PcJJpSmubwCqg+ZZULdgtVr3S
  238. ANas2dgMPVwXhnAalgkcc+lb2QqaEz06axfbRGBsgnyqR5/koKCg1Hr0+vThHSsR
  239. E0+r2+4=
  240. -----END CERTIFICATE-----`
  241. client2Key = `-----BEGIN RSA PRIVATE KEY-----
  242. MIIEowIBAAKCAQEApNYpNZVmXZtAObpRRIuP2o/7z04H2E161vKZvJ3LSLlUTImV
  243. jm/bQe6DTNCUVLnzQuanmUlu2rUnN3lDSfYoBcJWbvC3y1OCPRkCjDV6KiYMA9TP
  244. kZuaeq6y3+bFFfEmyumsVEe0bSuzNHXCOIBT7PqYMdovECcwBh/RZCA5mqO5omEK
  245. h4LQcr6+sVVkvD3nsyx0Alz/kTLFqc0mVflmpJq+0BpdetHRg4n5vy/I/08jZ81P
  246. QAmTA0kyl0Jh132JBGFdA8eyugPPP8n5edU4f3HXV/nR7XLwBrpSt8KgEg8cwfAu
  247. 4Ic06tGzB0CH8lSGtU0tH2/cOlDuguDD7VvokQIDAQABAoIBAQCMnEeg9uXQmdvq
  248. op4qi6bV+ZcDWvvkLwvHikFMnYpIaheYBpF2ZMKzdmO4xgCSWeFCQ4Hah8KxfHCM
  249. qLuWvw2bBBE5J8yQ/JaPyeLbec7RX41GQ2YhPoxDdP0PdErREdpWo4imiFhH/Ewt
  250. Rvq7ufRdpdLoS8dzzwnvX3r+H2MkHoC/QANW2AOuVoZK5qyCH5N8yEAAbWKaQaeL
  251. VBhAYEVKbAkWEtXw7bYXzxRR7WIM3f45v3ncRusDIG+Hf75ZjatoH0lF1gHQNofO
  252. qkCVZVzjkLFuzDic2KZqsNORglNs4J6t5Dahb9v3hnoK963YMnVSUjFvqQ+/RZZy
  253. VILFShilAoGBANucwZU61eJ0tLKBYEwmRY/K7Gu1MvvcYJIOoX8/BL3zNmNO0CLl
  254. NiABtNt9WOVwZxDsxJXdo1zvMtAegNqS6W11R1VAZbL6mQ/krScbLDE6JKA5DmA7
  255. 4nNi1gJOW1ziAfdBAfhe4cLbQOb94xkOK5xM1YpO0xgDJLwrZbehDMmPAoGBAMAl
  256. /owPDAvcXz7JFynT0ieYVc64MSFiwGYJcsmxSAnbEgQ+TR5FtkHYe91OSqauZcCd
  257. aoKXQNyrYKIhyounRPFTdYQrlx6KtEs7LU9wOxuphhpJtGjRnhmA7IqvX703wNvu
  258. khrEavn86G5boH8R80371SrN0Rh9UeAlQGuNBdvfAoGAEAmokW9Ug08miwqrr6Pz
  259. 3IZjMZJwALidTM1IufQuMnj6ddIhnQrEIx48yPKkdUz6GeBQkuk2rujA+zXfDxc/
  260. eMDhzrX/N0zZtLFse7ieR5IJbrH7/MciyG5lVpHGVkgjAJ18uVikgAhm+vd7iC7i
  261. vG1YAtuyysQgAKXircBTIL0CgYAHeTLWVbt9NpwJwB6DhPaWjalAug9HIiUjktiB
  262. GcEYiQnBWn77X3DATOA8clAa/Yt9m2HKJIHkU1IV3ESZe+8Fh955PozJJlHu3yVb
  263. Ap157PUHTriSnxyMF2Sb3EhX/rQkmbnbCqqygHC14iBy8MrKzLG00X6BelZV5n0D
  264. 8d85dwKBgGWY2nsaemPH/TiTVF6kW1IKSQoIyJChkngc+Xj/2aCCkkmAEn8eqncl
  265. RKjnkiEZeG4+G91Xu7+HmcBLwV86k5I+tXK9O1Okomr6Zry8oqVcxU5TB6VRS+rA
  266. ubwF00Drdvk2+kDZfxIM137nBiy7wgCJi2Ksm5ihN3dUF6Q0oNPl
  267. -----END RSA PRIVATE KEY-----`
  268. )
  269. // MockOsFs mockable OsFs
  270. type MockOsFs struct {
  271. vfs.Fs
  272. err error
  273. isAtomicUploadSupported bool
  274. reader *pipeat.PipeReaderAt
  275. }
  276. // Name returns the name for the Fs implementation
  277. func (fs *MockOsFs) Name() string {
  278. return "mockOsFs"
  279. }
  280. // Open returns nil
  281. func (fs *MockOsFs) Open(name string, offset int64) (vfs.File, vfs.PipeReader, func(), error) {
  282. if fs.reader != nil {
  283. return nil, vfs.NewPipeReader(fs.reader), nil, nil
  284. }
  285. return fs.Fs.Open(name, offset)
  286. }
  287. // IsUploadResumeSupported returns true if resuming uploads is supported
  288. func (*MockOsFs) IsUploadResumeSupported() bool {
  289. return false
  290. }
  291. // IsAtomicUploadSupported returns true if atomic upload is supported
  292. func (fs *MockOsFs) IsAtomicUploadSupported() bool {
  293. return fs.isAtomicUploadSupported
  294. }
  295. // Remove removes the named file or (empty) directory.
  296. func (fs *MockOsFs) Remove(name string, _ bool) error {
  297. if fs.err != nil {
  298. return fs.err
  299. }
  300. return os.Remove(name)
  301. }
  302. // Rename renames (moves) source to target
  303. func (fs *MockOsFs) Rename(source, target string, _ int) (int, int64, error) {
  304. err := os.Rename(source, target)
  305. return -1, -1, err
  306. }
  307. // GetMimeType returns the content type
  308. func (fs *MockOsFs) GetMimeType(_ string) (string, error) {
  309. if fs.err != nil {
  310. return "", fs.err
  311. }
  312. return "application/custom-mime", nil
  313. }
  314. func newMockOsFs(atomicUpload bool, connectionID, rootDir string, reader *pipeat.PipeReaderAt, err error) vfs.Fs {
  315. return &MockOsFs{
  316. Fs: vfs.NewOsFs(connectionID, rootDir, "", nil),
  317. isAtomicUploadSupported: atomicUpload,
  318. reader: reader,
  319. err: err,
  320. }
  321. }
  322. func TestUserInvalidParams(t *testing.T) {
  323. u := &dataprovider.User{
  324. BaseUser: sdk.BaseUser{
  325. Username: "username",
  326. HomeDir: "invalid",
  327. },
  328. }
  329. c := &Configuration{
  330. Bindings: []Binding{
  331. {
  332. Port: 9000,
  333. },
  334. },
  335. }
  336. server := webDavServer{
  337. config: c,
  338. binding: c.Bindings[0],
  339. }
  340. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", u.Username), nil)
  341. assert.NoError(t, err)
  342. _, err = server.validateUser(u, req, dataprovider.LoginMethodPassword)
  343. if assert.Error(t, err) {
  344. assert.EqualError(t, err, fmt.Sprintf("cannot login user with invalid home dir: %q", u.HomeDir))
  345. }
  346. req.TLS = &tls.ConnectionState{}
  347. writeLog(req, http.StatusOK, nil)
  348. }
  349. func TestAllowedProxyUnixDomainSocket(t *testing.T) {
  350. b := Binding{
  351. Address: filepath.Join(os.TempDir(), "sock"),
  352. ProxyAllowed: []string{"127.0.0.1", "127.0.1.1"},
  353. }
  354. err := b.parseAllowedProxy()
  355. assert.NoError(t, err)
  356. if assert.Len(t, b.allowHeadersFrom, 1) {
  357. assert.True(t, b.allowHeadersFrom[0](nil))
  358. }
  359. }
  360. func TestProxyListenerWrapper(t *testing.T) {
  361. b := Binding{
  362. ProxyMode: 0,
  363. }
  364. require.Nil(t, b.listenerWrapper())
  365. b.ProxyMode = 1
  366. require.NotNil(t, b.listenerWrapper())
  367. }
  368. func TestRemoteAddress(t *testing.T) {
  369. remoteAddr1 := "100.100.100.100"
  370. remoteAddr2 := "172.172.172.172"
  371. c := &Configuration{
  372. Bindings: []Binding{
  373. {
  374. Port: 9000,
  375. ProxyAllowed: []string{remoteAddr2, "10.8.0.0/30"},
  376. },
  377. },
  378. }
  379. server := webDavServer{
  380. config: c,
  381. binding: c.Bindings[0],
  382. }
  383. err := server.binding.parseAllowedProxy()
  384. assert.NoError(t, err)
  385. req, err := http.NewRequest(http.MethodGet, "/", nil)
  386. assert.NoError(t, err)
  387. assert.Empty(t, req.RemoteAddr)
  388. trueClientIP := "True-Client-IP"
  389. cfConnectingIP := "CF-Connecting-IP"
  390. xff := "X-Forwarded-For"
  391. xRealIP := "X-Real-IP"
  392. req.Header.Set(trueClientIP, remoteAddr1)
  393. ip := util.GetRealIP(req, trueClientIP, 0)
  394. assert.Equal(t, remoteAddr1, ip)
  395. ip = util.GetRealIP(req, trueClientIP, 2)
  396. assert.Empty(t, ip)
  397. req.Header.Del(trueClientIP)
  398. req.Header.Set(cfConnectingIP, remoteAddr1)
  399. ip = util.GetRealIP(req, cfConnectingIP, 0)
  400. assert.Equal(t, remoteAddr1, ip)
  401. req.Header.Del(cfConnectingIP)
  402. req.Header.Set(xff, remoteAddr1)
  403. ip = util.GetRealIP(req, xff, 0)
  404. assert.Equal(t, remoteAddr1, ip)
  405. // this will be ignored, remoteAddr1 is not allowed to se this header
  406. req.Header.Set(xff, remoteAddr2)
  407. req.RemoteAddr = remoteAddr1
  408. ip = server.checkRemoteAddress(req)
  409. assert.Equal(t, remoteAddr1, ip)
  410. req.RemoteAddr = ""
  411. ip = server.checkRemoteAddress(req)
  412. assert.Empty(t, ip)
  413. req.Header.Set(xff, fmt.Sprintf("%v , %v", remoteAddr2, remoteAddr1))
  414. ip = util.GetRealIP(req, xff, 1)
  415. assert.Equal(t, remoteAddr2, ip)
  416. req.RemoteAddr = remoteAddr2
  417. req.Header.Set(xff, fmt.Sprintf("%v,%v", "12.34.56.78", "172.16.2.4"))
  418. server.binding.ClientIPHeaderDepth = 1
  419. server.binding.ClientIPProxyHeader = xff
  420. ip = server.checkRemoteAddress(req)
  421. assert.Equal(t, "12.34.56.78", ip)
  422. assert.Equal(t, ip, req.RemoteAddr)
  423. req.RemoteAddr = remoteAddr2
  424. req.Header.Set(xff, fmt.Sprintf("%v,%v", "12.34.56.79", "172.16.2.5"))
  425. server.binding.ClientIPHeaderDepth = 0
  426. ip = server.checkRemoteAddress(req)
  427. assert.Equal(t, "172.16.2.5", ip)
  428. assert.Equal(t, ip, req.RemoteAddr)
  429. req.RemoteAddr = "10.8.0.2"
  430. req.Header.Set(xff, remoteAddr1)
  431. ip = server.checkRemoteAddress(req)
  432. assert.Equal(t, remoteAddr1, ip)
  433. assert.Equal(t, ip, req.RemoteAddr)
  434. req.RemoteAddr = "10.8.0.3"
  435. req.Header.Set(xff, "not an ip")
  436. ip = server.checkRemoteAddress(req)
  437. assert.Equal(t, "10.8.0.3", ip)
  438. assert.Equal(t, ip, req.RemoteAddr)
  439. req.Header.Del(xff)
  440. req.RemoteAddr = ""
  441. req.Header.Set(xRealIP, remoteAddr1)
  442. ip = util.GetRealIP(req, "x-real-ip", 0)
  443. assert.Equal(t, remoteAddr1, ip)
  444. req.RemoteAddr = ""
  445. }
  446. func TestConnWithNilRequest(t *testing.T) {
  447. c := &Connection{}
  448. assert.Empty(t, c.GetClientVersion())
  449. assert.Empty(t, c.GetCommand())
  450. assert.Empty(t, c.GetRemoteAddress())
  451. assert.True(t, c.getModificationTime().IsZero())
  452. }
  453. func TestResolvePathErrors(t *testing.T) {
  454. ctx := context.Background()
  455. user := dataprovider.User{
  456. BaseUser: sdk.BaseUser{
  457. HomeDir: "invalid",
  458. },
  459. }
  460. user.Permissions = make(map[string][]string)
  461. user.Permissions["/"] = []string{dataprovider.PermAny}
  462. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  463. connection := &Connection{
  464. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  465. }
  466. err := connection.Mkdir(ctx, "", os.ModePerm)
  467. if assert.Error(t, err) {
  468. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  469. }
  470. err = connection.Rename(ctx, "oldName", "newName")
  471. if assert.Error(t, err) {
  472. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  473. }
  474. _, err = connection.Stat(ctx, "name")
  475. if assert.Error(t, err) {
  476. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  477. }
  478. err = connection.RemoveAll(ctx, "")
  479. if assert.Error(t, err) {
  480. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  481. }
  482. _, err = connection.OpenFile(ctx, "", 0, os.ModePerm)
  483. if assert.Error(t, err) {
  484. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  485. }
  486. if runtime.GOOS != "windows" {
  487. user.HomeDir = filepath.Clean(os.TempDir())
  488. connection.User = user
  489. fs := vfs.NewOsFs("connID", connection.User.HomeDir, "", nil)
  490. subDir := "sub"
  491. testTxtFile := "file.txt"
  492. err = os.MkdirAll(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  493. assert.NoError(t, err)
  494. err = os.WriteFile(filepath.Join(os.TempDir(), subDir, subDir, testTxtFile), []byte("content"), os.ModePerm)
  495. assert.NoError(t, err)
  496. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), 0001)
  497. assert.NoError(t, err)
  498. err = os.WriteFile(filepath.Join(os.TempDir(), testTxtFile), []byte("test content"), os.ModePerm)
  499. assert.NoError(t, err)
  500. err = connection.Rename(ctx, testTxtFile, path.Join(subDir, subDir, testTxtFile))
  501. if assert.Error(t, err) {
  502. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  503. }
  504. _, err = connection.putFile(fs, filepath.Join(connection.User.HomeDir, subDir, subDir, testTxtFile),
  505. path.Join(subDir, subDir, testTxtFile))
  506. if assert.Error(t, err) {
  507. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  508. }
  509. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  510. assert.NoError(t, err)
  511. err = os.RemoveAll(filepath.Join(os.TempDir(), subDir))
  512. assert.NoError(t, err)
  513. err = os.Remove(filepath.Join(os.TempDir(), testTxtFile))
  514. assert.NoError(t, err)
  515. }
  516. }
  517. func TestFileAccessErrors(t *testing.T) {
  518. ctx := context.Background()
  519. user := dataprovider.User{
  520. BaseUser: sdk.BaseUser{
  521. HomeDir: filepath.Clean(os.TempDir()),
  522. },
  523. }
  524. user.Permissions = make(map[string][]string)
  525. user.Permissions["/"] = []string{dataprovider.PermAny}
  526. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  527. connection := &Connection{
  528. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  529. }
  530. missingPath := "missing path"
  531. fsMissingPath := filepath.Join(user.HomeDir, missingPath)
  532. err := connection.RemoveAll(ctx, missingPath)
  533. assert.ErrorIs(t, err, os.ErrNotExist)
  534. davFile, err := connection.getFile(fs, fsMissingPath, missingPath)
  535. assert.NoError(t, err)
  536. buf := make([]byte, 64)
  537. _, err = davFile.Read(buf)
  538. assert.ErrorIs(t, err, os.ErrNotExist)
  539. err = davFile.Close()
  540. assert.ErrorIs(t, err, os.ErrNotExist)
  541. p := filepath.Join(user.HomeDir, "adir", missingPath)
  542. _, err = connection.handleUploadToNewFile(fs, p, p, path.Join("adir", missingPath))
  543. assert.ErrorIs(t, err, os.ErrNotExist)
  544. _, err = connection.handleUploadToExistingFile(fs, p, "_"+p, 0, path.Join("adir", missingPath))
  545. if assert.Error(t, err) {
  546. assert.ErrorIs(t, err, os.ErrNotExist)
  547. }
  548. fs = newMockOsFs(false, fs.ConnectionID(), user.HomeDir, nil, nil)
  549. _, err = connection.handleUploadToExistingFile(fs, p, p, 0, path.Join("adir", missingPath))
  550. assert.ErrorIs(t, err, os.ErrNotExist)
  551. f, err := os.CreateTemp("", "temp")
  552. assert.NoError(t, err)
  553. err = f.Close()
  554. assert.NoError(t, err)
  555. davFile, err = connection.handleUploadToExistingFile(fs, f.Name(), f.Name(), 123, f.Name())
  556. if assert.NoError(t, err) {
  557. transfer := davFile.(*webDavFile)
  558. transfers := connection.GetTransfers()
  559. if assert.Equal(t, 1, len(transfers)) {
  560. assert.Equal(t, transfers[0].ID, transfer.GetID())
  561. assert.Equal(t, int64(123), transfer.InitialSize)
  562. err = transfer.Close()
  563. assert.NoError(t, err)
  564. assert.Equal(t, 0, len(connection.GetTransfers()))
  565. }
  566. // test PROPPATCH date parsing error
  567. pstats, err := transfer.Patch([]webdav.Proppatch{
  568. {
  569. Props: []webdav.Property{
  570. {
  571. XMLName: xml.Name{
  572. Space: "DAV",
  573. Local: "getlastmodified",
  574. },
  575. InnerXML: []byte(`Wid, 04 Nov 2020 13:25:51 GMT`),
  576. },
  577. },
  578. },
  579. })
  580. assert.NoError(t, err)
  581. for _, pstat := range pstats {
  582. assert.Equal(t, http.StatusForbidden, pstat.Status)
  583. }
  584. err = os.Remove(f.Name())
  585. assert.NoError(t, err)
  586. // the file is deleted PROPPATCH should fail
  587. pstats, err = transfer.Patch([]webdav.Proppatch{
  588. {
  589. Props: []webdav.Property{
  590. {
  591. XMLName: xml.Name{
  592. Space: "DAV",
  593. Local: "getlastmodified",
  594. },
  595. InnerXML: []byte(`Wed, 04 Nov 2020 13:25:51 GMT`),
  596. },
  597. },
  598. },
  599. })
  600. assert.NoError(t, err)
  601. for _, pstat := range pstats {
  602. assert.Equal(t, http.StatusForbidden, pstat.Status)
  603. }
  604. }
  605. }
  606. func TestCheckRequestMethodWithPrefix(t *testing.T) {
  607. user := dataprovider.User{
  608. BaseUser: sdk.BaseUser{
  609. HomeDir: filepath.Clean(os.TempDir()),
  610. Permissions: map[string][]string{
  611. "/": {dataprovider.PermAny},
  612. },
  613. },
  614. }
  615. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  616. connection := &Connection{
  617. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  618. }
  619. server := webDavServer{
  620. binding: Binding{
  621. Prefix: "/dav",
  622. },
  623. }
  624. req, err := http.NewRequest(http.MethodGet, "/../dav", nil)
  625. require.NoError(t, err)
  626. server.checkRequestMethod(context.Background(), req, connection)
  627. require.Equal(t, "PROPFIND", req.Method)
  628. require.Equal(t, "1", req.Header.Get("Depth"))
  629. }
  630. func TestContentType(t *testing.T) {
  631. user := dataprovider.User{
  632. BaseUser: sdk.BaseUser{
  633. HomeDir: filepath.Clean(os.TempDir()),
  634. },
  635. }
  636. user.Permissions = make(map[string][]string)
  637. user.Permissions["/"] = []string{dataprovider.PermAny}
  638. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  639. connection := &Connection{
  640. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  641. }
  642. testFilePath := filepath.Join(user.HomeDir, testFile)
  643. ctx := context.Background()
  644. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".unknown",
  645. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  646. fs = newMockOsFs(false, fs.ConnectionID(), user.GetHomeDir(), nil, nil)
  647. err := os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  648. assert.NoError(t, err)
  649. davFile := newWebDavFile(baseTransfer, nil, nil)
  650. davFile.Fs = fs
  651. fi, err := davFile.Stat()
  652. if assert.NoError(t, err) {
  653. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  654. assert.NoError(t, err)
  655. assert.Equal(t, "application/custom-mime", ctype)
  656. }
  657. _, err = davFile.Readdir(-1)
  658. assert.ErrorIs(t, err, webdav.ErrNotImplemented)
  659. _, err = davFile.ReadDir()
  660. assert.Error(t, err)
  661. err = davFile.Close()
  662. assert.NoError(t, err)
  663. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".unknown1",
  664. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  665. davFile = newWebDavFile(baseTransfer, nil, nil)
  666. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, "", nil)
  667. fi, err = davFile.Stat()
  668. if assert.NoError(t, err) {
  669. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  670. assert.NoError(t, err)
  671. assert.Equal(t, "text/plain; charset=utf-8", ctype)
  672. }
  673. err = davFile.Close()
  674. assert.NoError(t, err)
  675. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  676. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  677. davFile = newWebDavFile(baseTransfer, nil, nil)
  678. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, "", nil)
  679. fi, err = davFile.Stat()
  680. if assert.NoError(t, err) {
  681. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  682. assert.NoError(t, err)
  683. assert.Equal(t, "application/octet-stream", ctype)
  684. }
  685. err = davFile.Close()
  686. assert.NoError(t, err)
  687. for i := 0; i < 2; i++ {
  688. // the second time the cache will be used
  689. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".custom",
  690. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  691. davFile = newWebDavFile(baseTransfer, nil, nil)
  692. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, "", nil)
  693. fi, err = davFile.Stat()
  694. if assert.NoError(t, err) {
  695. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  696. assert.NoError(t, err)
  697. assert.Equal(t, "text/plain; charset=utf-8", ctype)
  698. }
  699. err = davFile.Close()
  700. assert.NoError(t, err)
  701. }
  702. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".sftpgo",
  703. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  704. fs = newMockOsFs(false, fs.ConnectionID(), user.GetHomeDir(), nil, os.ErrInvalid)
  705. davFile = newWebDavFile(baseTransfer, nil, nil)
  706. davFile.Fs = fs
  707. fi, err = davFile.Stat()
  708. if assert.NoError(t, err) {
  709. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  710. assert.NoError(t, err)
  711. assert.Equal(t, "application/sftpgo", ctype)
  712. }
  713. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".unknown2",
  714. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  715. fs = newMockOsFs(false, fs.ConnectionID(), user.GetHomeDir(), nil, os.ErrInvalid)
  716. davFile = newWebDavFile(baseTransfer, nil, nil)
  717. davFile.Fs = fs
  718. fi, err = davFile.Stat()
  719. if assert.NoError(t, err) {
  720. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  721. assert.EqualError(t, err, webdav.ErrNotImplemented.Error(), "unexpected content type %q", ctype)
  722. }
  723. cache := mimeCache{
  724. maxSize: 10,
  725. mimeTypes: map[string]string{},
  726. }
  727. cache.addMimeToCache("", "")
  728. cache.RLock()
  729. assert.Len(t, cache.mimeTypes, 0)
  730. cache.RUnlock()
  731. err = os.Remove(testFilePath)
  732. assert.NoError(t, err)
  733. }
  734. func TestTransferReadWriteErrors(t *testing.T) {
  735. user := dataprovider.User{
  736. BaseUser: sdk.BaseUser{
  737. HomeDir: filepath.Clean(os.TempDir()),
  738. },
  739. }
  740. user.Permissions = make(map[string][]string)
  741. user.Permissions["/"] = []string{dataprovider.PermAny}
  742. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  743. connection := &Connection{
  744. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  745. }
  746. testFilePath := filepath.Join(user.HomeDir, testFile)
  747. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  748. common.TransferUpload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  749. davFile := newWebDavFile(baseTransfer, nil, nil)
  750. p := make([]byte, 1)
  751. _, err := davFile.Read(p)
  752. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  753. r, w, err := pipeat.Pipe()
  754. assert.NoError(t, err)
  755. davFile = newWebDavFile(baseTransfer, nil, r)
  756. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  757. davFile = newWebDavFile(baseTransfer, vfs.NewPipeWriter(w), nil)
  758. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  759. err = r.Close()
  760. assert.NoError(t, err)
  761. err = w.Close()
  762. assert.NoError(t, err)
  763. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  764. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  765. davFile = newWebDavFile(baseTransfer, nil, nil)
  766. _, err = davFile.Read(p)
  767. assert.True(t, fs.IsNotExist(err))
  768. _, err = davFile.Stat()
  769. assert.True(t, fs.IsNotExist(err))
  770. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  771. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  772. err = os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  773. assert.NoError(t, err)
  774. f, err := os.Open(testFilePath)
  775. if assert.NoError(t, err) {
  776. err = f.Close()
  777. assert.NoError(t, err)
  778. }
  779. davFile = newWebDavFile(baseTransfer, nil, nil)
  780. davFile.reader = f
  781. err = davFile.Close()
  782. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  783. err = davFile.Close()
  784. assert.EqualError(t, err, common.ErrTransferClosed.Error())
  785. _, err = davFile.Read(p)
  786. assert.Error(t, err)
  787. info, err := davFile.Stat()
  788. if assert.NoError(t, err) {
  789. assert.Equal(t, int64(0), info.Size())
  790. }
  791. r, w, err = pipeat.Pipe()
  792. assert.NoError(t, err)
  793. mockFs := newMockOsFs(false, fs.ConnectionID(), user.HomeDir, r, nil)
  794. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  795. common.TransferDownload, 0, 0, 0, 0, false, mockFs, dataprovider.TransferQuota{})
  796. davFile = newWebDavFile(baseTransfer, nil, nil)
  797. writeContent := []byte("content\r\n")
  798. go func() {
  799. n, err := w.Write(writeContent)
  800. assert.NoError(t, err)
  801. assert.Equal(t, len(writeContent), n)
  802. err = w.Close()
  803. assert.NoError(t, err)
  804. }()
  805. p = make([]byte, 64)
  806. n, err := davFile.Read(p)
  807. assert.EqualError(t, err, io.EOF.Error())
  808. assert.Equal(t, len(writeContent), n)
  809. err = davFile.Close()
  810. assert.NoError(t, err)
  811. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  812. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  813. davFile = newWebDavFile(baseTransfer, nil, nil)
  814. davFile.writer = f
  815. err = davFile.Close()
  816. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  817. err = os.Remove(testFilePath)
  818. assert.NoError(t, err)
  819. }
  820. func TestTransferSeek(t *testing.T) {
  821. user := dataprovider.User{
  822. BaseUser: sdk.BaseUser{
  823. HomeDir: filepath.Clean(os.TempDir()),
  824. },
  825. }
  826. user.Permissions = make(map[string][]string)
  827. user.Permissions["/"] = []string{dataprovider.PermAny}
  828. fs := newMockOsFs(true, "connID", user.HomeDir, nil, nil)
  829. connection := &Connection{
  830. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  831. }
  832. testFilePath := filepath.Join(user.HomeDir, testFile)
  833. testFileContents := []byte("content")
  834. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  835. common.TransferUpload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  836. davFile := newWebDavFile(baseTransfer, nil, nil)
  837. _, err := davFile.Seek(0, io.SeekStart)
  838. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  839. err = davFile.Close()
  840. assert.NoError(t, err)
  841. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  842. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  843. davFile = newWebDavFile(baseTransfer, nil, nil)
  844. _, err = davFile.Seek(0, io.SeekCurrent)
  845. assert.True(t, fs.IsNotExist(err))
  846. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  847. err = os.WriteFile(testFilePath, testFileContents, os.ModePerm)
  848. assert.NoError(t, err)
  849. f, err := os.Open(testFilePath)
  850. if assert.NoError(t, err) {
  851. err = f.Close()
  852. assert.NoError(t, err)
  853. }
  854. baseTransfer = common.NewBaseTransfer(f, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  855. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  856. davFile = newWebDavFile(baseTransfer, nil, nil)
  857. _, err = davFile.Seek(0, io.SeekStart)
  858. assert.Error(t, err)
  859. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  860. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  861. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  862. davFile = newWebDavFile(baseTransfer, nil, nil)
  863. res, err := davFile.Seek(0, io.SeekStart)
  864. assert.NoError(t, err)
  865. assert.Equal(t, int64(0), res)
  866. err = davFile.Close()
  867. assert.NoError(t, err)
  868. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  869. davFile = newWebDavFile(baseTransfer, nil, nil)
  870. res, err = davFile.Seek(0, io.SeekEnd)
  871. assert.NoError(t, err)
  872. assert.Equal(t, int64(len(testFileContents)), res)
  873. err = davFile.updateStatInfo()
  874. assert.NoError(t, err)
  875. err = davFile.Close()
  876. assert.NoError(t, err)
  877. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  878. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  879. davFile = newWebDavFile(baseTransfer, nil, nil)
  880. _, err = davFile.Seek(0, io.SeekEnd)
  881. assert.True(t, fs.IsNotExist(err))
  882. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  883. fs = vfs.NewOsFs(fs.ConnectionID(), user.GetHomeDir(), "", nil)
  884. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  885. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  886. davFile = newWebDavFile(baseTransfer, nil, nil)
  887. _, err = davFile.Seek(0, io.SeekEnd)
  888. assert.True(t, fs.IsNotExist(err))
  889. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  890. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  891. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  892. davFile = newWebDavFile(baseTransfer, nil, nil)
  893. davFile.reader = f
  894. r, _, err := pipeat.Pipe()
  895. assert.NoError(t, err)
  896. davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), r, nil)
  897. res, err = davFile.Seek(2, io.SeekStart)
  898. assert.NoError(t, err)
  899. assert.Equal(t, int64(2), res)
  900. err = davFile.Close()
  901. assert.NoError(t, err)
  902. r, _, err = pipeat.Pipe()
  903. assert.NoError(t, err)
  904. davFile = newWebDavFile(baseTransfer, nil, nil)
  905. davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), r, nil)
  906. res, err = davFile.Seek(2, io.SeekEnd)
  907. assert.NoError(t, err)
  908. assert.Equal(t, int64(5), res)
  909. err = davFile.Close()
  910. assert.NoError(t, err)
  911. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  912. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  913. davFile = newWebDavFile(baseTransfer, nil, nil)
  914. davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), nil, nil)
  915. res, err = davFile.Seek(2, io.SeekEnd)
  916. assert.True(t, fs.IsNotExist(err))
  917. assert.Equal(t, int64(0), res)
  918. assert.Len(t, common.Connections.GetStats(""), 0)
  919. err = os.Remove(testFilePath)
  920. assert.NoError(t, err)
  921. }
  922. func TestBasicUsersCache(t *testing.T) {
  923. username := "webdav_internal_test"
  924. password := "pwd"
  925. u := dataprovider.User{
  926. BaseUser: sdk.BaseUser{
  927. Username: username,
  928. Password: password,
  929. HomeDir: filepath.Join(os.TempDir(), username),
  930. Status: 1,
  931. ExpirationDate: 0,
  932. },
  933. }
  934. u.Permissions = make(map[string][]string)
  935. u.Permissions["/"] = []string{dataprovider.PermAny}
  936. err := dataprovider.AddUser(&u, "", "", "")
  937. assert.NoError(t, err)
  938. user, err := dataprovider.UserExists(u.Username, "")
  939. assert.NoError(t, err)
  940. c := &Configuration{
  941. Bindings: []Binding{
  942. {
  943. Port: 9000,
  944. },
  945. },
  946. Cache: Cache{
  947. Users: UsersCacheConfig{
  948. MaxSize: 50,
  949. ExpirationTime: 1,
  950. },
  951. },
  952. }
  953. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  954. server := webDavServer{
  955. config: c,
  956. binding: c.Bindings[0],
  957. }
  958. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user.Username), nil)
  959. assert.NoError(t, err)
  960. ipAddr := "127.0.0.1"
  961. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  962. assert.Error(t, err)
  963. now := time.Now()
  964. req.SetBasicAuth(username, password)
  965. _, isCached, _, loginMethod, err := server.authenticate(req, ipAddr)
  966. assert.NoError(t, err)
  967. assert.False(t, isCached)
  968. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  969. // now the user should be cached
  970. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  971. if assert.True(t, ok) {
  972. assert.False(t, cachedUser.IsExpired())
  973. assert.True(t, cachedUser.Expiration.After(now.Add(time.Duration(c.Cache.Users.ExpirationTime)*time.Minute)))
  974. // authenticate must return the cached user now
  975. authUser, isCached, _, _, err := server.authenticate(req, ipAddr)
  976. assert.NoError(t, err)
  977. assert.True(t, isCached)
  978. assert.Equal(t, cachedUser.User, authUser)
  979. }
  980. // a wrong password must fail
  981. req.SetBasicAuth(username, "wrong")
  982. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  983. assert.EqualError(t, err, dataprovider.ErrInvalidCredentials.Error())
  984. req.SetBasicAuth(username, password)
  985. // force cached user expiration
  986. cachedUser.Expiration = now
  987. dataprovider.CacheWebDAVUser(cachedUser)
  988. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  989. if assert.True(t, ok) {
  990. assert.True(t, cachedUser.IsExpired())
  991. }
  992. // now authenticate should get the user from the data provider and update the cache
  993. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  994. assert.NoError(t, err)
  995. assert.False(t, isCached)
  996. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  997. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  998. if assert.True(t, ok) {
  999. assert.False(t, cachedUser.IsExpired())
  1000. }
  1001. // cache is not invalidated after a user modification if the fs does not change
  1002. err = dataprovider.UpdateUser(&user, "", "", "")
  1003. assert.NoError(t, err)
  1004. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1005. assert.True(t, ok)
  1006. folderName := "testFolder"
  1007. f := &vfs.BaseVirtualFolder{
  1008. Name: folderName,
  1009. MappedPath: filepath.Join(os.TempDir(), "mapped"),
  1010. }
  1011. err = dataprovider.AddFolder(f, "", "", "")
  1012. assert.NoError(t, err)
  1013. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  1014. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1015. Name: folderName,
  1016. },
  1017. VirtualPath: "/vdir",
  1018. })
  1019. err = dataprovider.UpdateUser(&user, "", "", "")
  1020. assert.NoError(t, err)
  1021. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1022. assert.False(t, ok)
  1023. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1024. assert.NoError(t, err)
  1025. assert.False(t, isCached)
  1026. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1027. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1028. assert.True(t, ok)
  1029. // cache is invalidated after user deletion
  1030. err = dataprovider.DeleteUser(user.Username, "", "", "")
  1031. assert.NoError(t, err)
  1032. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1033. assert.False(t, ok)
  1034. err = dataprovider.DeleteFolder(folderName, "", "", "")
  1035. assert.NoError(t, err)
  1036. err = os.RemoveAll(u.GetHomeDir())
  1037. assert.NoError(t, err)
  1038. }
  1039. func TestCachedUserWithFolders(t *testing.T) {
  1040. username := "webdav_internal_folder_test"
  1041. password := "dav_pwd"
  1042. folderName := "test_folder"
  1043. u := dataprovider.User{
  1044. BaseUser: sdk.BaseUser{
  1045. Username: username,
  1046. Password: password,
  1047. HomeDir: filepath.Join(os.TempDir(), username),
  1048. Status: 1,
  1049. ExpirationDate: 0,
  1050. },
  1051. }
  1052. u.Permissions = make(map[string][]string)
  1053. u.Permissions["/"] = []string{dataprovider.PermAny}
  1054. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  1055. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1056. Name: folderName,
  1057. },
  1058. VirtualPath: "/vpath",
  1059. })
  1060. f := &vfs.BaseVirtualFolder{
  1061. Name: folderName,
  1062. MappedPath: filepath.Join(os.TempDir(), folderName),
  1063. }
  1064. err := dataprovider.AddFolder(f, "", "", "")
  1065. assert.NoError(t, err)
  1066. err = dataprovider.AddUser(&u, "", "", "")
  1067. assert.NoError(t, err)
  1068. user, err := dataprovider.UserExists(u.Username, "")
  1069. assert.NoError(t, err)
  1070. c := &Configuration{
  1071. Bindings: []Binding{
  1072. {
  1073. Port: 9000,
  1074. },
  1075. },
  1076. Cache: Cache{
  1077. Users: UsersCacheConfig{
  1078. MaxSize: 50,
  1079. ExpirationTime: 1,
  1080. },
  1081. },
  1082. }
  1083. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  1084. server := webDavServer{
  1085. config: c,
  1086. binding: c.Bindings[0],
  1087. }
  1088. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user.Username), nil)
  1089. assert.NoError(t, err)
  1090. ipAddr := "127.0.0.1"
  1091. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  1092. assert.Error(t, err)
  1093. now := time.Now()
  1094. req.SetBasicAuth(username, password)
  1095. _, isCached, _, loginMethod, err := server.authenticate(req, ipAddr)
  1096. assert.NoError(t, err)
  1097. assert.False(t, isCached)
  1098. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1099. // now the user should be cached
  1100. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  1101. if assert.True(t, ok) {
  1102. assert.False(t, cachedUser.IsExpired())
  1103. assert.True(t, cachedUser.Expiration.After(now.Add(time.Duration(c.Cache.Users.ExpirationTime)*time.Minute)))
  1104. // authenticate must return the cached user now
  1105. authUser, isCached, _, _, err := server.authenticate(req, ipAddr)
  1106. assert.NoError(t, err)
  1107. assert.True(t, isCached)
  1108. assert.Equal(t, cachedUser.User, authUser)
  1109. }
  1110. folder, err := dataprovider.GetFolderByName(folderName)
  1111. assert.NoError(t, err)
  1112. // updating a used folder should invalidate the cache only if the fs changed
  1113. err = dataprovider.UpdateFolder(&folder, folder.Users, folder.Groups, "", "", "")
  1114. assert.NoError(t, err)
  1115. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1116. assert.NoError(t, err)
  1117. assert.True(t, isCached)
  1118. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1119. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1120. if assert.True(t, ok) {
  1121. assert.False(t, cachedUser.IsExpired())
  1122. }
  1123. // changing the folder path should invalidate the cache
  1124. folder.MappedPath = filepath.Join(os.TempDir(), "anotherpath")
  1125. err = dataprovider.UpdateFolder(&folder, folder.Users, folder.Groups, "", "", "")
  1126. assert.NoError(t, err)
  1127. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1128. assert.NoError(t, err)
  1129. assert.False(t, isCached)
  1130. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1131. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1132. if assert.True(t, ok) {
  1133. assert.False(t, cachedUser.IsExpired())
  1134. }
  1135. err = dataprovider.DeleteFolder(folderName, "", "", "")
  1136. assert.NoError(t, err)
  1137. // removing a used folder should invalidate the cache
  1138. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1139. assert.NoError(t, err)
  1140. assert.False(t, isCached)
  1141. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1142. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1143. if assert.True(t, ok) {
  1144. assert.False(t, cachedUser.IsExpired())
  1145. }
  1146. err = dataprovider.DeleteUser(user.Username, "", "", "")
  1147. assert.NoError(t, err)
  1148. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1149. assert.False(t, ok)
  1150. err = os.RemoveAll(u.GetHomeDir())
  1151. assert.NoError(t, err)
  1152. err = os.RemoveAll(folder.MappedPath)
  1153. assert.NoError(t, err)
  1154. }
  1155. func TestUsersCacheSizeAndExpiration(t *testing.T) {
  1156. username := "webdav_internal_test"
  1157. password := "pwd"
  1158. u := dataprovider.User{
  1159. BaseUser: sdk.BaseUser{
  1160. HomeDir: filepath.Join(os.TempDir(), username),
  1161. Status: 1,
  1162. ExpirationDate: 0,
  1163. },
  1164. }
  1165. u.Username = username + "1"
  1166. u.Password = password + "1"
  1167. u.Permissions = make(map[string][]string)
  1168. u.Permissions["/"] = []string{dataprovider.PermAny}
  1169. err := dataprovider.AddUser(&u, "", "", "")
  1170. assert.NoError(t, err)
  1171. user1, err := dataprovider.UserExists(u.Username, "")
  1172. assert.NoError(t, err)
  1173. u.Username = username + "2"
  1174. u.Password = password + "2"
  1175. err = dataprovider.AddUser(&u, "", "", "")
  1176. assert.NoError(t, err)
  1177. user2, err := dataprovider.UserExists(u.Username, "")
  1178. assert.NoError(t, err)
  1179. u.Username = username + "3"
  1180. u.Password = password + "3"
  1181. err = dataprovider.AddUser(&u, "", "", "")
  1182. assert.NoError(t, err)
  1183. user3, err := dataprovider.UserExists(u.Username, "")
  1184. assert.NoError(t, err)
  1185. u.Username = username + "4"
  1186. u.Password = password + "4"
  1187. err = dataprovider.AddUser(&u, "", "", "")
  1188. assert.NoError(t, err)
  1189. user4, err := dataprovider.UserExists(u.Username, "")
  1190. assert.NoError(t, err)
  1191. c := &Configuration{
  1192. Bindings: []Binding{
  1193. {
  1194. Port: 9000,
  1195. },
  1196. },
  1197. Cache: Cache{
  1198. Users: UsersCacheConfig{
  1199. MaxSize: 3,
  1200. ExpirationTime: 1,
  1201. },
  1202. },
  1203. }
  1204. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  1205. server := webDavServer{
  1206. config: c,
  1207. binding: c.Bindings[0],
  1208. }
  1209. ipAddr := "127.0.1.1"
  1210. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1211. assert.NoError(t, err)
  1212. req.SetBasicAuth(user1.Username, password+"1")
  1213. _, isCached, _, loginMehod, err := server.authenticate(req, ipAddr)
  1214. assert.NoError(t, err)
  1215. assert.False(t, isCached)
  1216. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1217. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  1218. assert.NoError(t, err)
  1219. req.SetBasicAuth(user2.Username, password+"2")
  1220. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1221. assert.NoError(t, err)
  1222. assert.False(t, isCached)
  1223. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1224. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  1225. assert.NoError(t, err)
  1226. req.SetBasicAuth(user3.Username, password+"3")
  1227. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1228. assert.NoError(t, err)
  1229. assert.False(t, isCached)
  1230. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1231. // the first 3 users are now cached
  1232. _, ok := dataprovider.GetCachedWebDAVUser(user1.Username)
  1233. assert.True(t, ok)
  1234. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1235. assert.True(t, ok)
  1236. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1237. assert.True(t, ok)
  1238. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  1239. assert.NoError(t, err)
  1240. req.SetBasicAuth(user4.Username, password+"4")
  1241. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1242. assert.NoError(t, err)
  1243. assert.False(t, isCached)
  1244. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1245. // user1, the first cached, should be removed now
  1246. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1247. assert.False(t, ok)
  1248. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1249. assert.True(t, ok)
  1250. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1251. assert.True(t, ok)
  1252. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1253. assert.True(t, ok)
  1254. // a sleep ensures that expiration times are different
  1255. time.Sleep(20 * time.Millisecond)
  1256. // user1 logins, user2 should be removed
  1257. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1258. assert.NoError(t, err)
  1259. req.SetBasicAuth(user1.Username, password+"1")
  1260. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1261. assert.NoError(t, err)
  1262. assert.False(t, isCached)
  1263. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1264. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1265. assert.False(t, ok)
  1266. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1267. assert.True(t, ok)
  1268. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1269. assert.True(t, ok)
  1270. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1271. assert.True(t, ok)
  1272. // a sleep ensures that expiration times are different
  1273. time.Sleep(20 * time.Millisecond)
  1274. // user2 logins, user3 should be removed
  1275. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  1276. assert.NoError(t, err)
  1277. req.SetBasicAuth(user2.Username, password+"2")
  1278. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1279. assert.NoError(t, err)
  1280. assert.False(t, isCached)
  1281. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1282. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1283. assert.False(t, ok)
  1284. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1285. assert.True(t, ok)
  1286. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1287. assert.True(t, ok)
  1288. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1289. assert.True(t, ok)
  1290. // a sleep ensures that expiration times are different
  1291. time.Sleep(20 * time.Millisecond)
  1292. // user3 logins, user4 should be removed
  1293. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  1294. assert.NoError(t, err)
  1295. req.SetBasicAuth(user3.Username, password+"3")
  1296. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1297. assert.NoError(t, err)
  1298. assert.False(t, isCached)
  1299. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1300. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1301. assert.False(t, ok)
  1302. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1303. assert.True(t, ok)
  1304. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1305. assert.True(t, ok)
  1306. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1307. assert.True(t, ok)
  1308. // now remove user1 after an update
  1309. user1.HomeDir += "_mod"
  1310. err = dataprovider.UpdateUser(&user1, "", "", "")
  1311. assert.NoError(t, err)
  1312. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1313. assert.False(t, ok)
  1314. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  1315. assert.NoError(t, err)
  1316. req.SetBasicAuth(user4.Username, password+"4")
  1317. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1318. assert.NoError(t, err)
  1319. assert.False(t, isCached)
  1320. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1321. // a sleep ensures that expiration times are different
  1322. time.Sleep(20 * time.Millisecond)
  1323. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1324. assert.NoError(t, err)
  1325. req.SetBasicAuth(user1.Username, password+"1")
  1326. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1327. assert.NoError(t, err)
  1328. assert.False(t, isCached)
  1329. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1330. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1331. assert.False(t, ok)
  1332. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1333. assert.True(t, ok)
  1334. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1335. assert.True(t, ok)
  1336. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1337. assert.True(t, ok)
  1338. err = dataprovider.DeleteUser(user1.Username, "", "", "")
  1339. assert.NoError(t, err)
  1340. err = dataprovider.DeleteUser(user2.Username, "", "", "")
  1341. assert.NoError(t, err)
  1342. err = dataprovider.DeleteUser(user3.Username, "", "", "")
  1343. assert.NoError(t, err)
  1344. err = dataprovider.DeleteUser(user4.Username, "", "", "")
  1345. assert.NoError(t, err)
  1346. err = os.RemoveAll(u.GetHomeDir())
  1347. assert.NoError(t, err)
  1348. }
  1349. func TestUserCacheIsolation(t *testing.T) {
  1350. dataprovider.InitializeWebDAVUserCache(10)
  1351. username := "webdav_internal_cache_test"
  1352. password := "dav_pwd"
  1353. u := dataprovider.User{
  1354. BaseUser: sdk.BaseUser{
  1355. Username: username,
  1356. Password: password,
  1357. HomeDir: filepath.Join(os.TempDir(), username),
  1358. Status: 1,
  1359. ExpirationDate: 0,
  1360. },
  1361. }
  1362. u.Permissions = make(map[string][]string)
  1363. u.Permissions["/"] = []string{dataprovider.PermAny}
  1364. err := dataprovider.AddUser(&u, "", "", "")
  1365. assert.NoError(t, err)
  1366. user, err := dataprovider.UserExists(u.Username, "")
  1367. assert.NoError(t, err)
  1368. cachedUser := &dataprovider.CachedUser{
  1369. User: user,
  1370. Expiration: time.Now().Add(24 * time.Hour),
  1371. Password: password,
  1372. LockSystem: webdav.NewMemLS(),
  1373. }
  1374. cachedUser.User.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("test secret")
  1375. cachedUser.User.FsConfig.S3Config.SSECustomerKey = kms.NewPlainSecret("test key")
  1376. err = cachedUser.User.FsConfig.S3Config.AccessSecret.Encrypt()
  1377. assert.NoError(t, err)
  1378. err = cachedUser.User.FsConfig.S3Config.SSECustomerKey.Encrypt()
  1379. assert.NoError(t, err)
  1380. dataprovider.CacheWebDAVUser(cachedUser)
  1381. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  1382. if assert.True(t, ok) {
  1383. _, err = cachedUser.User.GetFilesystem("")
  1384. assert.NoError(t, err)
  1385. // the filesystem is now cached
  1386. }
  1387. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1388. if assert.True(t, ok) {
  1389. assert.True(t, cachedUser.User.FsConfig.S3Config.AccessSecret.IsEncrypted())
  1390. err = cachedUser.User.FsConfig.S3Config.AccessSecret.Decrypt()
  1391. assert.NoError(t, err)
  1392. assert.True(t, cachedUser.User.FsConfig.S3Config.SSECustomerKey.IsEncrypted())
  1393. err = cachedUser.User.FsConfig.S3Config.SSECustomerKey.Decrypt()
  1394. assert.NoError(t, err)
  1395. cachedUser.User.FsConfig.Provider = sdk.S3FilesystemProvider
  1396. _, err = cachedUser.User.GetFilesystem("")
  1397. assert.Error(t, err, "we don't have to get the previously cached filesystem!")
  1398. }
  1399. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1400. if assert.True(t, ok) {
  1401. assert.Equal(t, sdk.LocalFilesystemProvider, cachedUser.User.FsConfig.Provider)
  1402. assert.False(t, cachedUser.User.FsConfig.S3Config.AccessSecret.IsEncrypted())
  1403. assert.False(t, cachedUser.User.FsConfig.S3Config.SSECustomerKey.IsEncrypted())
  1404. }
  1405. err = dataprovider.DeleteUser(username, "", "", "")
  1406. assert.NoError(t, err)
  1407. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1408. assert.False(t, ok)
  1409. }
  1410. func TestRecoverer(t *testing.T) {
  1411. c := &Configuration{
  1412. Bindings: []Binding{
  1413. {
  1414. Port: 9000,
  1415. },
  1416. },
  1417. }
  1418. server := webDavServer{
  1419. config: c,
  1420. binding: c.Bindings[0],
  1421. }
  1422. rr := httptest.NewRecorder()
  1423. server.ServeHTTP(rr, nil)
  1424. assert.Equal(t, http.StatusInternalServerError, rr.Code)
  1425. }
  1426. func TestMimeCache(t *testing.T) {
  1427. cache := mimeCache{
  1428. maxSize: 0,
  1429. mimeTypes: make(map[string]string),
  1430. }
  1431. cache.addMimeToCache(".zip", "application/zip")
  1432. mtype := cache.getMimeFromCache(".zip")
  1433. assert.Equal(t, "", mtype)
  1434. cache.maxSize = 1
  1435. cache.addMimeToCache(".zip", "application/zip")
  1436. mtype = cache.getMimeFromCache(".zip")
  1437. assert.Equal(t, "application/zip", mtype)
  1438. cache.addMimeToCache(".jpg", "image/jpeg")
  1439. mtype = cache.getMimeFromCache(".jpg")
  1440. assert.Equal(t, "", mtype)
  1441. }
  1442. func TestVerifyTLSConnection(t *testing.T) {
  1443. oldCertMgr := certMgr
  1444. caCrlPath := filepath.Join(os.TempDir(), "testcrl.crt")
  1445. certPath := filepath.Join(os.TempDir(), "test.crt")
  1446. keyPath := filepath.Join(os.TempDir(), "test.key")
  1447. err := os.WriteFile(caCrlPath, []byte(caCRL), os.ModePerm)
  1448. assert.NoError(t, err)
  1449. err = os.WriteFile(certPath, []byte(webDavCert), os.ModePerm)
  1450. assert.NoError(t, err)
  1451. err = os.WriteFile(keyPath, []byte(webDavKey), os.ModePerm)
  1452. assert.NoError(t, err)
  1453. keyPairs := []common.TLSKeyPair{
  1454. {
  1455. Cert: certPath,
  1456. Key: keyPath,
  1457. ID: common.DefaultTLSKeyPaidID,
  1458. },
  1459. }
  1460. certMgr, err = common.NewCertManager(keyPairs, "", "webdav_test")
  1461. assert.NoError(t, err)
  1462. certMgr.SetCARevocationLists([]string{caCrlPath})
  1463. err = certMgr.LoadCRLs()
  1464. assert.NoError(t, err)
  1465. crt, err := tls.X509KeyPair([]byte(client1Crt), []byte(client1Key))
  1466. assert.NoError(t, err)
  1467. x509crt, err := x509.ParseCertificate(crt.Certificate[0])
  1468. assert.NoError(t, err)
  1469. server := webDavServer{}
  1470. state := tls.ConnectionState{
  1471. PeerCertificates: []*x509.Certificate{x509crt},
  1472. }
  1473. err = server.verifyTLSConnection(state)
  1474. assert.Error(t, err) // no verified certification chain
  1475. crt, err = tls.X509KeyPair([]byte(caCRT), []byte(caKey))
  1476. assert.NoError(t, err)
  1477. x509CAcrt, err := x509.ParseCertificate(crt.Certificate[0])
  1478. assert.NoError(t, err)
  1479. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crt, x509CAcrt})
  1480. err = server.verifyTLSConnection(state)
  1481. assert.NoError(t, err)
  1482. crt, err = tls.X509KeyPair([]byte(client2Crt), []byte(client2Key))
  1483. assert.NoError(t, err)
  1484. x509crtRevoked, err := x509.ParseCertificate(crt.Certificate[0])
  1485. assert.NoError(t, err)
  1486. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crtRevoked, x509CAcrt})
  1487. state.PeerCertificates = []*x509.Certificate{x509crtRevoked}
  1488. err = server.verifyTLSConnection(state)
  1489. assert.EqualError(t, err, common.ErrCrtRevoked.Error())
  1490. err = os.Remove(caCrlPath)
  1491. assert.NoError(t, err)
  1492. err = os.Remove(certPath)
  1493. assert.NoError(t, err)
  1494. err = os.Remove(keyPath)
  1495. assert.NoError(t, err)
  1496. certMgr = oldCertMgr
  1497. }
  1498. func TestMisc(t *testing.T) {
  1499. oldCertMgr := certMgr
  1500. certMgr = nil
  1501. err := ReloadCertificateMgr()
  1502. assert.Nil(t, err)
  1503. val := getConfigPath("", ".")
  1504. assert.Empty(t, val)
  1505. certMgr = oldCertMgr
  1506. }
  1507. func TestParseTime(t *testing.T) {
  1508. res, err := parseTime("Sat, 4 Feb 2023 17:00:50 GMT")
  1509. require.NoError(t, err)
  1510. require.Equal(t, int64(1675530050), res.Unix())
  1511. res, err = parseTime("Wed, 04 Nov 2020 13:25:51 GMT")
  1512. require.NoError(t, err)
  1513. require.Equal(t, int64(1604496351), res.Unix())
  1514. }
  1515. func TestConfigsFromProvider(t *testing.T) {
  1516. configDir := "."
  1517. err := dataprovider.UpdateConfigs(nil, "", "", "")
  1518. assert.NoError(t, err)
  1519. c := Configuration{
  1520. Bindings: []Binding{
  1521. {
  1522. Port: 1234,
  1523. },
  1524. },
  1525. }
  1526. err = c.loadFromProvider()
  1527. assert.NoError(t, err)
  1528. assert.Empty(t, c.acmeDomain)
  1529. configs := dataprovider.Configs{
  1530. ACME: &dataprovider.ACMEConfigs{
  1531. Domain: "domain.com",
  1532. Email: "[email protected]",
  1533. HTTP01Challenge: dataprovider.ACMEHTTP01Challenge{Port: 80},
  1534. Protocols: 7,
  1535. },
  1536. }
  1537. err = dataprovider.UpdateConfigs(&configs, "", "", "")
  1538. assert.NoError(t, err)
  1539. util.CertsBasePath = ""
  1540. // crt and key empty
  1541. err = c.loadFromProvider()
  1542. assert.NoError(t, err)
  1543. assert.Empty(t, c.acmeDomain)
  1544. util.CertsBasePath = filepath.Clean(os.TempDir())
  1545. // crt not found
  1546. err = c.loadFromProvider()
  1547. assert.NoError(t, err)
  1548. assert.Empty(t, c.acmeDomain)
  1549. keyPairs := c.getKeyPairs(configDir)
  1550. assert.Len(t, keyPairs, 0)
  1551. crtPath := filepath.Join(util.CertsBasePath, util.SanitizeDomain(configs.ACME.Domain)+".crt")
  1552. err = os.WriteFile(crtPath, nil, 0666)
  1553. assert.NoError(t, err)
  1554. // key not found
  1555. err = c.loadFromProvider()
  1556. assert.NoError(t, err)
  1557. assert.Empty(t, c.acmeDomain)
  1558. keyPairs = c.getKeyPairs(configDir)
  1559. assert.Len(t, keyPairs, 0)
  1560. keyPath := filepath.Join(util.CertsBasePath, util.SanitizeDomain(configs.ACME.Domain)+".key")
  1561. err = os.WriteFile(keyPath, nil, 0666)
  1562. assert.NoError(t, err)
  1563. // acme cert used
  1564. err = c.loadFromProvider()
  1565. assert.NoError(t, err)
  1566. assert.Equal(t, configs.ACME.Domain, c.acmeDomain)
  1567. keyPairs = c.getKeyPairs(configDir)
  1568. assert.Len(t, keyPairs, 1)
  1569. assert.True(t, c.Bindings[0].EnableHTTPS)
  1570. // protocols does not match
  1571. configs.ACME.Protocols = 3
  1572. err = dataprovider.UpdateConfigs(&configs, "", "", "")
  1573. assert.NoError(t, err)
  1574. c.acmeDomain = ""
  1575. err = c.loadFromProvider()
  1576. assert.NoError(t, err)
  1577. assert.Empty(t, c.acmeDomain)
  1578. keyPairs = c.getKeyPairs(configDir)
  1579. assert.Len(t, keyPairs, 0)
  1580. err = os.Remove(crtPath)
  1581. assert.NoError(t, err)
  1582. err = os.Remove(keyPath)
  1583. assert.NoError(t, err)
  1584. util.CertsBasePath = ""
  1585. err = dataprovider.UpdateConfigs(nil, "", "", "")
  1586. assert.NoError(t, err)
  1587. }
  1588. func TestGetCacheExpirationTime(t *testing.T) {
  1589. c := UsersCacheConfig{}
  1590. assert.True(t, c.getExpirationTime().IsZero())
  1591. c.ExpirationTime = 1
  1592. assert.False(t, c.getExpirationTime().IsZero())
  1593. }