internal_test.go 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274
  1. package webdavd
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "crypto/x509"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "net/http"
  10. "net/http/httptest"
  11. "os"
  12. "path"
  13. "path/filepath"
  14. "runtime"
  15. "testing"
  16. "time"
  17. "github.com/eikenb/pipeat"
  18. "github.com/stretchr/testify/assert"
  19. "golang.org/x/net/webdav"
  20. "github.com/drakkan/sftpgo/common"
  21. "github.com/drakkan/sftpgo/dataprovider"
  22. "github.com/drakkan/sftpgo/vfs"
  23. )
  24. const (
  25. testFile = "test_dav_file"
  26. webDavCert = `-----BEGIN CERTIFICATE-----
  27. MIICHTCCAaKgAwIBAgIUHnqw7QnB1Bj9oUsNpdb+ZkFPOxMwCgYIKoZIzj0EAwIw
  28. RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
  29. dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDAyMDQwOTUzMDRaFw0zMDAyMDEw
  30. OTUzMDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
  31. VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
  32. IgNiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVqWvrJ51t5OxV0v25NsOgR82CA
  33. NXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIVCzgWkxiz7XE4lgUwX44FCXZM
  34. 3+JeUbKjUzBRMB0GA1UdDgQWBBRhLw+/o3+Z02MI/d4tmaMui9W16jAfBgNVHSME
  35. GDAWgBRhLw+/o3+Z02MI/d4tmaMui9W16jAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
  36. SM49BAMCA2kAMGYCMQDqLt2lm8mE+tGgtjDmtFgdOcI72HSbRQ74D5rYTzgST1rY
  37. /8wTi5xl8TiFUyLMUsICMQC5ViVxdXbhuG7gX6yEqSkMKZICHpO8hqFwOD/uaFVI
  38. dV4vKmHUzwK/eIx+8Ay3neE=
  39. -----END CERTIFICATE-----`
  40. webDavKey = `-----BEGIN EC PARAMETERS-----
  41. BgUrgQQAIg==
  42. -----END EC PARAMETERS-----
  43. -----BEGIN EC PRIVATE KEY-----
  44. MIGkAgEBBDCfMNsN6miEE3rVyUPwElfiJSWaR5huPCzUenZOfJT04GAcQdWvEju3
  45. UM2lmBLIXpGgBwYFK4EEACKhZANiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVq
  46. WvrJ51t5OxV0v25NsOgR82CANXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIV
  47. CzgWkxiz7XE4lgUwX44FCXZM3+JeUbI=
  48. -----END EC PRIVATE KEY-----`
  49. caCRT = `-----BEGIN CERTIFICATE-----
  50. MIIE5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhDZXJ0
  51. QXV0aDAeFw0yMTAxMDIyMTIwNTVaFw0yMjA3MDIyMTMwNTJaMBMxETAPBgNVBAMT
  52. CENlcnRBdXRoMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4Tiho5xW
  53. AC15JRkMwfp3/TJwI2As7MY5dele5cmdr5bHAE+sRKqC+Ti88OJWCV5saoyax/1S
  54. CjxJlQMZMl169P1QYJskKjdG2sdv6RLWLMgwSNRRjxp/Bw9dHdiEb9MjLgu28Jro
  55. 9peQkHcRHeMf5hM9WvlIJGrdzbC4hUehmqggcqgARainBkYjf0SwuWxHeu4nMqkp
  56. Ak5tcSTLCjHfEFHZ9Te0TIPG5YkWocQKyeLgu4lvuU+DD2W2lym+YVUtRMGs1Env
  57. k7p+N0DcGU26qfzZ2sF5ZXkqm7dBsGQB9pIxwc2Q8T1dCIyP9OQCKVILdc5aVFf1
  58. cryQFHYzYNNZXFlIBims5VV5Mgfp8ESHQSue+v6n6ykecLEyKt1F1Y/MWY/nWUSI
  59. 8zdq83jdBAZVjo9MSthxVn57/06s/hQca65IpcTZV2gX0a+eRlAVqaRbAhL3LaZe
  60. bYsW3WHKoUOftwemuep3nL51TzlXZVL7Oz/ClGaEOsnGG9KFO6jh+W768qC0zLQI
  61. CdE7v2Zex98sZteHCg9fGJHIaYoF0aJG5P3WI5oZf2fy7UIYN9ADLFZiorCXAZEh
  62. CSU6mDoRViZ4RGR9GZxbDZ9KYn7O8M/KCR72bkQg73TlMsk1zSXEw0MKLUjtsw6c
  63. rZ0Jt8t3sRatHO3JrYHALMt9vZfyNCZp0IsCAwEAAaNFMEMwDgYDVR0PAQH/BAQD
  64. AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFO1yCNAGr/zQTJIi8lw3
  65. w5OiuBvMMA0GCSqGSIb3DQEBCwUAA4ICAQA6gCNuM7r8mnx674dm31GxBjQy5ZwB
  66. 7CxDzYEvL/oiZ3Tv3HlPfN2LAAsJUfGnghh9DOytenL2CTZWjl/emP5eijzmlP+9
  67. zva5I6CIMCf/eDDVsRdO244t0o4uG7+At0IgSDM3bpVaVb4RHZNjEziYChsEYY8d
  68. HK6iwuRSvFniV6yhR/Vj1Ymi9yZ5xclqseLXiQnUB0PkfIk23+7s42cXB16653fH
  69. O/FsPyKBLiKJArizLYQc12aP3QOrYoYD9+fAzIIzew7A5C0aanZCGzkuFpO6TRlD
  70. Tb7ry9Gf0DfPpCgxraH8tOcmnqp/ka3hjqo/SRnnTk0IFrmmLdarJvjD46rKwBo4
  71. MjyAIR1mQ5j8GTlSFBmSgETOQ/EYvO3FPLmra1Fh7L+DvaVzTpqI9fG3TuyyY+Ri
  72. Fby4ycTOGSZOe5Fh8lqkX5Y47mCUJ3zHzOA1vUJy2eTlMRGpu47Eb1++Vm6EzPUP
  73. 2EF5aD+zwcssh+atZvQbwxpgVqVcyLt91RSkKkmZQslh0rnlTb68yxvUnD3zw7So
  74. o6TAf9UvwVMEvdLT9NnFd6hwi2jcNte/h538GJwXeBb8EkfpqLKpTKyicnOdkamZ
  75. 7E9zY8SHNRYMwB9coQ/W8NvufbCgkvOoLyMXk5edbXofXl3PhNGOlraWbghBnzf5
  76. r3rwjFsQOoZotA==
  77. -----END CERTIFICATE-----`
  78. caKey = `-----BEGIN RSA PRIVATE KEY-----
  79. MIIJKQIBAAKCAgEA4Tiho5xWAC15JRkMwfp3/TJwI2As7MY5dele5cmdr5bHAE+s
  80. RKqC+Ti88OJWCV5saoyax/1SCjxJlQMZMl169P1QYJskKjdG2sdv6RLWLMgwSNRR
  81. jxp/Bw9dHdiEb9MjLgu28Jro9peQkHcRHeMf5hM9WvlIJGrdzbC4hUehmqggcqgA
  82. RainBkYjf0SwuWxHeu4nMqkpAk5tcSTLCjHfEFHZ9Te0TIPG5YkWocQKyeLgu4lv
  83. uU+DD2W2lym+YVUtRMGs1Envk7p+N0DcGU26qfzZ2sF5ZXkqm7dBsGQB9pIxwc2Q
  84. 8T1dCIyP9OQCKVILdc5aVFf1cryQFHYzYNNZXFlIBims5VV5Mgfp8ESHQSue+v6n
  85. 6ykecLEyKt1F1Y/MWY/nWUSI8zdq83jdBAZVjo9MSthxVn57/06s/hQca65IpcTZ
  86. V2gX0a+eRlAVqaRbAhL3LaZebYsW3WHKoUOftwemuep3nL51TzlXZVL7Oz/ClGaE
  87. OsnGG9KFO6jh+W768qC0zLQICdE7v2Zex98sZteHCg9fGJHIaYoF0aJG5P3WI5oZ
  88. f2fy7UIYN9ADLFZiorCXAZEhCSU6mDoRViZ4RGR9GZxbDZ9KYn7O8M/KCR72bkQg
  89. 73TlMsk1zSXEw0MKLUjtsw6crZ0Jt8t3sRatHO3JrYHALMt9vZfyNCZp0IsCAwEA
  90. AQKCAgAV+ElERYbaI5VyufvVnFJCH75ypPoc6sVGLEq2jbFVJJcq/5qlZCC8oP1F
  91. Xj7YUR6wUiDzK1Hqb7EZ2SCHGjlZVrCVi+y+NYAy7UuMZ+r+mVSkdhmypPoJPUVv
  92. GOTqZ6VB46Cn3eSl0WknvoWr7bD555yPmEuiSc5zNy74yWEJTidEKAFGyknowcTK
  93. sG+w1tAuPLcUKQ44DGB+rgEkcHL7C5EAa7upzx0C3RmZFB+dTAVyJdkBMbFuOhTS
  94. sB7DLeTplR7/4mp9da7EQw51ZXC1DlZOEZt++4/desXsqATNAbva1OuzrLG7mMKe
  95. N/PCBh/aERQcsCvgUmaXqGQgqN1Jhw8kbXnjZnVd9iE7TAh7ki3VqNy1OMgTwOex
  96. bBYWaCqHuDYIxCjeW0qLJcn0cKQ13FVYrxgInf4Jp82SQht5b/zLL3IRZEyKcLJF
  97. kL6g1wlmTUTUX0z8eZzlM0ZCrqtExjgElMO/rV971nyNV5WU8Og3NmE8/slqMrmJ
  98. DlrQr9q0WJsDKj1IMe46EUM6ix7bbxC5NIfJ96dgdxZDn6ghjca6iZYqqUACvmUj
  99. cq08s3R4Ouw9/87kn11wwGBx2yDueCwrjKEGc0RKjweGbwu0nBxOrkJ8JXz6bAv7
  100. 1OKfYaX3afI9B8x4uaiuRs38oBQlg9uAYFfl4HNBPuQikGLmsQKCAQEA8VjFOsaz
  101. y6NMZzKXi7WZ48uu3ed5x3Kf6RyDr1WvQ1jkBMv9b6b8Gp1CRnPqviRBto9L8QAg
  102. bCXZTqnXzn//brskmW8IZgqjAlf89AWa53piucu9/hgidrHRZobs5gTqev28uJdc
  103. zcuw1g8c3nCpY9WeTjHODzX5NXYRLFpkazLfYa6c8Q9jZR4KKrpdM+66fxL0JlOd
  104. 7dN0oQtEqEAugsd3cwkZgvWhY4oM7FGErrZoDLy273ZdJzi/vU+dThyVzfD8Ab8u
  105. VxxuobVMT/S608zbe+uaiUdov5s96OkCl87403UNKJBH+6LNb3rjBBLE9NPN5ET9
  106. JLQMrYd+zj8jQwKCAQEA7uU5I9MOufo9bIgJqjY4Ie1+Ex9DZEMUYFAvGNCJCVcS
  107. mwOdGF8AWzIavTLACmEDJO7t/OrBdoo4L7IEsCNjgA3WiIwIMiWUVqveAGUMEXr6
  108. TRI5EolV6FTqqIP6AS+BAeBq7G1ELgsTrWNHh11rW3+3kBMuOCn77PUQ8WHwcq/r
  109. teZcZn4Ewcr6P7cBODgVvnBPhe/J8xHS0HFVCeS1CvaiNYgees5yA80Apo9IPjDJ
  110. YWawLjmH5wUBI5yDFVp067wjqJnoKPSoKwWkZXqUk+zgFXx5KT0gh/c5yh1frASp
  111. q6oaYnHEVC5qj2SpT1GFLonTcrQUXiSkiUudvNu1GQKCAQEAmko+5GFtRe0ihgLQ
  112. 4S76r6diJli6AKil1Fg3U1r6zZpBQ1PJtJxTJQyN9w5Z7q6tF/GqAesrzxevQdvQ
  113. rCImAPtA3ZofC2UXawMnIjWHHx6diNvYnV1+gtUQ4nO1dSOFZ5VZFcUmPiZO6boF
  114. oaryj3FcX+71JcJCjEvrlKhA9Es0hXUkvfMxfs5if4he1zlyHpTWYr4oA4egUugq
  115. P0mwskikc3VIyvEO+NyjgFxo72yLPkFSzemkidN8uKDyFqKtnlfGM7OuA2CY1WZa
  116. 3+67lXWshx9KzyJIs92iCYkU8EoPxtdYzyrV6efdX7x27v60zTOut5TnJJS6WiF6
  117. Do5MkwKCAQAxoR9IyP0DN/BwzqYrXU42Bi+t603F04W1KJNQNWpyrUspNwv41yus
  118. xnD1o0hwH41Wq+h3JZIBfV+E0RfWO9Pc84MBJQ5C1LnHc7cQH+3s575+Km3+4tcd
  119. CB8j2R8kBeloKWYtLdn/Mr/ownpGreqyvIq2/LUaZ+Z1aMgXTYB1YwS16mCBzmZQ
  120. mEl62RsAwe4KfSyYJ6OtwqMoOJMxFfliiLBULK4gVykqjvk2oQeiG+KKQJoTUFJi
  121. dRCyhD5bPkqR+qjxyt+HOqSBI4/uoROi05AOBqjpH1DVzk+MJKQOiX1yM0l98CKY
  122. Vng+x+vAla/0Zh+ucajVkgk4mKPxazdpAoIBAQC17vWk4KYJpF2RC3pKPcQ0PdiX
  123. bN35YNlvyhkYlSfDNdyH3aDrGiycUyW2mMXUgEDFsLRxHMTL+zPC6efqO6sTAJDY
  124. cBptsW4drW/qo8NTx3dNOisLkW+mGGJOR/w157hREFr29ymCVMYu/Z7fVWIeSpCq
  125. p3u8YX8WTljrxwSczlGjvpM7uJx3SfYRM4TUoy+8wU8bK74LywLa5f60bQY6Dye0
  126. Gqd9O6OoPfgcQlwjC5MiAofeqwPJvU0hQOPoehZyNLAmOCWXTYWaTP7lxO1r6+NE
  127. M3hGYqW3W8Ixua71OskCypBZg/HVlIP/lzjRzdx+VOB2hbWVth2Iup/Z1egW
  128. -----END RSA PRIVATE KEY-----`
  129. caCRL = `-----BEGIN X509 CRL-----
  130. MIICpzCBkAIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhDZXJ0QXV0aBcN
  131. MjEwMTAyMjEzNDA1WhcNMjMwMTAyMjEzNDA1WjAkMCICEQC+l04DbHWMyC3fG09k
  132. VXf+Fw0yMTAxMDIyMTM0MDVaoCMwITAfBgNVHSMEGDAWgBTtcgjQBq/80EySIvJc
  133. N8OTorgbzDANBgkqhkiG9w0BAQsFAAOCAgEAEJ7z+uNc8sqtxlOhSdTGDzX/xput
  134. E857kFQkSlMnU2whQ8c+XpYrBLA5vIZJNSSwohTpM4+zVBX/bJpmu3wqqaArRO9/
  135. YcW5mQk9Anvb4WjQW1cHmtNapMTzoC9AiYt/OWPfy+P6JCgCr4Hy6LgQyIRL6bM9
  136. VYTalolOm1qa4Y5cIeT7iHq/91mfaqo8/6MYRjLl8DOTROpmw8OS9bCXkzGKdCat
  137. AbAzwkQUSauyoCQ10rpX+Y64w9ng3g4Dr20aCqPf5osaqplEJ2HTK8ljDTidlslv
  138. 9anQj8ax3Su89vI8+hK+YbfVQwrThabgdSjQsn+veyx8GlP8WwHLAQ379KjZjWg+
  139. OlOSwBeU1vTdP0QcB8X5C2gVujAyuQekbaV86xzIBOj7vZdfHZ6ee30TZ2FKiMyg
  140. 7/N2OqW0w77ChsjB4MSHJCfuTgIeg62GzuZXLM+Q2Z9LBdtm4Byg+sm/P52adOEg
  141. gVb2Zf4KSvsAmA0PIBlu449/QXUFcMxzLFy7mwTeZj2B4Ln0Hm0szV9f9R8MwMtB
  142. SyLYxVH+mgqaR6Jkk22Q/yYyLPaELfafX5gp/AIXG8n0zxfVaTvK3auSgb1Q6ZLS
  143. 5QH9dSIsmZHlPq7GoSXmKpMdjUL8eaky/IMteioyXgsBiATzl5L2dsw6MTX3MDF0
  144. QbDK+MzhmbKfDxs=
  145. -----END X509 CRL-----`
  146. client1Crt = `-----BEGIN CERTIFICATE-----
  147. MIIEITCCAgmgAwIBAgIRAIppZHoj1hM80D7WzTEKLuAwDQYJKoZIhvcNAQELBQAw
  148. EzERMA8GA1UEAxMIQ2VydEF1dGgwHhcNMjEwMTAyMjEyMzEwWhcNMjIwNzAyMjEz
  149. MDUxWjASMRAwDgYDVQQDEwdjbGllbnQxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
  150. MIIBCgKCAQEAoKbYY9MdF2kF/nhBESIiZTdVYtA8XL9xrIZyDj9EnCiTxHiVbJtH
  151. XVwszqSl5TRrotPmnmAQcX3r8OCk+z+RQZ0QQj257P3kG6q4rNnOcWCS5xEd20jP
  152. yhQ3m+hMGfZsotNTQze1ochuQgLUN6IPyPxZkH22ia3jX4iu1eo/QxeLYHj1UHw4
  153. 3Cii9yE+j5kPUC21xmnrGKdUrB55NYLXHx6yTIqYR5znSOVB8oJi18/hwdZmH859
  154. DHhm0Hx1HrS+jbjI3+CMorZJ3WUyNf+CkiVLD3xYutPbxzEpwiqkG/XYzLH0habT
  155. cDcILo18n+o3jvem2KWBrDhyairjIDscwQIDAQABo3EwbzAOBgNVHQ8BAf8EBAMC
  156. A7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSJ5GIv
  157. zIrE4ZSQt2+CGblKTDswizAfBgNVHSMEGDAWgBTtcgjQBq/80EySIvJcN8OTorgb
  158. zDANBgkqhkiG9w0BAQsFAAOCAgEALh4f5GhvNYNou0Ab04iQBbLEdOu2RlbK1B5n
  159. K9P/umYenBHMY/z6HT3+6tpcHsDuqE8UVdq3f3Gh4S2Gu9m8PRitT+cJ3gdo9Plm
  160. 3rD4ufn/s6rGg3ppydXcedm17492tbccUDWOBZw3IO/ASVq13WPgT0/Kev7cPq0k
  161. sSdSNhVeXqx8Myc2/d+8GYyzbul2Kpfa7h9i24sK49E9ftnSmsIvngONo08eT1T0
  162. 3wAOyK2981LIsHaAWcneShKFLDB6LeXIT9oitOYhiykhFlBZ4M1GNlSNfhQ8IIQP
  163. xbqMNXCLkW4/BtLhGEEcg0QVso6Kudl9rzgTfQknrdF7pHp6rS46wYUjoSyIY6dl
  164. oLmnoAVJX36J3QPWelePI9e07X2wrTfiZWewwgw3KNRWjd6/zfPLe7GoqXnK1S2z
  165. PT8qMfCaTwKTtUkzXuTFvQ8bAo2My/mS8FOcpkt2oQWeOsADHAUX7fz5BCoa2DL3
  166. k/7Mh4gVT+JYZEoTwCFuYHgMWFWe98naqHi9lB4yR981p1QgXgxO7qBeipagKY1F
  167. LlH1iwXUqZ3MZnkNA+4e1Fglsw3sa/rC+L98HnznJ/YbTfQbCP6aQ1qcOymrjMud
  168. 7MrFwqZjtd/SK4Qx1VpK6jGEAtPgWBTUS3p9ayg6lqjMBjsmySWfvRsDQbq6P5Ct
  169. O/e3EH8=
  170. -----END CERTIFICATE-----`
  171. client1Key = `-----BEGIN RSA PRIVATE KEY-----
  172. MIIEpAIBAAKCAQEAoKbYY9MdF2kF/nhBESIiZTdVYtA8XL9xrIZyDj9EnCiTxHiV
  173. bJtHXVwszqSl5TRrotPmnmAQcX3r8OCk+z+RQZ0QQj257P3kG6q4rNnOcWCS5xEd
  174. 20jPyhQ3m+hMGfZsotNTQze1ochuQgLUN6IPyPxZkH22ia3jX4iu1eo/QxeLYHj1
  175. UHw43Cii9yE+j5kPUC21xmnrGKdUrB55NYLXHx6yTIqYR5znSOVB8oJi18/hwdZm
  176. H859DHhm0Hx1HrS+jbjI3+CMorZJ3WUyNf+CkiVLD3xYutPbxzEpwiqkG/XYzLH0
  177. habTcDcILo18n+o3jvem2KWBrDhyairjIDscwQIDAQABAoIBAEBSjVFqtbsp0byR
  178. aXvyrtLX1Ng7h++at2jca85Ihq//jyqbHTje8zPuNAKI6eNbmb0YGr5OuEa4pD9N
  179. ssDmMsKSoG/lRwwcm7h4InkSvBWpFShvMgUaohfHAHzsBYxfnh+TfULsi0y7c2n6
  180. t/2OZcOTRkkUDIITnXYiw93ibHHv2Mv2bBDu35kGrcK+c2dN5IL5ZjTjMRpbJTe2
  181. 44RBJbdTxHBVSgoGBnugF+s2aEma6Ehsj70oyfoVpM6Aed5kGge0A5zA1JO7WCn9
  182. Ay/DzlULRXHjJIoRWd2NKvx5n3FNppUc9vJh2plRHalRooZ2+MjSf8HmXlvG2Hpb
  183. ScvmWgECgYEA1G+A/2KnxWsr/7uWIJ7ClcGCiNLdk17Pv3DZ3G4qUsU2ITftfIbb
  184. tU0Q/b19na1IY8Pjy9ptP7t74/hF5kky97cf1FA8F+nMj/k4+wO8QDI8OJfzVzh9
  185. PwielA5vbE+xmvis5Hdp8/od1Yrc/rPSy2TKtPFhvsqXjqoUmOAjDP8CgYEAwZjH
  186. 9dt1sc2lx/rMxihlWEzQ3JPswKW9/LJAmbRBoSWF9FGNjbX7uhWtXRKJkzb8ZAwa
  187. 88azluNo2oftbDD/+jw8b2cDgaJHlLAkSD4O1D1RthW7/LKD15qZ/oFsRb13NV85
  188. ZNKtwslXGbfVNyGKUVFm7fVA8vBAOUey+LKDFj8CgYEAg8WWstOzVdYguMTXXuyb
  189. ruEV42FJaDyLiSirOvxq7GTAKuLSQUg1yMRBIeQEo2X1XU0JZE3dLodRVhuO4EXP
  190. g7Dn4X7Th9HSvgvNuIacowWGLWSz4Qp9RjhGhXhezUSx2nseY6le46PmFavJYYSR
  191. 4PBofMyt4PcyA6Cknh+KHmkCgYEAnTriG7ETE0a7v4DXUpB4TpCEiMCy5Xs2o8Z5
  192. ZNva+W+qLVUWq+MDAIyechqeFSvxK6gRM69LJ96lx+XhU58wJiFJzAhT9rK/g+jS
  193. bsHH9WOfu0xHkuHA5hgvvV2Le9B2wqgFyva4HJy82qxMxCu/VG/SMqyfBS9OWbb7
  194. ibQhdq0CgYAl53LUWZsFSZIth1vux2LVOsI8C3X1oiXDGpnrdlQ+K7z57hq5EsRq
  195. GC+INxwXbvKNqp5h0z2MvmKYPDlGVTgw8f8JjM7TkN17ERLcydhdRrMONUryZpo8
  196. 1xTob+8blyJgfxZUIAKbMbMbIiU0WAF0rfD/eJJwS4htOW/Hfv4TGA==
  197. -----END RSA PRIVATE KEY-----`
  198. // client 2 crt is revoked
  199. client2Crt = `-----BEGIN CERTIFICATE-----
  200. MIIEITCCAgmgAwIBAgIRAL6XTgNsdYzILd8bT2RVd/4wDQYJKoZIhvcNAQELBQAw
  201. EzERMA8GA1UEAxMIQ2VydEF1dGgwHhcNMjEwMTAyMjEyMzIwWhcNMjIwNzAyMjEz
  202. MDUxWjASMRAwDgYDVQQDEwdjbGllbnQyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
  203. MIIBCgKCAQEA6xjW5KQR3/OFQtV5M75WINqQ4AzXSu6DhSz/yumaaQZP/UxY+6hi
  204. jcrFzGo9MMie/Sza8DhkXOFAl2BelUubrOeB2cl+/Gr8OCyRi2Gv6j3zCsuN/4jQ
  205. tNaoez/IbkDvI3l/ZpzBtnuNY2RiemGgHuORXHRVf3qVlsw+npBIRW5rM2HkO/xG
  206. oZjeBErWVu390Lyn+Gvk2TqQDnkutWnxUC60/zPlHhXZ4BwaFAekbSnjsSDB1YFM
  207. s8HwW4oBryoxdj3/+/qLrBHt75IdLw3T7/V1UDJQM3EvSQOr12w4egpldhtsC871
  208. nnBQZeY6qA5feffIwwg/6lJm70o6S6OX6wIDAQABo3EwbzAOBgNVHQ8BAf8EBAMC
  209. A7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTB84v5
  210. t9HqhLhMODbn6oYkEQt3KzAfBgNVHSMEGDAWgBTtcgjQBq/80EySIvJcN8OTorgb
  211. zDANBgkqhkiG9w0BAQsFAAOCAgEALGtBCve5k8tToL3oLuXp/oSik6ovIB/zq4I/
  212. 4zNMYPU31+ZWz6aahysgx1JL1yqTa3Qm8o2tu52MbnV10dM7CIw7c/cYa+c+OPcG
  213. 5LF97kp13X+r2axy+CmwM86b4ILaDGs2Qyai6VB6k7oFUve+av5o7aUrNFpqGCJz
  214. HWdtHZSVA3JMATzy0TfWanwkzreqfdw7qH0yZ9bDURlBKAVWrqnCstva9jRuv+AI
  215. eqxr/4Ro986TFjJdoAP3Vr16CPg7/B6GA/KmsBWJrpeJdPWq4i2gpLKvYZoy89qD
  216. mUZf34RbzcCtV4NvV1DadGnt4us0nvLrvS5rL2+2uWD09kZYq9RbLkvgzF/cY0fz
  217. i7I1bi5XQ+alWe0uAk5ZZL/D+GTRYUX1AWwCqwJxmHrMxcskMyO9pXvLyuSWRDLo
  218. YNBrbX9nLcfJzVCp+X+9sntTHjs4l6Cw+fLepJIgtgqdCHtbhTiv68vSM6cgb4br
  219. 6n2xrXRKuioiWFOrTSRr+oalZh8dGJ/xvwY8IbWknZAvml9mf1VvfE7Ma5P777QM
  220. fsbYVTq0Y3R/5hIWsC3HA5z6MIM8L1oRe/YyhP3CTmrCHkVKyDOosGXpGz+JVcyo
  221. cfYkY5A3yFKB2HaCwZSfwFmRhxkrYWGEbHv3Cd9YkZs1J3hNhGFZyVMC9Uh0S85a
  222. 6zdDidU=
  223. -----END CERTIFICATE-----`
  224. client2Key = `-----BEGIN RSA PRIVATE KEY-----
  225. MIIEpAIBAAKCAQEA6xjW5KQR3/OFQtV5M75WINqQ4AzXSu6DhSz/yumaaQZP/UxY
  226. +6hijcrFzGo9MMie/Sza8DhkXOFAl2BelUubrOeB2cl+/Gr8OCyRi2Gv6j3zCsuN
  227. /4jQtNaoez/IbkDvI3l/ZpzBtnuNY2RiemGgHuORXHRVf3qVlsw+npBIRW5rM2Hk
  228. O/xGoZjeBErWVu390Lyn+Gvk2TqQDnkutWnxUC60/zPlHhXZ4BwaFAekbSnjsSDB
  229. 1YFMs8HwW4oBryoxdj3/+/qLrBHt75IdLw3T7/V1UDJQM3EvSQOr12w4egpldhts
  230. C871nnBQZeY6qA5feffIwwg/6lJm70o6S6OX6wIDAQABAoIBAFatstVb1KdQXsq0
  231. cFpui8zTKOUiduJOrDkWzTygAmlEhYtrccdfXu7OWz0x0lvBLDVGK3a0I/TGrAzj
  232. 4BuFY+FM/egxTVt9in6fmA3et4BS1OAfCryzUdfK6RV//8L+t+zJZ/qKQzWnugpy
  233. QYjDo8ifuMFwtvEoXizaIyBNLAhEp9hnrv+Tyi2O2gahPvCHsD48zkyZRCHYRstD
  234. NH5cIrwz9/RJgPO1KI+QsJE7Nh7stR0sbr+5TPU4fnsL2mNhMUF2TJrwIPrc1yp+
  235. YIUjdnh3SO88j4TQT3CIrWi8i4pOy6N0dcVn3gpCRGaqAKyS2ZYUj+yVtLO4KwxZ
  236. SZ1lNvECgYEA78BrF7f4ETfWSLcBQ3qxfLs7ibB6IYo2x25685FhZjD+zLXM1AKb
  237. FJHEXUm3mUYrFJK6AFEyOQnyGKBOLs3S6oTAswMPbTkkZeD1Y9O6uv0AHASLZnK6
  238. pC6ub0eSRF5LUyTQ55Jj8D7QsjXJueO8v+G5ihWhNSN9tB2UA+8NBmkCgYEA+weq
  239. cvoeMIEMBQHnNNLy35bwfqrceGyPIRBcUIvzQfY1vk7KW6DYOUzC7u+WUzy/hA52
  240. DjXVVhua2eMQ9qqtOav7djcMc2W9RbLowxvno7K5qiCss013MeWk64TCWy+WMp5A
  241. AVAtOliC3hMkIKqvR2poqn+IBTh1449agUJQqTMCgYEAu06IHGq1GraV6g9XpGF5
  242. wqoAlMzUTdnOfDabRilBf/YtSr+J++ThRcuwLvXFw7CnPZZ4TIEjDJ7xjj3HdxeE
  243. fYYjineMmNd40UNUU556F1ZLvJfsVKizmkuCKhwvcMx+asGrmA+tlmds4p3VMS50
  244. KzDtpKzLWlmU/p/RINWlRmkCgYBy0pHTn7aZZx2xWKqCDg+L2EXPGqZX6wgZDpu7
  245. OBifzlfM4ctL2CmvI/5yPmLbVgkgBWFYpKUdiujsyyEiQvWTUKhn7UwjqKDHtcsk
  246. G6p7xS+JswJrzX4885bZJ9Oi1AR2yM3sC9l0O7I4lDbNPmWIXBLeEhGMmcPKv/Kc
  247. 91Ff4wKBgQCF3ur+Vt0PSU0ucrPVHjCe7tqazm0LJaWbPXL1Aw0pzdM2EcNcW/MA
  248. w0kqpr7MgJ94qhXCBcVcfPuFN9fBOadM3UBj1B45Cz3pptoK+ScI8XKno6jvVK/p
  249. xr5cb9VBRBtB9aOKVfuRhpatAfS2Pzm2Htae9lFn7slGPUmu2hkjDw==
  250. -----END RSA PRIVATE KEY-----`
  251. )
  252. var (
  253. errWalkDir = errors.New("err walk dir")
  254. errWalkFile = errors.New("err walk file")
  255. )
  256. // MockOsFs mockable OsFs
  257. type MockOsFs struct {
  258. vfs.Fs
  259. err error
  260. isAtomicUploadSupported bool
  261. reader *pipeat.PipeReaderAt
  262. }
  263. // Name returns the name for the Fs implementation
  264. func (fs *MockOsFs) Name() string {
  265. return "mockOsFs"
  266. }
  267. // Open returns nil
  268. func (fs *MockOsFs) Open(name string, offset int64) (vfs.File, *pipeat.PipeReaderAt, func(), error) {
  269. return nil, fs.reader, nil, nil
  270. }
  271. // IsUploadResumeSupported returns true if upload resume is supported
  272. func (*MockOsFs) IsUploadResumeSupported() bool {
  273. return false
  274. }
  275. // IsAtomicUploadSupported returns true if atomic upload is supported
  276. func (fs *MockOsFs) IsAtomicUploadSupported() bool {
  277. return fs.isAtomicUploadSupported
  278. }
  279. // Remove removes the named file or (empty) directory.
  280. func (fs *MockOsFs) Remove(name string, isDir bool) error {
  281. if fs.err != nil {
  282. return fs.err
  283. }
  284. return os.Remove(name)
  285. }
  286. // Rename renames (moves) source to target
  287. func (fs *MockOsFs) Rename(source, target string) error {
  288. if fs.err != nil {
  289. return fs.err
  290. }
  291. return os.Rename(source, target)
  292. }
  293. // Walk returns a duplicate path for testing
  294. func (fs *MockOsFs) Walk(root string, walkFn filepath.WalkFunc) error {
  295. if fs.err == errWalkDir {
  296. walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
  297. walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
  298. return nil
  299. }
  300. walkFn("fsfpath", vfs.NewFileInfo("fpath", false, 0, time.Now(), false), nil) //nolint:errcheck
  301. return fs.err
  302. }
  303. // GetMimeType returns the content type
  304. func (fs *MockOsFs) GetMimeType(name string) (string, error) {
  305. return "application/custom-mime", nil
  306. }
  307. func newMockOsFs(err error, atomicUpload bool, connectionID, rootDir string, reader *pipeat.PipeReaderAt) vfs.Fs {
  308. return &MockOsFs{
  309. Fs: vfs.NewOsFs(connectionID, rootDir, nil),
  310. err: err,
  311. isAtomicUploadSupported: atomicUpload,
  312. reader: reader,
  313. }
  314. }
  315. func TestOrderDirsToRemove(t *testing.T) {
  316. user := dataprovider.User{}
  317. fs := vfs.NewOsFs("id", os.TempDir(), nil)
  318. connection := &Connection{
  319. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, user, fs),
  320. request: nil,
  321. }
  322. dirsToRemove := []objectMapping{}
  323. orderedDirs := connection.orderDirsToRemove(dirsToRemove)
  324. assert.Equal(t, len(dirsToRemove), len(orderedDirs))
  325. dirsToRemove = []objectMapping{
  326. {
  327. fsPath: "dir1",
  328. virtualPath: "",
  329. },
  330. }
  331. orderedDirs = connection.orderDirsToRemove(dirsToRemove)
  332. assert.Equal(t, len(dirsToRemove), len(orderedDirs))
  333. dirsToRemove = []objectMapping{
  334. {
  335. fsPath: "dir1",
  336. virtualPath: "",
  337. },
  338. {
  339. fsPath: "dir12",
  340. virtualPath: "",
  341. },
  342. {
  343. fsPath: filepath.Join("dir1", "a", "b"),
  344. virtualPath: "",
  345. },
  346. {
  347. fsPath: filepath.Join("dir1", "a"),
  348. virtualPath: "",
  349. },
  350. }
  351. orderedDirs = connection.orderDirsToRemove(dirsToRemove)
  352. if assert.Equal(t, len(dirsToRemove), len(orderedDirs)) {
  353. assert.Equal(t, "dir12", orderedDirs[0].fsPath)
  354. assert.Equal(t, filepath.Join("dir1", "a", "b"), orderedDirs[1].fsPath)
  355. assert.Equal(t, filepath.Join("dir1", "a"), orderedDirs[2].fsPath)
  356. assert.Equal(t, "dir1", orderedDirs[3].fsPath)
  357. }
  358. }
  359. func TestUserInvalidParams(t *testing.T) {
  360. u := &dataprovider.User{
  361. Username: "username",
  362. HomeDir: "invalid",
  363. }
  364. c := &Configuration{
  365. Bindings: []Binding{
  366. {
  367. Port: 9000,
  368. },
  369. },
  370. }
  371. server := webDavServer{
  372. config: c,
  373. binding: c.Bindings[0],
  374. }
  375. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", u.Username), nil)
  376. assert.NoError(t, err)
  377. _, err = server.validateUser(u, req)
  378. if assert.Error(t, err) {
  379. assert.EqualError(t, err, fmt.Sprintf("cannot login user with invalid home dir: %#v", u.HomeDir))
  380. }
  381. u.HomeDir = filepath.Clean(os.TempDir())
  382. subDir := "subdir"
  383. mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
  384. vdirPath1 := "/vdir1"
  385. mappedPath2 := filepath.Join(os.TempDir(), "vdir1", subDir)
  386. vdirPath2 := "/vdir2"
  387. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  388. BaseVirtualFolder: vfs.BaseVirtualFolder{
  389. MappedPath: mappedPath1,
  390. },
  391. VirtualPath: vdirPath1,
  392. })
  393. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  394. BaseVirtualFolder: vfs.BaseVirtualFolder{
  395. MappedPath: mappedPath2,
  396. },
  397. VirtualPath: vdirPath2,
  398. })
  399. _, err = server.validateUser(u, req)
  400. if assert.Error(t, err) {
  401. assert.EqualError(t, err, "overlapping mapped folders are allowed only with quota tracking disabled")
  402. }
  403. req.TLS = &tls.ConnectionState{}
  404. writeLog(req, nil)
  405. }
  406. func TestRemoteAddress(t *testing.T) {
  407. req, err := http.NewRequest(http.MethodGet, "/username", nil)
  408. assert.NoError(t, err)
  409. assert.Empty(t, req.RemoteAddr)
  410. remoteAddr1 := "100.100.100.100"
  411. remoteAddr2 := "172.172.172.172"
  412. req.Header.Set("X-Forwarded-For", remoteAddr1)
  413. checkRemoteAddress(req)
  414. assert.Equal(t, remoteAddr1, req.RemoteAddr)
  415. req.RemoteAddr = ""
  416. req.Header.Set("X-Forwarded-For", fmt.Sprintf("%v, %v", remoteAddr2, remoteAddr1))
  417. checkRemoteAddress(req)
  418. assert.Equal(t, remoteAddr2, req.RemoteAddr)
  419. req.Header.Del("X-Forwarded-For")
  420. req.RemoteAddr = ""
  421. req.Header.Set("X-Real-IP", remoteAddr1)
  422. checkRemoteAddress(req)
  423. assert.Equal(t, remoteAddr1, req.RemoteAddr)
  424. req.RemoteAddr = ""
  425. oldValue := common.Config.ProxyProtocol
  426. common.Config.ProxyProtocol = 1
  427. checkRemoteAddress(req)
  428. assert.Empty(t, req.RemoteAddr)
  429. common.Config.ProxyProtocol = oldValue
  430. }
  431. func TestConnWithNilRequest(t *testing.T) {
  432. c := &Connection{}
  433. assert.Empty(t, c.GetClientVersion())
  434. assert.Empty(t, c.GetCommand())
  435. assert.Empty(t, c.GetRemoteAddress())
  436. }
  437. func TestResolvePathErrors(t *testing.T) {
  438. ctx := context.Background()
  439. user := dataprovider.User{
  440. HomeDir: "invalid",
  441. }
  442. user.Permissions = make(map[string][]string)
  443. user.Permissions["/"] = []string{dataprovider.PermAny}
  444. fs := vfs.NewOsFs("connID", user.HomeDir, nil)
  445. connection := &Connection{
  446. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, user, fs),
  447. }
  448. err := connection.Mkdir(ctx, "", os.ModePerm)
  449. if assert.Error(t, err) {
  450. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  451. }
  452. err = connection.Rename(ctx, "oldName", "newName")
  453. if assert.Error(t, err) {
  454. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  455. }
  456. _, err = connection.Stat(ctx, "name")
  457. if assert.Error(t, err) {
  458. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  459. }
  460. err = connection.RemoveAll(ctx, "")
  461. if assert.Error(t, err) {
  462. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  463. }
  464. _, err = connection.OpenFile(ctx, "", 0, os.ModePerm)
  465. if assert.Error(t, err) {
  466. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  467. }
  468. if runtime.GOOS != "windows" {
  469. connection.User.HomeDir = filepath.Clean(os.TempDir())
  470. connection.Fs = vfs.NewOsFs("connID", connection.User.HomeDir, nil)
  471. subDir := "sub"
  472. testTxtFile := "file.txt"
  473. err = os.MkdirAll(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  474. assert.NoError(t, err)
  475. err = os.WriteFile(filepath.Join(os.TempDir(), subDir, subDir, testTxtFile), []byte("content"), os.ModePerm)
  476. assert.NoError(t, err)
  477. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), 0001)
  478. assert.NoError(t, err)
  479. err = connection.Rename(ctx, testTxtFile, path.Join(subDir, subDir, testTxtFile))
  480. if assert.Error(t, err) {
  481. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  482. }
  483. _, err = connection.putFile(filepath.Join(connection.User.HomeDir, subDir, subDir, testTxtFile),
  484. path.Join(subDir, subDir, testTxtFile))
  485. if assert.Error(t, err) {
  486. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  487. }
  488. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  489. assert.NoError(t, err)
  490. err = os.RemoveAll(filepath.Join(os.TempDir(), subDir))
  491. assert.NoError(t, err)
  492. }
  493. }
  494. func TestFileAccessErrors(t *testing.T) {
  495. ctx := context.Background()
  496. user := dataprovider.User{
  497. HomeDir: filepath.Clean(os.TempDir()),
  498. }
  499. user.Permissions = make(map[string][]string)
  500. user.Permissions["/"] = []string{dataprovider.PermAny}
  501. fs := vfs.NewOsFs("connID", user.HomeDir, nil)
  502. connection := &Connection{
  503. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, user, fs),
  504. }
  505. missingPath := "missing path"
  506. fsMissingPath := filepath.Join(user.HomeDir, missingPath)
  507. err := connection.RemoveAll(ctx, missingPath)
  508. if assert.Error(t, err) {
  509. assert.EqualError(t, err, os.ErrNotExist.Error())
  510. }
  511. _, err = connection.getFile(fsMissingPath, missingPath)
  512. if assert.Error(t, err) {
  513. assert.EqualError(t, err, os.ErrNotExist.Error())
  514. }
  515. _, err = connection.getFile(fsMissingPath, missingPath)
  516. if assert.Error(t, err) {
  517. assert.EqualError(t, err, os.ErrNotExist.Error())
  518. }
  519. p := filepath.Join(user.HomeDir, "adir", missingPath)
  520. _, err = connection.handleUploadToNewFile(p, p, path.Join("adir", missingPath))
  521. if assert.Error(t, err) {
  522. assert.EqualError(t, err, os.ErrNotExist.Error())
  523. }
  524. _, err = connection.handleUploadToExistingFile(p, p, 0, path.Join("adir", missingPath))
  525. if assert.Error(t, err) {
  526. assert.EqualError(t, err, os.ErrNotExist.Error())
  527. }
  528. connection.Fs = newMockOsFs(nil, false, fs.ConnectionID(), user.HomeDir, nil)
  529. _, err = connection.handleUploadToExistingFile(p, p, 0, path.Join("adir", missingPath))
  530. if assert.Error(t, err) {
  531. assert.EqualError(t, err, os.ErrNotExist.Error())
  532. }
  533. f, err := os.CreateTemp("", "temp")
  534. assert.NoError(t, err)
  535. err = f.Close()
  536. assert.NoError(t, err)
  537. davFile, err := connection.handleUploadToExistingFile(f.Name(), f.Name(), 123, f.Name())
  538. if assert.NoError(t, err) {
  539. transfer := davFile.(*webDavFile)
  540. transfers := connection.GetTransfers()
  541. if assert.Equal(t, 1, len(transfers)) {
  542. assert.Equal(t, transfers[0].ID, transfer.GetID())
  543. assert.Equal(t, int64(123), transfer.InitialSize)
  544. err = transfer.Close()
  545. assert.NoError(t, err)
  546. assert.Equal(t, 0, len(connection.GetTransfers()))
  547. }
  548. }
  549. err = os.Remove(f.Name())
  550. assert.NoError(t, err)
  551. }
  552. func TestRemoveDirTree(t *testing.T) {
  553. user := dataprovider.User{
  554. HomeDir: filepath.Clean(os.TempDir()),
  555. }
  556. user.Permissions = make(map[string][]string)
  557. user.Permissions["/"] = []string{dataprovider.PermAny}
  558. fs := vfs.NewOsFs("connID", user.HomeDir, nil)
  559. connection := &Connection{
  560. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, user, fs),
  561. }
  562. vpath := path.Join("adir", "missing")
  563. p := filepath.Join(user.HomeDir, "adir", "missing")
  564. err := connection.removeDirTree(p, vpath)
  565. if assert.Error(t, err) {
  566. assert.True(t, os.IsNotExist(err))
  567. }
  568. connection.Fs = newMockOsFs(nil, false, "mockID", user.HomeDir, nil)
  569. err = connection.removeDirTree(p, vpath)
  570. if assert.Error(t, err) {
  571. assert.True(t, os.IsNotExist(err))
  572. }
  573. errFake := errors.New("fake err")
  574. connection.Fs = newMockOsFs(errFake, false, "mockID", user.HomeDir, nil)
  575. err = connection.removeDirTree(p, vpath)
  576. if assert.Error(t, err) {
  577. assert.EqualError(t, err, errFake.Error())
  578. }
  579. connection.Fs = newMockOsFs(errWalkDir, true, "mockID", user.HomeDir, nil)
  580. err = connection.removeDirTree(p, vpath)
  581. if assert.Error(t, err) {
  582. assert.True(t, os.IsNotExist(err))
  583. }
  584. connection.Fs = newMockOsFs(errWalkFile, false, "mockID", user.HomeDir, nil)
  585. err = connection.removeDirTree(p, vpath)
  586. if assert.Error(t, err) {
  587. assert.EqualError(t, err, errWalkFile.Error())
  588. }
  589. connection.User.Permissions["/"] = []string{dataprovider.PermListItems}
  590. connection.Fs = newMockOsFs(nil, false, "mockID", user.HomeDir, nil)
  591. err = connection.removeDirTree(p, vpath)
  592. if assert.Error(t, err) {
  593. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  594. }
  595. }
  596. func TestContentType(t *testing.T) {
  597. user := dataprovider.User{
  598. HomeDir: filepath.Clean(os.TempDir()),
  599. }
  600. user.Permissions = make(map[string][]string)
  601. user.Permissions["/"] = []string{dataprovider.PermAny}
  602. fs := vfs.NewOsFs("connID", user.HomeDir, nil)
  603. connection := &Connection{
  604. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, user, fs),
  605. }
  606. testFilePath := filepath.Join(user.HomeDir, testFile)
  607. ctx := context.Background()
  608. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  609. common.TransferDownload, 0, 0, 0, false, fs)
  610. fs = newMockOsFs(nil, false, fs.ConnectionID(), user.GetHomeDir(), nil)
  611. err := os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  612. assert.NoError(t, err)
  613. davFile := newWebDavFile(baseTransfer, nil, nil)
  614. davFile.Fs = fs
  615. fi, err := davFile.Stat()
  616. if assert.NoError(t, err) {
  617. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  618. assert.NoError(t, err)
  619. assert.Equal(t, "application/custom-mime", ctype)
  620. }
  621. _, err = davFile.Readdir(-1)
  622. assert.Error(t, err)
  623. err = davFile.Close()
  624. assert.NoError(t, err)
  625. davFile = newWebDavFile(baseTransfer, nil, nil)
  626. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, nil)
  627. fi, err = davFile.Stat()
  628. if assert.NoError(t, err) {
  629. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  630. assert.NoError(t, err)
  631. assert.Equal(t, "text/plain; charset=utf-8", ctype)
  632. }
  633. err = davFile.Close()
  634. assert.NoError(t, err)
  635. fi.(*webDavFileInfo).fsPath = "missing"
  636. _, err = fi.(*webDavFileInfo).ContentType(ctx)
  637. assert.EqualError(t, err, webdav.ErrNotImplemented.Error())
  638. err = os.Remove(testFilePath)
  639. assert.NoError(t, err)
  640. }
  641. func TestTransferReadWriteErrors(t *testing.T) {
  642. user := dataprovider.User{
  643. HomeDir: filepath.Clean(os.TempDir()),
  644. }
  645. user.Permissions = make(map[string][]string)
  646. user.Permissions["/"] = []string{dataprovider.PermAny}
  647. fs := vfs.NewOsFs("connID", user.HomeDir, nil)
  648. connection := &Connection{
  649. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, user, fs),
  650. }
  651. testFilePath := filepath.Join(user.HomeDir, testFile)
  652. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  653. common.TransferUpload, 0, 0, 0, false, fs)
  654. davFile := newWebDavFile(baseTransfer, nil, nil)
  655. p := make([]byte, 1)
  656. _, err := davFile.Read(p)
  657. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  658. r, w, err := pipeat.Pipe()
  659. assert.NoError(t, err)
  660. davFile = newWebDavFile(baseTransfer, nil, r)
  661. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  662. davFile = newWebDavFile(baseTransfer, vfs.NewPipeWriter(w), nil)
  663. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  664. err = r.Close()
  665. assert.NoError(t, err)
  666. err = w.Close()
  667. assert.NoError(t, err)
  668. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  669. common.TransferDownload, 0, 0, 0, false, fs)
  670. davFile = newWebDavFile(baseTransfer, nil, nil)
  671. _, err = davFile.Read(p)
  672. assert.True(t, os.IsNotExist(err))
  673. _, err = davFile.Stat()
  674. assert.True(t, os.IsNotExist(err))
  675. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  676. common.TransferDownload, 0, 0, 0, false, fs)
  677. err = os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  678. assert.NoError(t, err)
  679. f, err := os.Open(testFilePath)
  680. if assert.NoError(t, err) {
  681. err = f.Close()
  682. assert.NoError(t, err)
  683. }
  684. davFile = newWebDavFile(baseTransfer, nil, nil)
  685. davFile.reader = f
  686. err = davFile.Close()
  687. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  688. err = davFile.Close()
  689. assert.EqualError(t, err, common.ErrTransferClosed.Error())
  690. _, err = davFile.Read(p)
  691. assert.Error(t, err)
  692. info, err := davFile.Stat()
  693. if assert.NoError(t, err) {
  694. assert.Equal(t, int64(0), info.Size())
  695. }
  696. r, w, err = pipeat.Pipe()
  697. assert.NoError(t, err)
  698. mockFs := newMockOsFs(nil, false, fs.ConnectionID(), user.HomeDir, r)
  699. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  700. common.TransferDownload, 0, 0, 0, false, mockFs)
  701. davFile = newWebDavFile(baseTransfer, nil, nil)
  702. writeContent := []byte("content\r\n")
  703. go func() {
  704. n, err := w.Write(writeContent)
  705. assert.NoError(t, err)
  706. assert.Equal(t, len(writeContent), n)
  707. err = w.Close()
  708. assert.NoError(t, err)
  709. }()
  710. p = make([]byte, 64)
  711. n, err := davFile.Read(p)
  712. assert.EqualError(t, err, io.EOF.Error())
  713. assert.Equal(t, len(writeContent), n)
  714. err = davFile.Close()
  715. assert.NoError(t, err)
  716. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  717. common.TransferDownload, 0, 0, 0, false, fs)
  718. davFile = newWebDavFile(baseTransfer, nil, nil)
  719. davFile.writer = f
  720. err = davFile.Close()
  721. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  722. err = os.Remove(testFilePath)
  723. assert.NoError(t, err)
  724. }
  725. func TestTransferSeek(t *testing.T) {
  726. user := dataprovider.User{
  727. HomeDir: filepath.Clean(os.TempDir()),
  728. }
  729. user.Permissions = make(map[string][]string)
  730. user.Permissions["/"] = []string{dataprovider.PermAny}
  731. fs := vfs.NewOsFs("connID", user.HomeDir, nil)
  732. connection := &Connection{
  733. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, user, fs),
  734. }
  735. testFilePath := filepath.Join(user.HomeDir, testFile)
  736. testFileContents := []byte("content")
  737. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  738. common.TransferUpload, 0, 0, 0, false, fs)
  739. davFile := newWebDavFile(baseTransfer, nil, nil)
  740. _, err := davFile.Seek(0, io.SeekStart)
  741. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  742. err = davFile.Close()
  743. assert.NoError(t, err)
  744. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  745. common.TransferDownload, 0, 0, 0, false, fs)
  746. davFile = newWebDavFile(baseTransfer, nil, nil)
  747. _, err = davFile.Seek(0, io.SeekCurrent)
  748. assert.True(t, os.IsNotExist(err))
  749. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  750. err = os.WriteFile(testFilePath, testFileContents, os.ModePerm)
  751. assert.NoError(t, err)
  752. f, err := os.Open(testFilePath)
  753. if assert.NoError(t, err) {
  754. err = f.Close()
  755. assert.NoError(t, err)
  756. }
  757. baseTransfer = common.NewBaseTransfer(f, connection.BaseConnection, nil, testFilePath, testFile,
  758. common.TransferDownload, 0, 0, 0, false, fs)
  759. davFile = newWebDavFile(baseTransfer, nil, nil)
  760. _, err = davFile.Seek(0, io.SeekStart)
  761. assert.Error(t, err)
  762. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  763. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  764. common.TransferDownload, 0, 0, 0, false, fs)
  765. davFile = newWebDavFile(baseTransfer, nil, nil)
  766. res, err := davFile.Seek(0, io.SeekStart)
  767. assert.NoError(t, err)
  768. assert.Equal(t, int64(0), res)
  769. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  770. davFile = newWebDavFile(baseTransfer, nil, nil)
  771. res, err = davFile.Seek(0, io.SeekEnd)
  772. assert.NoError(t, err)
  773. assert.Equal(t, int64(len(testFileContents)), res)
  774. err = davFile.updateStatInfo()
  775. assert.Nil(t, err)
  776. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFile,
  777. common.TransferDownload, 0, 0, 0, false, fs)
  778. davFile = newWebDavFile(baseTransfer, nil, nil)
  779. _, err = davFile.Seek(0, io.SeekEnd)
  780. assert.True(t, os.IsNotExist(err))
  781. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  782. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
  783. common.TransferDownload, 0, 0, 0, false, fs)
  784. davFile = newWebDavFile(baseTransfer, nil, nil)
  785. davFile.reader = f
  786. davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
  787. res, err = davFile.Seek(2, io.SeekStart)
  788. assert.NoError(t, err)
  789. assert.Equal(t, int64(2), res)
  790. davFile = newWebDavFile(baseTransfer, nil, nil)
  791. davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
  792. res, err = davFile.Seek(2, io.SeekEnd)
  793. assert.NoError(t, err)
  794. assert.Equal(t, int64(5), res)
  795. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFile,
  796. common.TransferDownload, 0, 0, 0, false, fs)
  797. davFile = newWebDavFile(baseTransfer, nil, nil)
  798. davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
  799. res, err = davFile.Seek(2, io.SeekEnd)
  800. assert.True(t, os.IsNotExist(err))
  801. assert.Equal(t, int64(0), res)
  802. assert.Len(t, common.Connections.GetStats(), 0)
  803. err = os.Remove(testFilePath)
  804. assert.NoError(t, err)
  805. }
  806. func TestBasicUsersCache(t *testing.T) {
  807. username := "webdav_internal_test"
  808. password := "pwd"
  809. u := dataprovider.User{
  810. Username: username,
  811. Password: password,
  812. HomeDir: filepath.Join(os.TempDir(), username),
  813. Status: 1,
  814. ExpirationDate: 0,
  815. }
  816. u.Permissions = make(map[string][]string)
  817. u.Permissions["/"] = []string{dataprovider.PermAny}
  818. err := dataprovider.AddUser(&u)
  819. assert.NoError(t, err)
  820. user, err := dataprovider.UserExists(u.Username)
  821. assert.NoError(t, err)
  822. c := &Configuration{
  823. Bindings: []Binding{
  824. {
  825. Port: 9000,
  826. },
  827. },
  828. Cache: Cache{
  829. Users: UsersCacheConfig{
  830. MaxSize: 50,
  831. ExpirationTime: 1,
  832. },
  833. },
  834. }
  835. server := webDavServer{
  836. config: c,
  837. binding: c.Bindings[0],
  838. }
  839. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user.Username), nil)
  840. assert.NoError(t, err)
  841. ipAddr := "127.0.0.1"
  842. _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  843. assert.Error(t, err)
  844. now := time.Now()
  845. req.SetBasicAuth(username, password)
  846. _, isCached, _, err := server.authenticate(req, ipAddr)
  847. assert.NoError(t, err)
  848. assert.False(t, isCached)
  849. // now the user should be cached
  850. var cachedUser *dataprovider.CachedUser
  851. result, ok := dataprovider.GetCachedWebDAVUser(username)
  852. if assert.True(t, ok) {
  853. cachedUser = result.(*dataprovider.CachedUser)
  854. assert.False(t, cachedUser.IsExpired())
  855. assert.True(t, cachedUser.Expiration.After(now.Add(time.Duration(c.Cache.Users.ExpirationTime)*time.Minute)))
  856. // authenticate must return the cached user now
  857. authUser, isCached, _, err := server.authenticate(req, ipAddr)
  858. assert.NoError(t, err)
  859. assert.True(t, isCached)
  860. assert.Equal(t, cachedUser.User, authUser)
  861. }
  862. // a wrong password must fail
  863. req.SetBasicAuth(username, "wrong")
  864. _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  865. assert.EqualError(t, err, dataprovider.ErrInvalidCredentials.Error())
  866. req.SetBasicAuth(username, password)
  867. // force cached user expiration
  868. cachedUser.Expiration = now
  869. dataprovider.CacheWebDAVUser(cachedUser, c.Cache.Users.MaxSize)
  870. result, ok = dataprovider.GetCachedWebDAVUser(username)
  871. if assert.True(t, ok) {
  872. cachedUser = result.(*dataprovider.CachedUser)
  873. assert.True(t, cachedUser.IsExpired())
  874. }
  875. // now authenticate should get the user from the data provider and update the cache
  876. _, isCached, _, err = server.authenticate(req, ipAddr)
  877. assert.NoError(t, err)
  878. assert.False(t, isCached)
  879. result, ok = dataprovider.GetCachedWebDAVUser(username)
  880. if assert.True(t, ok) {
  881. cachedUser = result.(*dataprovider.CachedUser)
  882. assert.False(t, cachedUser.IsExpired())
  883. }
  884. // cache is invalidated after a user modification
  885. err = dataprovider.UpdateUser(&user)
  886. assert.NoError(t, err)
  887. _, ok = dataprovider.GetCachedWebDAVUser(username)
  888. assert.False(t, ok)
  889. _, isCached, _, err = server.authenticate(req, ipAddr)
  890. assert.NoError(t, err)
  891. assert.False(t, isCached)
  892. _, ok = dataprovider.GetCachedWebDAVUser(username)
  893. assert.True(t, ok)
  894. // cache is invalidated after user deletion
  895. err = dataprovider.DeleteUser(user.Username)
  896. assert.NoError(t, err)
  897. _, ok = dataprovider.GetCachedWebDAVUser(username)
  898. assert.False(t, ok)
  899. err = os.RemoveAll(u.GetHomeDir())
  900. assert.NoError(t, err)
  901. }
  902. func TestUsersCacheSizeAndExpiration(t *testing.T) {
  903. username := "webdav_internal_test"
  904. password := "pwd"
  905. u := dataprovider.User{
  906. HomeDir: filepath.Join(os.TempDir(), username),
  907. Status: 1,
  908. ExpirationDate: 0,
  909. }
  910. u.Username = username + "1"
  911. u.Password = password + "1"
  912. u.Permissions = make(map[string][]string)
  913. u.Permissions["/"] = []string{dataprovider.PermAny}
  914. err := dataprovider.AddUser(&u)
  915. assert.NoError(t, err)
  916. user1, err := dataprovider.UserExists(u.Username)
  917. assert.NoError(t, err)
  918. u.Username = username + "2"
  919. u.Password = password + "2"
  920. err = dataprovider.AddUser(&u)
  921. assert.NoError(t, err)
  922. user2, err := dataprovider.UserExists(u.Username)
  923. assert.NoError(t, err)
  924. u.Username = username + "3"
  925. u.Password = password + "3"
  926. err = dataprovider.AddUser(&u)
  927. assert.NoError(t, err)
  928. user3, err := dataprovider.UserExists(u.Username)
  929. assert.NoError(t, err)
  930. u.Username = username + "4"
  931. u.Password = password + "4"
  932. err = dataprovider.AddUser(&u)
  933. assert.NoError(t, err)
  934. user4, err := dataprovider.UserExists(u.Username)
  935. assert.NoError(t, err)
  936. c := &Configuration{
  937. Bindings: []Binding{
  938. {
  939. Port: 9000,
  940. },
  941. },
  942. Cache: Cache{
  943. Users: UsersCacheConfig{
  944. MaxSize: 3,
  945. ExpirationTime: 1,
  946. },
  947. },
  948. }
  949. server := webDavServer{
  950. config: c,
  951. binding: c.Bindings[0],
  952. }
  953. ipAddr := "127.0.1.1"
  954. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  955. assert.NoError(t, err)
  956. req.SetBasicAuth(user1.Username, password+"1")
  957. _, isCached, _, err := server.authenticate(req, ipAddr)
  958. assert.NoError(t, err)
  959. assert.False(t, isCached)
  960. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  961. assert.NoError(t, err)
  962. req.SetBasicAuth(user2.Username, password+"2")
  963. _, isCached, _, err = server.authenticate(req, ipAddr)
  964. assert.NoError(t, err)
  965. assert.False(t, isCached)
  966. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  967. assert.NoError(t, err)
  968. req.SetBasicAuth(user3.Username, password+"3")
  969. _, isCached, _, err = server.authenticate(req, ipAddr)
  970. assert.NoError(t, err)
  971. assert.False(t, isCached)
  972. // the first 3 users are now cached
  973. _, ok := dataprovider.GetCachedWebDAVUser(user1.Username)
  974. assert.True(t, ok)
  975. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  976. assert.True(t, ok)
  977. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  978. assert.True(t, ok)
  979. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  980. assert.NoError(t, err)
  981. req.SetBasicAuth(user4.Username, password+"4")
  982. _, isCached, _, err = server.authenticate(req, ipAddr)
  983. assert.NoError(t, err)
  984. assert.False(t, isCached)
  985. // user1, the first cached, should be removed now
  986. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  987. assert.False(t, ok)
  988. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  989. assert.True(t, ok)
  990. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  991. assert.True(t, ok)
  992. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  993. assert.True(t, ok)
  994. // user1 logins, user2 should be removed
  995. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  996. assert.NoError(t, err)
  997. req.SetBasicAuth(user1.Username, password+"1")
  998. _, isCached, _, err = server.authenticate(req, ipAddr)
  999. assert.NoError(t, err)
  1000. assert.False(t, isCached)
  1001. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1002. assert.False(t, ok)
  1003. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1004. assert.True(t, ok)
  1005. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1006. assert.True(t, ok)
  1007. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1008. assert.True(t, ok)
  1009. // user2 logins, user3 should be removed
  1010. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  1011. assert.NoError(t, err)
  1012. req.SetBasicAuth(user2.Username, password+"2")
  1013. _, isCached, _, err = server.authenticate(req, ipAddr)
  1014. assert.NoError(t, err)
  1015. assert.False(t, isCached)
  1016. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1017. assert.False(t, ok)
  1018. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1019. assert.True(t, ok)
  1020. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1021. assert.True(t, ok)
  1022. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1023. assert.True(t, ok)
  1024. // user3 logins, user4 should be removed
  1025. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  1026. assert.NoError(t, err)
  1027. req.SetBasicAuth(user3.Username, password+"3")
  1028. _, isCached, _, err = server.authenticate(req, ipAddr)
  1029. assert.NoError(t, err)
  1030. assert.False(t, isCached)
  1031. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1032. assert.False(t, ok)
  1033. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1034. assert.True(t, ok)
  1035. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1036. assert.True(t, ok)
  1037. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1038. assert.True(t, ok)
  1039. // now remove user1 after an update
  1040. err = dataprovider.UpdateUser(&user1)
  1041. assert.NoError(t, err)
  1042. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1043. assert.False(t, ok)
  1044. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  1045. assert.NoError(t, err)
  1046. req.SetBasicAuth(user4.Username, password+"4")
  1047. _, isCached, _, err = server.authenticate(req, ipAddr)
  1048. assert.NoError(t, err)
  1049. assert.False(t, isCached)
  1050. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1051. assert.NoError(t, err)
  1052. req.SetBasicAuth(user1.Username, password+"1")
  1053. _, isCached, _, err = server.authenticate(req, ipAddr)
  1054. assert.NoError(t, err)
  1055. assert.False(t, isCached)
  1056. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1057. assert.False(t, ok)
  1058. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1059. assert.True(t, ok)
  1060. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1061. assert.True(t, ok)
  1062. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1063. assert.True(t, ok)
  1064. err = dataprovider.DeleteUser(user1.Username)
  1065. assert.NoError(t, err)
  1066. err = dataprovider.DeleteUser(user2.Username)
  1067. assert.NoError(t, err)
  1068. err = dataprovider.DeleteUser(user3.Username)
  1069. assert.NoError(t, err)
  1070. err = dataprovider.DeleteUser(user4.Username)
  1071. assert.NoError(t, err)
  1072. err = os.RemoveAll(u.GetHomeDir())
  1073. assert.NoError(t, err)
  1074. }
  1075. func TestRecoverer(t *testing.T) {
  1076. c := &Configuration{
  1077. Bindings: []Binding{
  1078. {
  1079. Port: 9000,
  1080. },
  1081. },
  1082. }
  1083. server := webDavServer{
  1084. config: c,
  1085. binding: c.Bindings[0],
  1086. }
  1087. rr := httptest.NewRecorder()
  1088. server.ServeHTTP(rr, nil)
  1089. assert.Equal(t, http.StatusInternalServerError, rr.Code)
  1090. }
  1091. func TestMimeCache(t *testing.T) {
  1092. cache := mimeCache{
  1093. maxSize: 0,
  1094. mimeTypes: make(map[string]string),
  1095. }
  1096. cache.addMimeToCache(".zip", "application/zip")
  1097. mtype := cache.getMimeFromCache(".zip")
  1098. assert.Equal(t, "", mtype)
  1099. cache.maxSize = 1
  1100. cache.addMimeToCache(".zip", "application/zip")
  1101. mtype = cache.getMimeFromCache(".zip")
  1102. assert.Equal(t, "application/zip", mtype)
  1103. cache.addMimeToCache(".jpg", "image/jpeg")
  1104. mtype = cache.getMimeFromCache(".jpg")
  1105. assert.Equal(t, "", mtype)
  1106. }
  1107. func TestVerifyTLSConnection(t *testing.T) {
  1108. oldCertMgr := certMgr
  1109. caCrlPath := filepath.Join(os.TempDir(), "testcrl.crt")
  1110. certPath := filepath.Join(os.TempDir(), "test.crt")
  1111. keyPath := filepath.Join(os.TempDir(), "test.key")
  1112. err := os.WriteFile(caCrlPath, []byte(caCRL), os.ModePerm)
  1113. assert.NoError(t, err)
  1114. err = os.WriteFile(certPath, []byte(webDavCert), os.ModePerm)
  1115. assert.NoError(t, err)
  1116. err = os.WriteFile(keyPath, []byte(webDavKey), os.ModePerm)
  1117. assert.NoError(t, err)
  1118. certMgr, err = common.NewCertManager(certPath, keyPath, "", "webdav_test")
  1119. assert.NoError(t, err)
  1120. certMgr.SetCARevocationLists([]string{caCrlPath})
  1121. err = certMgr.LoadCRLs()
  1122. assert.NoError(t, err)
  1123. crt, err := tls.X509KeyPair([]byte(client1Crt), []byte(client1Key))
  1124. assert.NoError(t, err)
  1125. x509crt, err := x509.ParseCertificate(crt.Certificate[0])
  1126. assert.NoError(t, err)
  1127. server := webDavServer{}
  1128. state := tls.ConnectionState{
  1129. PeerCertificates: []*x509.Certificate{x509crt},
  1130. }
  1131. err = server.verifyTLSConnection(state)
  1132. assert.Error(t, err) // no verified certification chain
  1133. crt, err = tls.X509KeyPair([]byte(caCRT), []byte(caKey))
  1134. assert.NoError(t, err)
  1135. x509CAcrt, err := x509.ParseCertificate(crt.Certificate[0])
  1136. assert.NoError(t, err)
  1137. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crt, x509CAcrt})
  1138. err = server.verifyTLSConnection(state)
  1139. assert.NoError(t, err)
  1140. crt, err = tls.X509KeyPair([]byte(client2Crt), []byte(client2Key))
  1141. assert.NoError(t, err)
  1142. x509crtRevoked, err := x509.ParseCertificate(crt.Certificate[0])
  1143. assert.NoError(t, err)
  1144. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crtRevoked, x509CAcrt})
  1145. state.PeerCertificates = []*x509.Certificate{x509crtRevoked}
  1146. err = server.verifyTLSConnection(state)
  1147. assert.EqualError(t, err, common.ErrCrtRevoked.Error())
  1148. err = os.Remove(caCrlPath)
  1149. assert.NoError(t, err)
  1150. err = os.Remove(certPath)
  1151. assert.NoError(t, err)
  1152. err = os.Remove(keyPath)
  1153. assert.NoError(t, err)
  1154. certMgr = oldCertMgr
  1155. }