1
0

test_rights.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # This file is part of Radicale Server - Calendar Server
  2. # Copyright © 2017-2019 Unrud <unrud@outlook.com>
  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 os
  20. import shutil
  21. import tempfile
  22. from radicale import Application, config
  23. from radicale.tests import BaseTest
  24. from radicale.tests.helpers import get_file_content
  25. class TestBaseRightsRequests(BaseTest):
  26. """Tests basic requests with rights."""
  27. def setup(self):
  28. self.configuration = config.load()
  29. self.colpath = tempfile.mkdtemp()
  30. self.configuration.update({
  31. "storage": {"filesystem_folder": self.colpath,
  32. # Disable syncing to disk for better performance
  33. "_filesystem_fsync": "False"}},
  34. "test", privileged=True)
  35. def teardown(self):
  36. shutil.rmtree(self.colpath)
  37. def _test_rights(self, rights_type, user, path, mode, expected_status,
  38. with_auth=True):
  39. assert mode in ("r", "w")
  40. assert user in ("", "tmp")
  41. htpasswd_file_path = os.path.join(self.colpath, ".htpasswd")
  42. with open(htpasswd_file_path, "w") as f:
  43. f.write("tmp:bepo\nother:bepo")
  44. self.configuration.update({
  45. "rights": {"type": rights_type},
  46. "auth": {"type": "htpasswd" if with_auth else "none",
  47. "htpasswd_filename": htpasswd_file_path,
  48. "htpasswd_encryption": "plain"}}, "test")
  49. self.application = Application(self.configuration)
  50. for u in ("tmp", "other"):
  51. # Indirect creation of principal collection
  52. self.propfind("/%s/" % u, login="%s:bepo" % u)
  53. (self.propfind if mode == "r" else self.proppatch)(
  54. path, check=expected_status, login="tmp:bepo" if user else None)
  55. def test_owner_only(self):
  56. self._test_rights("owner_only", "", "/", "r", 401)
  57. self._test_rights("owner_only", "", "/", "w", 401)
  58. self._test_rights("owner_only", "", "/tmp/", "r", 401)
  59. self._test_rights("owner_only", "", "/tmp/", "w", 401)
  60. self._test_rights("owner_only", "tmp", "/", "r", 207)
  61. self._test_rights("owner_only", "tmp", "/", "w", 403)
  62. self._test_rights("owner_only", "tmp", "/tmp/", "r", 207)
  63. self._test_rights("owner_only", "tmp", "/tmp/", "w", 207)
  64. self._test_rights("owner_only", "tmp", "/other/", "r", 403)
  65. self._test_rights("owner_only", "tmp", "/other/", "w", 403)
  66. def test_owner_only_without_auth(self):
  67. self._test_rights("owner_only", "", "/", "r", 207, False)
  68. self._test_rights("owner_only", "", "/", "w", 401, False)
  69. self._test_rights("owner_only", "", "/tmp/", "r", 207, False)
  70. self._test_rights("owner_only", "", "/tmp/", "w", 207, False)
  71. def test_owner_write(self):
  72. self._test_rights("owner_write", "", "/", "r", 401)
  73. self._test_rights("owner_write", "", "/", "w", 401)
  74. self._test_rights("owner_write", "", "/tmp/", "r", 401)
  75. self._test_rights("owner_write", "", "/tmp/", "w", 401)
  76. self._test_rights("owner_write", "tmp", "/", "r", 207)
  77. self._test_rights("owner_write", "tmp", "/", "w", 403)
  78. self._test_rights("owner_write", "tmp", "/tmp/", "r", 207)
  79. self._test_rights("owner_write", "tmp", "/tmp/", "w", 207)
  80. self._test_rights("owner_write", "tmp", "/other/", "r", 207)
  81. self._test_rights("owner_write", "tmp", "/other/", "w", 403)
  82. def test_owner_write_without_auth(self):
  83. self._test_rights("owner_write", "", "/", "r", 207, False)
  84. self._test_rights("owner_write", "", "/", "w", 401, False)
  85. self._test_rights("owner_write", "", "/tmp/", "r", 207, False)
  86. self._test_rights("owner_write", "", "/tmp/", "w", 207, False)
  87. def test_authenticated(self):
  88. self._test_rights("authenticated", "", "/", "r", 401)
  89. self._test_rights("authenticated", "", "/", "w", 401)
  90. self._test_rights("authenticated", "", "/tmp/", "r", 401)
  91. self._test_rights("authenticated", "", "/tmp/", "w", 401)
  92. self._test_rights("authenticated", "tmp", "/", "r", 207)
  93. self._test_rights("authenticated", "tmp", "/", "w", 207)
  94. self._test_rights("authenticated", "tmp", "/tmp/", "r", 207)
  95. self._test_rights("authenticated", "tmp", "/tmp/", "w", 207)
  96. self._test_rights("authenticated", "tmp", "/other/", "r", 207)
  97. self._test_rights("authenticated", "tmp", "/other/", "w", 207)
  98. def test_authenticated_without_auth(self):
  99. self._test_rights("authenticated", "", "/", "r", 207, False)
  100. self._test_rights("authenticated", "", "/", "w", 207, False)
  101. self._test_rights("authenticated", "", "/tmp/", "r", 207, False)
  102. self._test_rights("authenticated", "", "/tmp/", "w", 207, False)
  103. def test_from_file(self):
  104. rights_file_path = os.path.join(self.colpath, "rights")
  105. with open(rights_file_path, "w") as f:
  106. f.write("""\
  107. [owner]
  108. user: .+
  109. collection: {user}(/.*)?
  110. permissions: RrWw
  111. [custom]
  112. user: .*
  113. collection: custom(/.*)?
  114. permissions: Rr""")
  115. self.configuration.update(
  116. {"rights": {"file": rights_file_path}}, "test")
  117. self._test_rights("from_file", "", "/other/", "r", 401)
  118. self._test_rights("from_file", "tmp", "/other/", "r", 403)
  119. self._test_rights("from_file", "", "/custom/sub", "r", 404)
  120. self._test_rights("from_file", "tmp", "/custom/sub", "r", 404)
  121. self._test_rights("from_file", "", "/custom/sub", "w", 401)
  122. self._test_rights("from_file", "tmp", "/custom/sub", "w", 403)
  123. def test_from_file_limited_get(self):
  124. rights_file_path = os.path.join(self.colpath, "rights")
  125. with open(rights_file_path, "w") as f:
  126. f.write("""\
  127. [write-all]
  128. user: tmp
  129. collection: .*
  130. permissions: RrWw
  131. [limited-public]
  132. user: .*
  133. collection: public/[^/]*
  134. permissions: i""")
  135. self.configuration.update(
  136. {"rights": {"type": "from_file",
  137. "file": rights_file_path}}, "test")
  138. self.application = Application(self.configuration)
  139. self.mkcalendar("/tmp/calendar", login="tmp:bepo")
  140. self.mkcol("/public", login="tmp:bepo")
  141. self.mkcalendar("/public/calendar", login="tmp:bepo")
  142. self.get("/tmp/calendar", check=401)
  143. self.get("/public/", check=401)
  144. self.get("/public/calendar")
  145. self.get("/public/calendar/1.ics", check=401)
  146. def test_custom(self):
  147. """Custom rights management."""
  148. self._test_rights("radicale.tests.custom.rights", "", "/", "r", 401)
  149. self._test_rights(
  150. "radicale.tests.custom.rights", "", "/tmp/", "r", 207)
  151. def test_collections_and_items(self):
  152. """Test rights for creation of collections, calendars and items.
  153. Collections are allowed at "/" and "/.../".
  154. Calendars/Address books are allowed at "/.../.../".
  155. Items are allowed at "/.../.../...".
  156. """
  157. self.application = Application(self.configuration)
  158. self.mkcalendar("/", check=401)
  159. self.mkcalendar("/user/", check=401)
  160. self.mkcol("/user/")
  161. self.mkcol("/user/calendar/", check=401)
  162. self.mkcalendar("/user/calendar/")
  163. self.mkcol("/user/calendar/item", check=401)
  164. self.mkcalendar("/user/calendar/item", check=401)
  165. def test_put_collections_and_items(self):
  166. """Test rights for creation of calendars and items with PUT."""
  167. self.application = Application(self.configuration)
  168. self.put("/user/", "BEGIN:VCALENDAR\r\nEND:VCALENDAR", check=401)
  169. self.mkcol("/user/")
  170. self.put("/user/calendar/", "BEGIN:VCALENDAR\r\nEND:VCALENDAR")
  171. event1 = get_file_content("event1.ics")
  172. self.put("/user/calendar/event1.ics", event1)