internal_test.go 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715
  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, 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 TestRemoteAddress(t *testing.T) {
  361. remoteAddr1 := "100.100.100.100"
  362. remoteAddr2 := "172.172.172.172"
  363. c := &Configuration{
  364. Bindings: []Binding{
  365. {
  366. Port: 9000,
  367. ProxyAllowed: []string{remoteAddr2, "10.8.0.0/30"},
  368. },
  369. },
  370. }
  371. server := webDavServer{
  372. config: c,
  373. binding: c.Bindings[0],
  374. }
  375. err := server.binding.parseAllowedProxy()
  376. assert.NoError(t, err)
  377. req, err := http.NewRequest(http.MethodGet, "/", nil)
  378. assert.NoError(t, err)
  379. assert.Empty(t, req.RemoteAddr)
  380. trueClientIP := "True-Client-IP"
  381. cfConnectingIP := "CF-Connecting-IP"
  382. xff := "X-Forwarded-For"
  383. xRealIP := "X-Real-IP"
  384. req.Header.Set(trueClientIP, remoteAddr1)
  385. ip := util.GetRealIP(req, trueClientIP, 0)
  386. assert.Equal(t, remoteAddr1, ip)
  387. ip = util.GetRealIP(req, trueClientIP, 2)
  388. assert.Empty(t, ip)
  389. req.Header.Del(trueClientIP)
  390. req.Header.Set(cfConnectingIP, remoteAddr1)
  391. ip = util.GetRealIP(req, cfConnectingIP, 0)
  392. assert.Equal(t, remoteAddr1, ip)
  393. req.Header.Del(cfConnectingIP)
  394. req.Header.Set(xff, remoteAddr1)
  395. ip = util.GetRealIP(req, xff, 0)
  396. assert.Equal(t, remoteAddr1, ip)
  397. // this will be ignored, remoteAddr1 is not allowed to se this header
  398. req.Header.Set(xff, remoteAddr2)
  399. req.RemoteAddr = remoteAddr1
  400. ip = server.checkRemoteAddress(req)
  401. assert.Equal(t, remoteAddr1, ip)
  402. req.RemoteAddr = ""
  403. ip = server.checkRemoteAddress(req)
  404. assert.Empty(t, ip)
  405. req.Header.Set(xff, fmt.Sprintf("%v , %v", remoteAddr2, remoteAddr1))
  406. ip = util.GetRealIP(req, xff, 1)
  407. assert.Equal(t, remoteAddr2, ip)
  408. req.RemoteAddr = remoteAddr2
  409. req.Header.Set(xff, fmt.Sprintf("%v,%v", "12.34.56.78", "172.16.2.4"))
  410. server.binding.ClientIPHeaderDepth = 1
  411. server.binding.ClientIPProxyHeader = xff
  412. ip = server.checkRemoteAddress(req)
  413. assert.Equal(t, "12.34.56.78", ip)
  414. assert.Equal(t, ip, req.RemoteAddr)
  415. req.RemoteAddr = remoteAddr2
  416. req.Header.Set(xff, fmt.Sprintf("%v,%v", "12.34.56.79", "172.16.2.5"))
  417. server.binding.ClientIPHeaderDepth = 0
  418. ip = server.checkRemoteAddress(req)
  419. assert.Equal(t, "172.16.2.5", ip)
  420. assert.Equal(t, ip, req.RemoteAddr)
  421. req.RemoteAddr = "10.8.0.2"
  422. req.Header.Set(xff, remoteAddr1)
  423. ip = server.checkRemoteAddress(req)
  424. assert.Equal(t, remoteAddr1, ip)
  425. assert.Equal(t, ip, req.RemoteAddr)
  426. req.RemoteAddr = "10.8.0.3"
  427. req.Header.Set(xff, "not an ip")
  428. ip = server.checkRemoteAddress(req)
  429. assert.Equal(t, "10.8.0.3", ip)
  430. assert.Equal(t, ip, req.RemoteAddr)
  431. req.Header.Del(xff)
  432. req.RemoteAddr = ""
  433. req.Header.Set(xRealIP, remoteAddr1)
  434. ip = util.GetRealIP(req, "x-real-ip", 0)
  435. assert.Equal(t, remoteAddr1, ip)
  436. req.RemoteAddr = ""
  437. }
  438. func TestConnWithNilRequest(t *testing.T) {
  439. c := &Connection{}
  440. assert.Empty(t, c.GetClientVersion())
  441. assert.Empty(t, c.GetCommand())
  442. assert.Empty(t, c.GetRemoteAddress())
  443. assert.True(t, c.getModificationTime().IsZero())
  444. }
  445. func TestResolvePathErrors(t *testing.T) {
  446. ctx := context.Background()
  447. user := dataprovider.User{
  448. BaseUser: sdk.BaseUser{
  449. HomeDir: "invalid",
  450. },
  451. }
  452. user.Permissions = make(map[string][]string)
  453. user.Permissions["/"] = []string{dataprovider.PermAny}
  454. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  455. connection := &Connection{
  456. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  457. }
  458. err := connection.Mkdir(ctx, "", os.ModePerm)
  459. if assert.Error(t, err) {
  460. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  461. }
  462. err = connection.Rename(ctx, "oldName", "newName")
  463. if assert.Error(t, err) {
  464. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  465. }
  466. _, err = connection.Stat(ctx, "name")
  467. if assert.Error(t, err) {
  468. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  469. }
  470. err = connection.RemoveAll(ctx, "")
  471. if assert.Error(t, err) {
  472. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  473. }
  474. _, err = connection.OpenFile(ctx, "", 0, os.ModePerm)
  475. if assert.Error(t, err) {
  476. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  477. }
  478. if runtime.GOOS != "windows" {
  479. user.HomeDir = filepath.Clean(os.TempDir())
  480. connection.User = user
  481. fs := vfs.NewOsFs("connID", connection.User.HomeDir, "", nil)
  482. subDir := "sub"
  483. testTxtFile := "file.txt"
  484. err = os.MkdirAll(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  485. assert.NoError(t, err)
  486. err = os.WriteFile(filepath.Join(os.TempDir(), subDir, subDir, testTxtFile), []byte("content"), os.ModePerm)
  487. assert.NoError(t, err)
  488. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), 0001)
  489. assert.NoError(t, err)
  490. err = os.WriteFile(filepath.Join(os.TempDir(), testTxtFile), []byte("test content"), os.ModePerm)
  491. assert.NoError(t, err)
  492. err = connection.Rename(ctx, testTxtFile, path.Join(subDir, subDir, testTxtFile))
  493. if assert.Error(t, err) {
  494. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  495. }
  496. _, err = connection.putFile(fs, filepath.Join(connection.User.HomeDir, subDir, subDir, testTxtFile),
  497. path.Join(subDir, subDir, testTxtFile))
  498. if assert.Error(t, err) {
  499. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  500. }
  501. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  502. assert.NoError(t, err)
  503. err = os.RemoveAll(filepath.Join(os.TempDir(), subDir))
  504. assert.NoError(t, err)
  505. err = os.Remove(filepath.Join(os.TempDir(), testTxtFile))
  506. assert.NoError(t, err)
  507. }
  508. }
  509. func TestFileAccessErrors(t *testing.T) {
  510. ctx := context.Background()
  511. user := dataprovider.User{
  512. BaseUser: sdk.BaseUser{
  513. HomeDir: filepath.Clean(os.TempDir()),
  514. },
  515. }
  516. user.Permissions = make(map[string][]string)
  517. user.Permissions["/"] = []string{dataprovider.PermAny}
  518. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  519. connection := &Connection{
  520. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  521. }
  522. missingPath := "missing path"
  523. fsMissingPath := filepath.Join(user.HomeDir, missingPath)
  524. err := connection.RemoveAll(ctx, missingPath)
  525. assert.ErrorIs(t, err, os.ErrNotExist)
  526. davFile, err := connection.getFile(fs, fsMissingPath, missingPath)
  527. assert.NoError(t, err)
  528. buf := make([]byte, 64)
  529. _, err = davFile.Read(buf)
  530. assert.ErrorIs(t, err, os.ErrNotExist)
  531. err = davFile.Close()
  532. assert.ErrorIs(t, err, os.ErrNotExist)
  533. p := filepath.Join(user.HomeDir, "adir", missingPath)
  534. _, err = connection.handleUploadToNewFile(fs, p, p, path.Join("adir", missingPath))
  535. assert.ErrorIs(t, err, os.ErrNotExist)
  536. _, err = connection.handleUploadToExistingFile(fs, p, "_"+p, 0, path.Join("adir", missingPath))
  537. if assert.Error(t, err) {
  538. assert.ErrorIs(t, err, os.ErrNotExist)
  539. }
  540. fs = newMockOsFs(false, fs.ConnectionID(), user.HomeDir, nil, nil)
  541. _, err = connection.handleUploadToExistingFile(fs, p, p, 0, path.Join("adir", missingPath))
  542. assert.ErrorIs(t, err, os.ErrNotExist)
  543. f, err := os.CreateTemp("", "temp")
  544. assert.NoError(t, err)
  545. err = f.Close()
  546. assert.NoError(t, err)
  547. davFile, err = connection.handleUploadToExistingFile(fs, f.Name(), f.Name(), 123, f.Name())
  548. if assert.NoError(t, err) {
  549. transfer := davFile.(*webDavFile)
  550. transfers := connection.GetTransfers()
  551. if assert.Equal(t, 1, len(transfers)) {
  552. assert.Equal(t, transfers[0].ID, transfer.GetID())
  553. assert.Equal(t, int64(123), transfer.InitialSize)
  554. err = transfer.Close()
  555. assert.NoError(t, err)
  556. assert.Equal(t, 0, len(connection.GetTransfers()))
  557. }
  558. // test PROPPATCH date parsing error
  559. pstats, err := transfer.Patch([]webdav.Proppatch{
  560. {
  561. Props: []webdav.Property{
  562. {
  563. XMLName: xml.Name{
  564. Space: "DAV",
  565. Local: "getlastmodified",
  566. },
  567. InnerXML: []byte(`Wid, 04 Nov 2020 13:25:51 GMT`),
  568. },
  569. },
  570. },
  571. })
  572. assert.NoError(t, err)
  573. for _, pstat := range pstats {
  574. assert.Equal(t, http.StatusForbidden, pstat.Status)
  575. }
  576. err = os.Remove(f.Name())
  577. assert.NoError(t, err)
  578. // the file is deleted PROPPATCH should fail
  579. pstats, err = transfer.Patch([]webdav.Proppatch{
  580. {
  581. Props: []webdav.Property{
  582. {
  583. XMLName: xml.Name{
  584. Space: "DAV",
  585. Local: "getlastmodified",
  586. },
  587. InnerXML: []byte(`Wed, 04 Nov 2020 13:25:51 GMT`),
  588. },
  589. },
  590. },
  591. })
  592. assert.NoError(t, err)
  593. for _, pstat := range pstats {
  594. assert.Equal(t, http.StatusForbidden, pstat.Status)
  595. }
  596. }
  597. }
  598. func TestCheckRequestMethodWithPrefix(t *testing.T) {
  599. user := dataprovider.User{
  600. BaseUser: sdk.BaseUser{
  601. HomeDir: filepath.Clean(os.TempDir()),
  602. Permissions: map[string][]string{
  603. "/": {dataprovider.PermAny},
  604. },
  605. },
  606. }
  607. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  608. connection := &Connection{
  609. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  610. }
  611. server := webDavServer{
  612. binding: Binding{
  613. Prefix: "/dav",
  614. },
  615. }
  616. req, err := http.NewRequest(http.MethodGet, "/../dav", nil)
  617. require.NoError(t, err)
  618. server.checkRequestMethod(context.Background(), req, connection)
  619. require.Equal(t, "PROPFIND", req.Method)
  620. require.Equal(t, "1", req.Header.Get("Depth"))
  621. }
  622. func TestContentType(t *testing.T) {
  623. user := dataprovider.User{
  624. BaseUser: sdk.BaseUser{
  625. HomeDir: filepath.Clean(os.TempDir()),
  626. },
  627. }
  628. user.Permissions = make(map[string][]string)
  629. user.Permissions["/"] = []string{dataprovider.PermAny}
  630. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  631. connection := &Connection{
  632. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  633. }
  634. testFilePath := filepath.Join(user.HomeDir, testFile)
  635. ctx := context.Background()
  636. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".unknown",
  637. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  638. fs = newMockOsFs(false, fs.ConnectionID(), user.GetHomeDir(), nil, nil)
  639. err := os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  640. assert.NoError(t, err)
  641. davFile := newWebDavFile(baseTransfer, nil, nil)
  642. davFile.Fs = fs
  643. fi, err := davFile.Stat()
  644. if assert.NoError(t, err) {
  645. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  646. assert.NoError(t, err)
  647. assert.Equal(t, "application/custom-mime", ctype)
  648. }
  649. _, err = davFile.Readdir(-1)
  650. assert.ErrorIs(t, err, webdav.ErrNotImplemented)
  651. _, err = davFile.ReadDir()
  652. assert.Error(t, err)
  653. err = davFile.Close()
  654. assert.NoError(t, err)
  655. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".unknown1",
  656. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  657. davFile = newWebDavFile(baseTransfer, nil, nil)
  658. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, "", nil)
  659. fi, err = davFile.Stat()
  660. if assert.NoError(t, err) {
  661. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  662. assert.NoError(t, err)
  663. assert.Equal(t, "text/plain; charset=utf-8", ctype)
  664. }
  665. err = davFile.Close()
  666. assert.NoError(t, err)
  667. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  668. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  669. davFile = newWebDavFile(baseTransfer, nil, nil)
  670. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, "", nil)
  671. fi, err = davFile.Stat()
  672. if assert.NoError(t, err) {
  673. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  674. assert.NoError(t, err)
  675. assert.Equal(t, "application/octet-stream", ctype)
  676. }
  677. err = davFile.Close()
  678. assert.NoError(t, err)
  679. for i := 0; i < 2; i++ {
  680. // the second time the cache will be used
  681. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".custom",
  682. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  683. davFile = newWebDavFile(baseTransfer, nil, nil)
  684. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, "", nil)
  685. fi, err = davFile.Stat()
  686. if assert.NoError(t, err) {
  687. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  688. assert.NoError(t, err)
  689. assert.Equal(t, "text/plain; charset=utf-8", ctype)
  690. }
  691. err = davFile.Close()
  692. assert.NoError(t, err)
  693. }
  694. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".sftpgo",
  695. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  696. fs = newMockOsFs(false, fs.ConnectionID(), user.GetHomeDir(), nil, os.ErrInvalid)
  697. davFile = newWebDavFile(baseTransfer, nil, nil)
  698. davFile.Fs = fs
  699. fi, err = davFile.Stat()
  700. if assert.NoError(t, err) {
  701. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  702. assert.NoError(t, err)
  703. assert.Equal(t, "application/sftpgo", ctype)
  704. }
  705. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile+".unknown2",
  706. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  707. fs = newMockOsFs(false, fs.ConnectionID(), user.GetHomeDir(), nil, os.ErrInvalid)
  708. davFile = newWebDavFile(baseTransfer, nil, nil)
  709. davFile.Fs = fs
  710. fi, err = davFile.Stat()
  711. if assert.NoError(t, err) {
  712. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  713. assert.EqualError(t, err, webdav.ErrNotImplemented.Error(), "unexpected content type %q", ctype)
  714. }
  715. cache := mimeCache{
  716. maxSize: 10,
  717. mimeTypes: map[string]string{},
  718. }
  719. cache.addMimeToCache("", "")
  720. cache.RLock()
  721. assert.Len(t, cache.mimeTypes, 0)
  722. cache.RUnlock()
  723. err = os.Remove(testFilePath)
  724. assert.NoError(t, err)
  725. }
  726. func TestTransferReadWriteErrors(t *testing.T) {
  727. user := dataprovider.User{
  728. BaseUser: sdk.BaseUser{
  729. HomeDir: filepath.Clean(os.TempDir()),
  730. },
  731. }
  732. user.Permissions = make(map[string][]string)
  733. user.Permissions["/"] = []string{dataprovider.PermAny}
  734. fs := vfs.NewOsFs("connID", user.HomeDir, "", nil)
  735. connection := &Connection{
  736. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  737. }
  738. testFilePath := filepath.Join(user.HomeDir, testFile)
  739. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  740. common.TransferUpload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  741. davFile := newWebDavFile(baseTransfer, nil, nil)
  742. p := make([]byte, 1)
  743. _, err := davFile.Read(p)
  744. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  745. r, w, err := pipeat.Pipe()
  746. assert.NoError(t, err)
  747. davFile = newWebDavFile(baseTransfer, nil, r)
  748. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  749. davFile = newWebDavFile(baseTransfer, vfs.NewPipeWriter(w), nil)
  750. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  751. err = r.Close()
  752. assert.NoError(t, err)
  753. err = w.Close()
  754. assert.NoError(t, err)
  755. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  756. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  757. davFile = newWebDavFile(baseTransfer, nil, nil)
  758. _, err = davFile.Read(p)
  759. assert.True(t, fs.IsNotExist(err))
  760. _, err = davFile.Stat()
  761. assert.True(t, fs.IsNotExist(err))
  762. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  763. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  764. err = os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  765. assert.NoError(t, err)
  766. f, err := os.Open(testFilePath)
  767. if assert.NoError(t, err) {
  768. err = f.Close()
  769. assert.NoError(t, err)
  770. }
  771. davFile = newWebDavFile(baseTransfer, nil, nil)
  772. davFile.reader = f
  773. err = davFile.Close()
  774. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  775. err = davFile.Close()
  776. assert.EqualError(t, err, common.ErrTransferClosed.Error())
  777. _, err = davFile.Read(p)
  778. assert.Error(t, err)
  779. info, err := davFile.Stat()
  780. if assert.NoError(t, err) {
  781. assert.Equal(t, int64(0), info.Size())
  782. }
  783. r, w, err = pipeat.Pipe()
  784. assert.NoError(t, err)
  785. mockFs := newMockOsFs(false, fs.ConnectionID(), user.HomeDir, r, nil)
  786. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  787. common.TransferDownload, 0, 0, 0, 0, false, mockFs, dataprovider.TransferQuota{})
  788. davFile = newWebDavFile(baseTransfer, nil, nil)
  789. writeContent := []byte("content\r\n")
  790. go func() {
  791. n, err := w.Write(writeContent)
  792. assert.NoError(t, err)
  793. assert.Equal(t, len(writeContent), n)
  794. err = w.Close()
  795. assert.NoError(t, err)
  796. }()
  797. p = make([]byte, 64)
  798. n, err := davFile.Read(p)
  799. assert.EqualError(t, err, io.EOF.Error())
  800. assert.Equal(t, len(writeContent), n)
  801. err = davFile.Close()
  802. assert.NoError(t, err)
  803. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  804. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  805. davFile = newWebDavFile(baseTransfer, nil, nil)
  806. davFile.writer = f
  807. err = davFile.Close()
  808. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  809. err = os.Remove(testFilePath)
  810. assert.NoError(t, err)
  811. }
  812. func TestTransferSeek(t *testing.T) {
  813. user := dataprovider.User{
  814. BaseUser: sdk.BaseUser{
  815. HomeDir: filepath.Clean(os.TempDir()),
  816. },
  817. }
  818. user.Permissions = make(map[string][]string)
  819. user.Permissions["/"] = []string{dataprovider.PermAny}
  820. fs := newMockOsFs(true, "connID", user.HomeDir, nil, nil)
  821. connection := &Connection{
  822. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  823. }
  824. testFilePath := filepath.Join(user.HomeDir, testFile)
  825. testFileContents := []byte("content")
  826. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  827. common.TransferUpload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  828. davFile := newWebDavFile(baseTransfer, nil, nil)
  829. _, err := davFile.Seek(0, io.SeekStart)
  830. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  831. err = davFile.Close()
  832. assert.NoError(t, err)
  833. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  834. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  835. davFile = newWebDavFile(baseTransfer, nil, nil)
  836. _, err = davFile.Seek(0, io.SeekCurrent)
  837. assert.True(t, fs.IsNotExist(err))
  838. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  839. err = os.WriteFile(testFilePath, testFileContents, os.ModePerm)
  840. assert.NoError(t, err)
  841. f, err := os.Open(testFilePath)
  842. if assert.NoError(t, err) {
  843. err = f.Close()
  844. assert.NoError(t, err)
  845. }
  846. baseTransfer = common.NewBaseTransfer(f, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  847. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  848. davFile = newWebDavFile(baseTransfer, nil, nil)
  849. _, err = davFile.Seek(0, io.SeekStart)
  850. assert.Error(t, err)
  851. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  852. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  853. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  854. davFile = newWebDavFile(baseTransfer, nil, nil)
  855. res, err := davFile.Seek(0, io.SeekStart)
  856. assert.NoError(t, err)
  857. assert.Equal(t, int64(0), res)
  858. err = davFile.Close()
  859. assert.NoError(t, err)
  860. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  861. davFile = newWebDavFile(baseTransfer, nil, nil)
  862. res, err = davFile.Seek(0, io.SeekEnd)
  863. assert.NoError(t, err)
  864. assert.Equal(t, int64(len(testFileContents)), res)
  865. err = davFile.updateStatInfo()
  866. assert.NoError(t, err)
  867. err = davFile.Close()
  868. assert.NoError(t, err)
  869. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  870. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  871. davFile = newWebDavFile(baseTransfer, nil, nil)
  872. _, err = davFile.Seek(0, io.SeekEnd)
  873. assert.True(t, fs.IsNotExist(err))
  874. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  875. fs = vfs.NewOsFs(fs.ConnectionID(), user.GetHomeDir(), "", nil)
  876. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  877. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  878. davFile = newWebDavFile(baseTransfer, nil, nil)
  879. _, err = davFile.Seek(0, io.SeekEnd)
  880. assert.True(t, fs.IsNotExist(err))
  881. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  882. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  883. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  884. davFile = newWebDavFile(baseTransfer, nil, nil)
  885. davFile.reader = f
  886. r, _, err := pipeat.Pipe()
  887. assert.NoError(t, err)
  888. davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), r, nil)
  889. res, err = davFile.Seek(2, io.SeekStart)
  890. assert.NoError(t, err)
  891. assert.Equal(t, int64(2), res)
  892. err = davFile.Close()
  893. assert.NoError(t, err)
  894. r, _, err = pipeat.Pipe()
  895. assert.NoError(t, err)
  896. davFile = newWebDavFile(baseTransfer, nil, nil)
  897. davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), r, nil)
  898. res, err = davFile.Seek(2, io.SeekEnd)
  899. assert.NoError(t, err)
  900. assert.Equal(t, int64(5), res)
  901. err = davFile.Close()
  902. assert.NoError(t, err)
  903. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  904. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  905. davFile = newWebDavFile(baseTransfer, nil, nil)
  906. davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), nil, nil)
  907. res, err = davFile.Seek(2, io.SeekEnd)
  908. assert.True(t, fs.IsNotExist(err))
  909. assert.Equal(t, int64(0), res)
  910. assert.Len(t, common.Connections.GetStats(""), 0)
  911. err = os.Remove(testFilePath)
  912. assert.NoError(t, err)
  913. }
  914. func TestBasicUsersCache(t *testing.T) {
  915. username := "webdav_internal_test"
  916. password := "pwd"
  917. u := dataprovider.User{
  918. BaseUser: sdk.BaseUser{
  919. Username: username,
  920. Password: password,
  921. HomeDir: filepath.Join(os.TempDir(), username),
  922. Status: 1,
  923. ExpirationDate: 0,
  924. },
  925. }
  926. u.Permissions = make(map[string][]string)
  927. u.Permissions["/"] = []string{dataprovider.PermAny}
  928. err := dataprovider.AddUser(&u, "", "", "")
  929. assert.NoError(t, err)
  930. user, err := dataprovider.UserExists(u.Username, "")
  931. assert.NoError(t, err)
  932. c := &Configuration{
  933. Bindings: []Binding{
  934. {
  935. Port: 9000,
  936. },
  937. },
  938. Cache: Cache{
  939. Users: UsersCacheConfig{
  940. MaxSize: 50,
  941. ExpirationTime: 1,
  942. },
  943. },
  944. }
  945. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  946. server := webDavServer{
  947. config: c,
  948. binding: c.Bindings[0],
  949. }
  950. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user.Username), nil)
  951. assert.NoError(t, err)
  952. ipAddr := "127.0.0.1"
  953. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  954. assert.Error(t, err)
  955. now := time.Now()
  956. req.SetBasicAuth(username, password)
  957. _, isCached, _, loginMethod, err := server.authenticate(req, ipAddr)
  958. assert.NoError(t, err)
  959. assert.False(t, isCached)
  960. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  961. // now the user should be cached
  962. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  963. if assert.True(t, ok) {
  964. assert.False(t, cachedUser.IsExpired())
  965. assert.True(t, cachedUser.Expiration.After(now.Add(time.Duration(c.Cache.Users.ExpirationTime)*time.Minute)))
  966. // authenticate must return the cached user now
  967. authUser, isCached, _, _, err := server.authenticate(req, ipAddr)
  968. assert.NoError(t, err)
  969. assert.True(t, isCached)
  970. assert.Equal(t, cachedUser.User, authUser)
  971. }
  972. // a wrong password must fail
  973. req.SetBasicAuth(username, "wrong")
  974. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  975. assert.EqualError(t, err, dataprovider.ErrInvalidCredentials.Error())
  976. req.SetBasicAuth(username, password)
  977. // force cached user expiration
  978. cachedUser.Expiration = now
  979. dataprovider.CacheWebDAVUser(cachedUser)
  980. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  981. if assert.True(t, ok) {
  982. assert.True(t, cachedUser.IsExpired())
  983. }
  984. // now authenticate should get the user from the data provider and update the cache
  985. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  986. assert.NoError(t, err)
  987. assert.False(t, isCached)
  988. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  989. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  990. if assert.True(t, ok) {
  991. assert.False(t, cachedUser.IsExpired())
  992. }
  993. // cache is not invalidated after a user modification if the fs does not change
  994. err = dataprovider.UpdateUser(&user, "", "", "")
  995. assert.NoError(t, err)
  996. _, ok = dataprovider.GetCachedWebDAVUser(username)
  997. assert.True(t, ok)
  998. folderName := "testFolder"
  999. f := &vfs.BaseVirtualFolder{
  1000. Name: folderName,
  1001. MappedPath: filepath.Join(os.TempDir(), "mapped"),
  1002. }
  1003. err = dataprovider.AddFolder(f, "", "", "")
  1004. assert.NoError(t, err)
  1005. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  1006. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1007. Name: folderName,
  1008. },
  1009. VirtualPath: "/vdir",
  1010. })
  1011. err = dataprovider.UpdateUser(&user, "", "", "")
  1012. assert.NoError(t, err)
  1013. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1014. assert.False(t, ok)
  1015. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1016. assert.NoError(t, err)
  1017. assert.False(t, isCached)
  1018. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1019. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1020. assert.True(t, ok)
  1021. // cache is invalidated after user deletion
  1022. err = dataprovider.DeleteUser(user.Username, "", "", "")
  1023. assert.NoError(t, err)
  1024. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1025. assert.False(t, ok)
  1026. err = dataprovider.DeleteFolder(folderName, "", "", "")
  1027. assert.NoError(t, err)
  1028. err = os.RemoveAll(u.GetHomeDir())
  1029. assert.NoError(t, err)
  1030. }
  1031. func TestCachedUserWithFolders(t *testing.T) {
  1032. username := "webdav_internal_folder_test"
  1033. password := "dav_pwd"
  1034. folderName := "test_folder"
  1035. u := dataprovider.User{
  1036. BaseUser: sdk.BaseUser{
  1037. Username: username,
  1038. Password: password,
  1039. HomeDir: filepath.Join(os.TempDir(), username),
  1040. Status: 1,
  1041. ExpirationDate: 0,
  1042. },
  1043. }
  1044. u.Permissions = make(map[string][]string)
  1045. u.Permissions["/"] = []string{dataprovider.PermAny}
  1046. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  1047. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1048. Name: folderName,
  1049. },
  1050. VirtualPath: "/vpath",
  1051. })
  1052. f := &vfs.BaseVirtualFolder{
  1053. Name: folderName,
  1054. MappedPath: filepath.Join(os.TempDir(), folderName),
  1055. }
  1056. err := dataprovider.AddFolder(f, "", "", "")
  1057. assert.NoError(t, err)
  1058. err = dataprovider.AddUser(&u, "", "", "")
  1059. assert.NoError(t, err)
  1060. user, err := dataprovider.UserExists(u.Username, "")
  1061. assert.NoError(t, err)
  1062. c := &Configuration{
  1063. Bindings: []Binding{
  1064. {
  1065. Port: 9000,
  1066. },
  1067. },
  1068. Cache: Cache{
  1069. Users: UsersCacheConfig{
  1070. MaxSize: 50,
  1071. ExpirationTime: 1,
  1072. },
  1073. },
  1074. }
  1075. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  1076. server := webDavServer{
  1077. config: c,
  1078. binding: c.Bindings[0],
  1079. }
  1080. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user.Username), nil)
  1081. assert.NoError(t, err)
  1082. ipAddr := "127.0.0.1"
  1083. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  1084. assert.Error(t, err)
  1085. now := time.Now()
  1086. req.SetBasicAuth(username, password)
  1087. _, isCached, _, loginMethod, err := server.authenticate(req, ipAddr)
  1088. assert.NoError(t, err)
  1089. assert.False(t, isCached)
  1090. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1091. // now the user should be cached
  1092. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  1093. if assert.True(t, ok) {
  1094. assert.False(t, cachedUser.IsExpired())
  1095. assert.True(t, cachedUser.Expiration.After(now.Add(time.Duration(c.Cache.Users.ExpirationTime)*time.Minute)))
  1096. // authenticate must return the cached user now
  1097. authUser, isCached, _, _, err := server.authenticate(req, ipAddr)
  1098. assert.NoError(t, err)
  1099. assert.True(t, isCached)
  1100. assert.Equal(t, cachedUser.User, authUser)
  1101. }
  1102. folder, err := dataprovider.GetFolderByName(folderName)
  1103. assert.NoError(t, err)
  1104. // updating a used folder should invalidate the cache only if the fs changed
  1105. err = dataprovider.UpdateFolder(&folder, folder.Users, folder.Groups, "", "", "")
  1106. assert.NoError(t, err)
  1107. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1108. assert.NoError(t, err)
  1109. assert.True(t, isCached)
  1110. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1111. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1112. if assert.True(t, ok) {
  1113. assert.False(t, cachedUser.IsExpired())
  1114. }
  1115. // changing the folder path should invalidate the cache
  1116. folder.MappedPath = filepath.Join(os.TempDir(), "anotherpath")
  1117. err = dataprovider.UpdateFolder(&folder, folder.Users, folder.Groups, "", "", "")
  1118. assert.NoError(t, err)
  1119. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1120. assert.NoError(t, err)
  1121. assert.False(t, isCached)
  1122. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1123. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1124. if assert.True(t, ok) {
  1125. assert.False(t, cachedUser.IsExpired())
  1126. }
  1127. err = dataprovider.DeleteFolder(folderName, "", "", "")
  1128. assert.NoError(t, err)
  1129. // removing a used folder should invalidate the cache
  1130. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1131. assert.NoError(t, err)
  1132. assert.False(t, isCached)
  1133. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1134. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1135. if assert.True(t, ok) {
  1136. assert.False(t, cachedUser.IsExpired())
  1137. }
  1138. err = dataprovider.DeleteUser(user.Username, "", "", "")
  1139. assert.NoError(t, err)
  1140. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1141. assert.False(t, ok)
  1142. err = os.RemoveAll(u.GetHomeDir())
  1143. assert.NoError(t, err)
  1144. err = os.RemoveAll(folder.MappedPath)
  1145. assert.NoError(t, err)
  1146. }
  1147. func TestUsersCacheSizeAndExpiration(t *testing.T) {
  1148. username := "webdav_internal_test"
  1149. password := "pwd"
  1150. u := dataprovider.User{
  1151. BaseUser: sdk.BaseUser{
  1152. HomeDir: filepath.Join(os.TempDir(), username),
  1153. Status: 1,
  1154. ExpirationDate: 0,
  1155. },
  1156. }
  1157. u.Username = username + "1"
  1158. u.Password = password + "1"
  1159. u.Permissions = make(map[string][]string)
  1160. u.Permissions["/"] = []string{dataprovider.PermAny}
  1161. err := dataprovider.AddUser(&u, "", "", "")
  1162. assert.NoError(t, err)
  1163. user1, err := dataprovider.UserExists(u.Username, "")
  1164. assert.NoError(t, err)
  1165. u.Username = username + "2"
  1166. u.Password = password + "2"
  1167. err = dataprovider.AddUser(&u, "", "", "")
  1168. assert.NoError(t, err)
  1169. user2, err := dataprovider.UserExists(u.Username, "")
  1170. assert.NoError(t, err)
  1171. u.Username = username + "3"
  1172. u.Password = password + "3"
  1173. err = dataprovider.AddUser(&u, "", "", "")
  1174. assert.NoError(t, err)
  1175. user3, err := dataprovider.UserExists(u.Username, "")
  1176. assert.NoError(t, err)
  1177. u.Username = username + "4"
  1178. u.Password = password + "4"
  1179. err = dataprovider.AddUser(&u, "", "", "")
  1180. assert.NoError(t, err)
  1181. user4, err := dataprovider.UserExists(u.Username, "")
  1182. assert.NoError(t, err)
  1183. c := &Configuration{
  1184. Bindings: []Binding{
  1185. {
  1186. Port: 9000,
  1187. },
  1188. },
  1189. Cache: Cache{
  1190. Users: UsersCacheConfig{
  1191. MaxSize: 3,
  1192. ExpirationTime: 1,
  1193. },
  1194. },
  1195. }
  1196. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  1197. server := webDavServer{
  1198. config: c,
  1199. binding: c.Bindings[0],
  1200. }
  1201. ipAddr := "127.0.1.1"
  1202. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1203. assert.NoError(t, err)
  1204. req.SetBasicAuth(user1.Username, password+"1")
  1205. _, isCached, _, loginMehod, err := server.authenticate(req, ipAddr)
  1206. assert.NoError(t, err)
  1207. assert.False(t, isCached)
  1208. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1209. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  1210. assert.NoError(t, err)
  1211. req.SetBasicAuth(user2.Username, password+"2")
  1212. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1213. assert.NoError(t, err)
  1214. assert.False(t, isCached)
  1215. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1216. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  1217. assert.NoError(t, err)
  1218. req.SetBasicAuth(user3.Username, password+"3")
  1219. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1220. assert.NoError(t, err)
  1221. assert.False(t, isCached)
  1222. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1223. // the first 3 users are now cached
  1224. _, ok := dataprovider.GetCachedWebDAVUser(user1.Username)
  1225. assert.True(t, ok)
  1226. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1227. assert.True(t, ok)
  1228. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1229. assert.True(t, ok)
  1230. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  1231. assert.NoError(t, err)
  1232. req.SetBasicAuth(user4.Username, password+"4")
  1233. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1234. assert.NoError(t, err)
  1235. assert.False(t, isCached)
  1236. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1237. // user1, the first cached, should be removed now
  1238. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1239. assert.False(t, ok)
  1240. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1241. assert.True(t, ok)
  1242. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1243. assert.True(t, ok)
  1244. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1245. assert.True(t, ok)
  1246. // a sleep ensures that expiration times are different
  1247. time.Sleep(20 * time.Millisecond)
  1248. // user1 logins, user2 should be removed
  1249. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1250. assert.NoError(t, err)
  1251. req.SetBasicAuth(user1.Username, password+"1")
  1252. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1253. assert.NoError(t, err)
  1254. assert.False(t, isCached)
  1255. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1256. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1257. assert.False(t, ok)
  1258. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1259. assert.True(t, ok)
  1260. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1261. assert.True(t, ok)
  1262. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1263. assert.True(t, ok)
  1264. // a sleep ensures that expiration times are different
  1265. time.Sleep(20 * time.Millisecond)
  1266. // user2 logins, user3 should be removed
  1267. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  1268. assert.NoError(t, err)
  1269. req.SetBasicAuth(user2.Username, password+"2")
  1270. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1271. assert.NoError(t, err)
  1272. assert.False(t, isCached)
  1273. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1274. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1275. assert.False(t, ok)
  1276. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1277. assert.True(t, ok)
  1278. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1279. assert.True(t, ok)
  1280. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1281. assert.True(t, ok)
  1282. // a sleep ensures that expiration times are different
  1283. time.Sleep(20 * time.Millisecond)
  1284. // user3 logins, user4 should be removed
  1285. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  1286. assert.NoError(t, err)
  1287. req.SetBasicAuth(user3.Username, password+"3")
  1288. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1289. assert.NoError(t, err)
  1290. assert.False(t, isCached)
  1291. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1292. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1293. assert.False(t, ok)
  1294. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1295. assert.True(t, ok)
  1296. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1297. assert.True(t, ok)
  1298. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1299. assert.True(t, ok)
  1300. // now remove user1 after an update
  1301. user1.HomeDir += "_mod"
  1302. err = dataprovider.UpdateUser(&user1, "", "", "")
  1303. assert.NoError(t, err)
  1304. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1305. assert.False(t, ok)
  1306. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  1307. assert.NoError(t, err)
  1308. req.SetBasicAuth(user4.Username, password+"4")
  1309. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1310. assert.NoError(t, err)
  1311. assert.False(t, isCached)
  1312. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1313. // a sleep ensures that expiration times are different
  1314. time.Sleep(20 * time.Millisecond)
  1315. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1316. assert.NoError(t, err)
  1317. req.SetBasicAuth(user1.Username, password+"1")
  1318. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1319. assert.NoError(t, err)
  1320. assert.False(t, isCached)
  1321. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1322. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1323. assert.False(t, ok)
  1324. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1325. assert.True(t, ok)
  1326. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1327. assert.True(t, ok)
  1328. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1329. assert.True(t, ok)
  1330. err = dataprovider.DeleteUser(user1.Username, "", "", "")
  1331. assert.NoError(t, err)
  1332. err = dataprovider.DeleteUser(user2.Username, "", "", "")
  1333. assert.NoError(t, err)
  1334. err = dataprovider.DeleteUser(user3.Username, "", "", "")
  1335. assert.NoError(t, err)
  1336. err = dataprovider.DeleteUser(user4.Username, "", "", "")
  1337. assert.NoError(t, err)
  1338. err = os.RemoveAll(u.GetHomeDir())
  1339. assert.NoError(t, err)
  1340. }
  1341. func TestUserCacheIsolation(t *testing.T) {
  1342. dataprovider.InitializeWebDAVUserCache(10)
  1343. username := "webdav_internal_cache_test"
  1344. password := "dav_pwd"
  1345. u := dataprovider.User{
  1346. BaseUser: sdk.BaseUser{
  1347. Username: username,
  1348. Password: password,
  1349. HomeDir: filepath.Join(os.TempDir(), username),
  1350. Status: 1,
  1351. ExpirationDate: 0,
  1352. },
  1353. }
  1354. u.Permissions = make(map[string][]string)
  1355. u.Permissions["/"] = []string{dataprovider.PermAny}
  1356. err := dataprovider.AddUser(&u, "", "", "")
  1357. assert.NoError(t, err)
  1358. user, err := dataprovider.UserExists(u.Username, "")
  1359. assert.NoError(t, err)
  1360. cachedUser := &dataprovider.CachedUser{
  1361. User: user,
  1362. Expiration: time.Now().Add(24 * time.Hour),
  1363. Password: password,
  1364. LockSystem: webdav.NewMemLS(),
  1365. }
  1366. cachedUser.User.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("test secret")
  1367. err = cachedUser.User.FsConfig.S3Config.AccessSecret.Encrypt()
  1368. assert.NoError(t, err)
  1369. dataprovider.CacheWebDAVUser(cachedUser)
  1370. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  1371. if assert.True(t, ok) {
  1372. _, err = cachedUser.User.GetFilesystem("")
  1373. assert.NoError(t, err)
  1374. // the filesystem is now cached
  1375. }
  1376. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1377. if assert.True(t, ok) {
  1378. assert.True(t, cachedUser.User.FsConfig.S3Config.AccessSecret.IsEncrypted())
  1379. err = cachedUser.User.FsConfig.S3Config.AccessSecret.Decrypt()
  1380. assert.NoError(t, err)
  1381. cachedUser.User.FsConfig.Provider = sdk.S3FilesystemProvider
  1382. _, err = cachedUser.User.GetFilesystem("")
  1383. assert.Error(t, err, "we don't have to get the previously cached filesystem!")
  1384. }
  1385. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1386. if assert.True(t, ok) {
  1387. assert.Equal(t, sdk.LocalFilesystemProvider, cachedUser.User.FsConfig.Provider)
  1388. assert.False(t, cachedUser.User.FsConfig.S3Config.AccessSecret.IsEncrypted())
  1389. }
  1390. err = dataprovider.DeleteUser(username, "", "", "")
  1391. assert.NoError(t, err)
  1392. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1393. assert.False(t, ok)
  1394. }
  1395. func TestRecoverer(t *testing.T) {
  1396. c := &Configuration{
  1397. Bindings: []Binding{
  1398. {
  1399. Port: 9000,
  1400. },
  1401. },
  1402. }
  1403. server := webDavServer{
  1404. config: c,
  1405. binding: c.Bindings[0],
  1406. }
  1407. rr := httptest.NewRecorder()
  1408. server.ServeHTTP(rr, nil)
  1409. assert.Equal(t, http.StatusInternalServerError, rr.Code)
  1410. }
  1411. func TestMimeCache(t *testing.T) {
  1412. cache := mimeCache{
  1413. maxSize: 0,
  1414. mimeTypes: make(map[string]string),
  1415. }
  1416. cache.addMimeToCache(".zip", "application/zip")
  1417. mtype := cache.getMimeFromCache(".zip")
  1418. assert.Equal(t, "", mtype)
  1419. cache.maxSize = 1
  1420. cache.addMimeToCache(".zip", "application/zip")
  1421. mtype = cache.getMimeFromCache(".zip")
  1422. assert.Equal(t, "application/zip", mtype)
  1423. cache.addMimeToCache(".jpg", "image/jpeg")
  1424. mtype = cache.getMimeFromCache(".jpg")
  1425. assert.Equal(t, "", mtype)
  1426. }
  1427. func TestVerifyTLSConnection(t *testing.T) {
  1428. oldCertMgr := certMgr
  1429. caCrlPath := filepath.Join(os.TempDir(), "testcrl.crt")
  1430. certPath := filepath.Join(os.TempDir(), "test.crt")
  1431. keyPath := filepath.Join(os.TempDir(), "test.key")
  1432. err := os.WriteFile(caCrlPath, []byte(caCRL), os.ModePerm)
  1433. assert.NoError(t, err)
  1434. err = os.WriteFile(certPath, []byte(webDavCert), os.ModePerm)
  1435. assert.NoError(t, err)
  1436. err = os.WriteFile(keyPath, []byte(webDavKey), os.ModePerm)
  1437. assert.NoError(t, err)
  1438. keyPairs := []common.TLSKeyPair{
  1439. {
  1440. Cert: certPath,
  1441. Key: keyPath,
  1442. ID: common.DefaultTLSKeyPaidID,
  1443. },
  1444. }
  1445. certMgr, err = common.NewCertManager(keyPairs, "", "webdav_test")
  1446. assert.NoError(t, err)
  1447. certMgr.SetCARevocationLists([]string{caCrlPath})
  1448. err = certMgr.LoadCRLs()
  1449. assert.NoError(t, err)
  1450. crt, err := tls.X509KeyPair([]byte(client1Crt), []byte(client1Key))
  1451. assert.NoError(t, err)
  1452. x509crt, err := x509.ParseCertificate(crt.Certificate[0])
  1453. assert.NoError(t, err)
  1454. server := webDavServer{}
  1455. state := tls.ConnectionState{
  1456. PeerCertificates: []*x509.Certificate{x509crt},
  1457. }
  1458. err = server.verifyTLSConnection(state)
  1459. assert.Error(t, err) // no verified certification chain
  1460. crt, err = tls.X509KeyPair([]byte(caCRT), []byte(caKey))
  1461. assert.NoError(t, err)
  1462. x509CAcrt, err := x509.ParseCertificate(crt.Certificate[0])
  1463. assert.NoError(t, err)
  1464. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crt, x509CAcrt})
  1465. err = server.verifyTLSConnection(state)
  1466. assert.NoError(t, err)
  1467. crt, err = tls.X509KeyPair([]byte(client2Crt), []byte(client2Key))
  1468. assert.NoError(t, err)
  1469. x509crtRevoked, err := x509.ParseCertificate(crt.Certificate[0])
  1470. assert.NoError(t, err)
  1471. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crtRevoked, x509CAcrt})
  1472. state.PeerCertificates = []*x509.Certificate{x509crtRevoked}
  1473. err = server.verifyTLSConnection(state)
  1474. assert.EqualError(t, err, common.ErrCrtRevoked.Error())
  1475. err = os.Remove(caCrlPath)
  1476. assert.NoError(t, err)
  1477. err = os.Remove(certPath)
  1478. assert.NoError(t, err)
  1479. err = os.Remove(keyPath)
  1480. assert.NoError(t, err)
  1481. certMgr = oldCertMgr
  1482. }
  1483. func TestMisc(t *testing.T) {
  1484. oldCertMgr := certMgr
  1485. certMgr = nil
  1486. err := ReloadCertificateMgr()
  1487. assert.Nil(t, err)
  1488. val := getConfigPath("", ".")
  1489. assert.Empty(t, val)
  1490. certMgr = oldCertMgr
  1491. }
  1492. func TestParseTime(t *testing.T) {
  1493. res, err := parseTime("Sat, 4 Feb 2023 17:00:50 GMT")
  1494. require.NoError(t, err)
  1495. require.Equal(t, int64(1675530050), res.Unix())
  1496. res, err = parseTime("Wed, 04 Nov 2020 13:25:51 GMT")
  1497. require.NoError(t, err)
  1498. require.Equal(t, int64(1604496351), res.Unix())
  1499. }
  1500. func TestConfigsFromProvider(t *testing.T) {
  1501. configDir := "."
  1502. err := dataprovider.UpdateConfigs(nil, "", "", "")
  1503. assert.NoError(t, err)
  1504. c := Configuration{
  1505. Bindings: []Binding{
  1506. {
  1507. Port: 1234,
  1508. },
  1509. },
  1510. }
  1511. err = c.loadFromProvider()
  1512. assert.NoError(t, err)
  1513. assert.Empty(t, c.acmeDomain)
  1514. configs := dataprovider.Configs{
  1515. ACME: &dataprovider.ACMEConfigs{
  1516. Domain: "domain.com",
  1517. Email: "[email protected]",
  1518. HTTP01Challenge: dataprovider.ACMEHTTP01Challenge{Port: 80},
  1519. Protocols: 7,
  1520. },
  1521. }
  1522. err = dataprovider.UpdateConfigs(&configs, "", "", "")
  1523. assert.NoError(t, err)
  1524. util.CertsBasePath = ""
  1525. // crt and key empty
  1526. err = c.loadFromProvider()
  1527. assert.NoError(t, err)
  1528. assert.Empty(t, c.acmeDomain)
  1529. util.CertsBasePath = filepath.Clean(os.TempDir())
  1530. // crt not found
  1531. err = c.loadFromProvider()
  1532. assert.NoError(t, err)
  1533. assert.Empty(t, c.acmeDomain)
  1534. keyPairs := c.getKeyPairs(configDir)
  1535. assert.Len(t, keyPairs, 0)
  1536. crtPath := filepath.Join(util.CertsBasePath, util.SanitizeDomain(configs.ACME.Domain)+".crt")
  1537. err = os.WriteFile(crtPath, nil, 0666)
  1538. assert.NoError(t, err)
  1539. // key not found
  1540. err = c.loadFromProvider()
  1541. assert.NoError(t, err)
  1542. assert.Empty(t, c.acmeDomain)
  1543. keyPairs = c.getKeyPairs(configDir)
  1544. assert.Len(t, keyPairs, 0)
  1545. keyPath := filepath.Join(util.CertsBasePath, util.SanitizeDomain(configs.ACME.Domain)+".key")
  1546. err = os.WriteFile(keyPath, nil, 0666)
  1547. assert.NoError(t, err)
  1548. // acme cert used
  1549. err = c.loadFromProvider()
  1550. assert.NoError(t, err)
  1551. assert.Equal(t, configs.ACME.Domain, c.acmeDomain)
  1552. keyPairs = c.getKeyPairs(configDir)
  1553. assert.Len(t, keyPairs, 1)
  1554. assert.True(t, c.Bindings[0].EnableHTTPS)
  1555. // protocols does not match
  1556. configs.ACME.Protocols = 3
  1557. err = dataprovider.UpdateConfigs(&configs, "", "", "")
  1558. assert.NoError(t, err)
  1559. c.acmeDomain = ""
  1560. err = c.loadFromProvider()
  1561. assert.NoError(t, err)
  1562. assert.Empty(t, c.acmeDomain)
  1563. keyPairs = c.getKeyPairs(configDir)
  1564. assert.Len(t, keyPairs, 0)
  1565. err = os.Remove(crtPath)
  1566. assert.NoError(t, err)
  1567. err = os.Remove(keyPath)
  1568. assert.NoError(t, err)
  1569. util.CertsBasePath = ""
  1570. err = dataprovider.UpdateConfigs(nil, "", "", "")
  1571. assert.NoError(t, err)
  1572. }
  1573. func TestGetCacheExpirationTime(t *testing.T) {
  1574. c := UsersCacheConfig{}
  1575. assert.True(t, c.getExpirationTime().IsZero())
  1576. c.ExpirationTime = 1
  1577. assert.False(t, c.getExpirationTime().IsZero())
  1578. }