attachment.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import os
  2. from django.conf import settings
  3. from django.core.exceptions import PermissionDenied
  4. from django.db.models import F
  5. from django.http import Http404
  6. from django.shortcuts import get_object_or_404, redirect
  7. from ..models import Attachment, AttachmentType
  8. ATTACHMENT_404_URL = '/'.join((settings.STATIC_URL, settings.MISAGO_404_IMAGE))
  9. ATTACHMENT_403_URL = '/'.join((settings.STATIC_URL, settings.MISAGO_403_IMAGE))
  10. def attachment_server(request, pk, secret, thumbnail=False):
  11. try:
  12. url = serve_file(request, pk, secret, thumbnail)
  13. return redirect(url)
  14. except Http404:
  15. return redirect(ATTACHMENT_404_URL)
  16. except PermissionDenied:
  17. return redirect(ATTACHMENT_403_URL)
  18. def serve_file(request, pk, secret, thumbnail):
  19. queryset = Attachment.objects.select_related('filetype')
  20. attachment = get_object_or_404(queryset, pk=pk, secret=secret)
  21. if not request.user.is_staff:
  22. allow_file_download(request, attachment)
  23. attachment.downloads = F('downloads') + 1
  24. attachment.save(update_fields=['downloads'])
  25. if attachment.is_image:
  26. if thumbnail:
  27. return attachment.thumbnail.url
  28. else:
  29. return attachment.image.url
  30. else:
  31. if thumbnail:
  32. raise Http404()
  33. else:
  34. return attachment.file.url
  35. def allow_file_download(request, attachment):
  36. is_authenticated = request.user.is_authenticated()
  37. if not attachment.post_id or not request.user.acl['can_download_other_users_attachments']:
  38. if not is_authenticated or request.user.id != attachment.uploader_id:
  39. raise PermissionDenied()
  40. allowed_roles = set(r.pk for r in attachment.filetype.limit_downloaders_to.all())
  41. if allowed_roles:
  42. user_roles = set(r.pk for r in request.user.get_roles())
  43. if not user_roles & allowed_roles:
  44. raise PermissionDenied()
  45. if attachment.filetype.status == AttachmentType.DISABLED:
  46. raise PermissionDenied()