test_rights.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. # This file is part of Radicale Server - Calendar Server
  2. # Copyright (C) 2017 Unrud <unrud@openaliasbox.org>
  3. #
  4. # This library is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
  16. """
  17. Radicale tests with simple requests and rights.
  18. """
  19. import base64
  20. import os
  21. import shutil
  22. import tempfile
  23. from radicale import Application, config
  24. from .test_base import BaseTest
  25. class TestBaseAuthRequests(BaseTest):
  26. """Tests basic requests with rights."""
  27. def setup(self):
  28. self.configuration = config.load()
  29. self.colpath = tempfile.mkdtemp()
  30. self.configuration["storage"]["filesystem_folder"] = self.colpath
  31. # Disable syncing to disk for better performance
  32. self.configuration["storage"]["filesystem_fsync"] = "False"
  33. # Required on Windows, doesn't matter on Unix
  34. self.configuration["storage"]["filesystem_close_lock_file"] = "True"
  35. def teardown(self):
  36. shutil.rmtree(self.colpath)
  37. def _test_rights(self, rights_type, user, path, mode, expected_status):
  38. assert mode in ("r", "w")
  39. assert user in ("", "tmp")
  40. htpasswd_file_path = os.path.join(self.colpath, ".htpasswd")
  41. with open(htpasswd_file_path, "w") as f:
  42. f.write("tmp:bepo\nother:bepo")
  43. self.configuration["rights"]["type"] = rights_type
  44. self.configuration["auth"]["type"] = "htpasswd"
  45. self.configuration["auth"]["htpasswd_filename"] = htpasswd_file_path
  46. self.configuration["auth"]["htpasswd_encryption"] = "plain"
  47. self.application = Application(self.configuration, self.logger)
  48. for u in ("tmp", "other"):
  49. status, _, _ = self.request(
  50. "PROPFIND", "/%s" % u, HTTP_AUTHORIZATION="Basic %s" %
  51. base64.b64encode(("%s:bepo" % u).encode()).decode())
  52. assert status == 207
  53. status, _, _ = self.request(
  54. "PROPFIND" if mode == "r" else "PROPPATCH", path,
  55. HTTP_AUTHORIZATION="Basic %s" % base64.b64encode(
  56. ("tmp:bepo").encode()).decode() if user else "")
  57. assert status == expected_status
  58. def test_owner_only(self):
  59. self._test_rights("owner_only", "", "/", "r", 401)
  60. self._test_rights("owner_only", "", "/", "w", 401)
  61. self._test_rights("owner_only", "", "/tmp", "r", 401)
  62. self._test_rights("owner_only", "", "/tmp", "w", 401)
  63. self._test_rights("owner_only", "tmp", "/", "r", 207)
  64. self._test_rights("owner_only", "tmp", "/", "w", 403)
  65. self._test_rights("owner_only", "tmp", "/tmp", "r", 207)
  66. self._test_rights("owner_only", "tmp", "/tmp", "w", 207)
  67. self._test_rights("owner_only", "tmp", "/other", "r", 403)
  68. self._test_rights("owner_only", "tmp", "/other", "w", 403)
  69. def test_owner_write(self):
  70. self._test_rights("owner_write", "", "/", "r", 401)
  71. self._test_rights("owner_write", "", "/", "w", 401)
  72. self._test_rights("owner_write", "", "/tmp", "r", 401)
  73. self._test_rights("owner_write", "", "/tmp", "w", 401)
  74. self._test_rights("owner_write", "tmp", "/", "r", 207)
  75. self._test_rights("owner_write", "tmp", "/", "w", 403)
  76. self._test_rights("owner_write", "tmp", "/tmp", "r", 207)
  77. self._test_rights("owner_write", "tmp", "/tmp", "w", 207)
  78. self._test_rights("owner_write", "tmp", "/other", "r", 207)
  79. self._test_rights("owner_write", "tmp", "/other", "w", 403)
  80. def test_authenticated(self):
  81. self._test_rights("authenticated", "", "/", "r", 401)
  82. self._test_rights("authenticated", "", "/", "w", 401)
  83. self._test_rights("authenticated", "", "/tmp", "r", 401)
  84. self._test_rights("authenticated", "", "/tmp", "w", 401)
  85. self._test_rights("authenticated", "tmp", "/", "r", 207)
  86. self._test_rights("authenticated", "tmp", "/", "w", 207)
  87. self._test_rights("authenticated", "tmp", "/tmp", "r", 207)
  88. self._test_rights("authenticated", "tmp", "/tmp", "w", 207)
  89. self._test_rights("authenticated", "tmp", "/other", "r", 207)
  90. self._test_rights("authenticated", "tmp", "/other", "w", 207)
  91. def test_none(self):
  92. self._test_rights("none", "", "/", "r", 207)
  93. self._test_rights("none", "", "/", "w", 207)
  94. self._test_rights("none", "", "/tmp", "r", 207)
  95. self._test_rights("none", "", "/tmp", "w", 207)
  96. self._test_rights("none", "tmp", "/", "r", 207)
  97. self._test_rights("none", "tmp", "/", "w", 207)
  98. self._test_rights("none", "tmp", "/tmp", "r", 207)
  99. self._test_rights("none", "tmp", "/tmp", "w", 207)
  100. self._test_rights("none", "tmp", "/other", "r", 207)
  101. self._test_rights("none", "tmp", "/other", "w", 207)
  102. def test_from_file(self):
  103. rights_file_path = os.path.join(self.colpath, "rights")
  104. with open(rights_file_path, "w") as f:
  105. f.write("""\
  106. [owner]
  107. user: .+
  108. collection: %(login)s(/.*)?
  109. permission: rw
  110. [custom]
  111. user: .*
  112. collection: custom(/.*)?
  113. permission: r""")
  114. self.configuration["rights"]["file"] = rights_file_path
  115. self._test_rights("from_file", "", "/other", "r", 401)
  116. self._test_rights("from_file", "tmp", "/other", "r", 403)
  117. self._test_rights("from_file", "", "/custom/sub", "r", 404)
  118. self._test_rights("from_file", "tmp", "/custom/sub", "r", 404)
  119. self._test_rights("from_file", "", "/custom/sub", "w", 401)
  120. self._test_rights("from_file", "tmp", "/custom/sub", "w", 403)
  121. def test_custom(self):
  122. """Custom rights management."""
  123. self._test_rights("tests.custom.rights", "", "/", "r", 401)
  124. self._test_rights("tests.custom.rights", "", "/tmp", "r", 207)