test_attachmentview.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import os
  2. from django.urls import reverse
  3. from .. import test
  4. from ...acl.models import Role
  5. from ...acl.test import patch_user_acl
  6. from ...categories.models import Category
  7. from ...conf import settings
  8. from ...users.test import AuthenticatedUserTestCase
  9. from ..models import Attachment, AttachmentType
  10. TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
  11. TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, "document.pdf")
  12. TEST_SMALLJPG_PATH = os.path.join(TESTFILES_DIR, "small.jpg")
  13. def patch_attachments_acl(acl_patch=None):
  14. acl_patch = acl_patch or {}
  15. acl_patch.setdefault("max_attachment_size", 1024)
  16. acl_patch.setdefault("can_download_other_users_attachments", True)
  17. return patch_user_acl(acl_patch)
  18. class AttachmentViewTestCase(AuthenticatedUserTestCase):
  19. def setUp(self):
  20. super().setUp()
  21. AttachmentType.objects.all().delete()
  22. self.category = Category.objects.get(slug="first-category")
  23. self.post = test.post_thread(category=self.category).first_post
  24. self.api_link = reverse("misago:api:attachment-list")
  25. self.attachment_type_jpg = AttachmentType.objects.create(
  26. name="JPG", extensions="jpeg,jpg"
  27. )
  28. self.attachment_type_pdf = AttachmentType.objects.create(
  29. name="PDF", extensions="pdf"
  30. )
  31. def upload_document(self, is_orphaned=False, by_other_user=False):
  32. with open(TEST_DOCUMENT_PATH, "rb") as upload:
  33. response = self.client.post(self.api_link, data={"upload": upload})
  34. self.assertEqual(response.status_code, 200)
  35. attachment = Attachment.objects.order_by("id").last()
  36. if not is_orphaned:
  37. attachment.post = self.post
  38. attachment.save()
  39. if by_other_user:
  40. attachment.uploader = None
  41. attachment.save()
  42. return attachment
  43. def upload_image(self):
  44. with open(TEST_SMALLJPG_PATH, "rb") as upload:
  45. response = self.client.post(self.api_link, data={"upload": upload})
  46. self.assertEqual(response.status_code, 200)
  47. return Attachment.objects.order_by("id").last()
  48. @patch_attachments_acl()
  49. def assertIs404(self, response):
  50. self.assertEqual(response.status_code, 302)
  51. self.assertTrue(response["location"].endswith(settings.MISAGO_404_IMAGE))
  52. @patch_attachments_acl()
  53. def assertIs403(self, response):
  54. self.assertEqual(response.status_code, 302)
  55. self.assertTrue(response["location"].endswith(settings.MISAGO_403_IMAGE))
  56. @patch_attachments_acl()
  57. def assertSuccess(self, response):
  58. self.assertEqual(response.status_code, 302)
  59. self.assertFalse(response["location"].endswith(settings.MISAGO_404_IMAGE))
  60. self.assertFalse(response["location"].endswith(settings.MISAGO_403_IMAGE))
  61. @patch_attachments_acl()
  62. def test_nonexistant_file(self):
  63. """user tries to retrieve nonexistant file"""
  64. response = self.client.get(
  65. reverse("misago:attachment", kwargs={"pk": 123, "secret": "qwertyuiop"})
  66. )
  67. self.assertIs404(response)
  68. @patch_attachments_acl()
  69. def test_invalid_secret(self):
  70. """user tries to retrieve existing file using invalid secret"""
  71. attachment = self.upload_document()
  72. response = self.client.get(
  73. reverse(
  74. "misago:attachment",
  75. kwargs={"pk": attachment.pk, "secret": "qwertyuiop"},
  76. )
  77. )
  78. self.assertIs404(response)
  79. @patch_attachments_acl({"can_download_other_users_attachments": False})
  80. def test_other_user_file_no_permission(self):
  81. """user tries to retrieve other user's file without perm"""
  82. attachment = self.upload_document(by_other_user=True)
  83. response = self.client.get(attachment.get_absolute_url())
  84. self.assertIs403(response)
  85. @patch_attachments_acl({"can_download_other_users_attachments": False})
  86. def test_other_user_orphaned_file(self):
  87. """user tries to retrieve other user's orphaned file"""
  88. attachment = self.upload_document(is_orphaned=True, by_other_user=True)
  89. response = self.client.get(attachment.get_absolute_url())
  90. self.assertIs404(response)
  91. response = self.client.get(attachment.get_absolute_url() + "?shva=1")
  92. self.assertIs404(response)
  93. @patch_attachments_acl()
  94. def test_document_thumbnail(self):
  95. """user tries to retrieve thumbnail from non-image attachment"""
  96. attachment = self.upload_document()
  97. response = self.client.get(
  98. reverse(
  99. "misago:attachment-thumbnail",
  100. kwargs={"pk": attachment.pk, "secret": attachment.secret},
  101. )
  102. )
  103. self.assertIs404(response)
  104. @patch_attachments_acl()
  105. def test_no_role(self):
  106. """user tries to retrieve attachment without perm to its type"""
  107. attachment = self.upload_document()
  108. user_roles = (r.pk for r in self.user.get_roles())
  109. self.attachment_type_pdf.limit_downloads_to.set(
  110. Role.objects.exclude(id__in=user_roles)
  111. )
  112. response = self.client.get(attachment.get_absolute_url())
  113. self.assertIs403(response)
  114. @patch_attachments_acl()
  115. def test_type_disabled(self):
  116. """user tries to retrieve attachment the type disabled downloads"""
  117. attachment = self.upload_document()
  118. self.attachment_type_pdf.status = AttachmentType.DISABLED
  119. self.attachment_type_pdf.save()
  120. response = self.client.get(attachment.get_absolute_url())
  121. self.assertIs403(response)
  122. @patch_attachments_acl()
  123. def test_locked_type(self):
  124. """user retrieves own locked file"""
  125. attachment = self.upload_document()
  126. self.attachment_type_pdf.status = AttachmentType.LOCKED
  127. self.attachment_type_pdf.save()
  128. response = self.client.get(attachment.get_absolute_url())
  129. self.assertSuccess(response)
  130. @patch_attachments_acl()
  131. def test_own_file(self):
  132. """user retrieves own file"""
  133. attachment = self.upload_document()
  134. response = self.client.get(attachment.get_absolute_url())
  135. self.assertSuccess(response)
  136. @patch_attachments_acl()
  137. def test_other_user_file(self):
  138. """user retrieves other user's file with perm"""
  139. attachment = self.upload_document(by_other_user=True)
  140. response = self.client.get(attachment.get_absolute_url())
  141. self.assertSuccess(response)
  142. @patch_attachments_acl()
  143. def test_other_user_orphaned_file_is_staff(self):
  144. """user retrieves other user's orphaned file because he is staff"""
  145. attachment = self.upload_document(is_orphaned=True, by_other_user=True)
  146. self.user.is_staff = True
  147. self.user.save()
  148. response = self.client.get(attachment.get_absolute_url())
  149. self.assertIs404(response)
  150. response = self.client.get(attachment.get_absolute_url() + "?shva=1")
  151. self.assertSuccess(response)
  152. @patch_attachments_acl()
  153. def test_orphaned_file_is_uploader(self):
  154. """user retrieves orphaned file because he is its uploader"""
  155. attachment = self.upload_document(is_orphaned=True)
  156. response = self.client.get(attachment.get_absolute_url())
  157. self.assertIs404(response)
  158. response = self.client.get(attachment.get_absolute_url() + "?shva=1")
  159. self.assertSuccess(response)
  160. @patch_attachments_acl()
  161. def test_has_role(self):
  162. """user retrieves file he has roles to download"""
  163. attachment = self.upload_document()
  164. user_roles = self.user.get_roles()
  165. self.attachment_type_pdf.limit_downloads_to.set(user_roles)
  166. response = self.client.get(attachment.get_absolute_url() + "?shva=1")
  167. self.assertSuccess(response)
  168. @patch_attachments_acl()
  169. def test_image(self):
  170. """user retrieves """
  171. attachment = self.upload_image()
  172. response = self.client.get(attachment.get_absolute_url() + "?shva=1")
  173. self.assertSuccess(response)
  174. @patch_attachments_acl()
  175. def test_image_thumb(self):
  176. """user retrieves image's thumbnail"""
  177. attachment = self.upload_image()
  178. response = self.client.get(attachment.get_absolute_url() + "?shva=1")
  179. self.assertSuccess(response)