From b513a6277dd07817e8a702c74de95e906a08ac9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 8 Aug 2014 14:26:55 +0200 Subject: [PATCH] Task #435: Now the attachments verify user permissions --- settings/common.py | 2 ++ taiga/projects/attachments/api.py | 11 +++++++++++ taiga/projects/attachments/serializers.py | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/settings/common.py b/settings/common.py index 95fad2bd..edd3a331 100644 --- a/settings/common.py +++ b/settings/common.py @@ -331,3 +331,5 @@ try: IN_DEVELOPMENT_SERVER = sys.argv[1] == 'runserver' except IndexError: IN_DEVELOPMENT_SERVER = False + +ATTACHMENTS_TOKEN_SALT = "ATTACHMENTS_TOKEN_SALT" diff --git a/taiga/projects/attachments/api.py b/taiga/projects/attachments/api.py index d916ec6d..31047506 100644 --- a/taiga/projects/attachments/api.py +++ b/taiga/projects/attachments/api.py @@ -15,6 +15,7 @@ # along with this program. If not, see . import os +import hashlib from django.utils.translation import ugettext as _ from django.contrib.contenttypes.models import ContentType @@ -26,6 +27,7 @@ from taiga.base.api import ModelCrudViewSet from taiga.base.api import generics from taiga.base import filters from taiga.base import exceptions as exc +from taiga.users.models import User from taiga.projects.notifications import WatchedResourceMixin from taiga.projects.history import HistoryResourceMixin @@ -112,9 +114,18 @@ class RawAttachmentView(generics.RetrieveAPIView): def check_permissions(self, request, action='retrieve', obj=None): self.object = self.get_object() + user_id = self.request.QUERY_PARAMS.get('user', None) + token = self.request.QUERY_PARAMS.get('token', None) + + if token and user_id: + token_src = "{}-{}-{}".format(settings.ATTACHMENTS_TOKEN_SALT, user_id, self.object.id) + if token == hashlib.sha1(token_src.encode("utf-8")).hexdigest(): + request.user = get_object_or_404(User, pk=user_id) + return super().check_permissions(request, action, self.object) def retrieve(self, request, *args, **kwargs): self.object = self.get_object() + self.check_permissions(request, 'retrieve', self.object) return self._serve_attachment(self.object.attached_file) diff --git a/taiga/projects/attachments/serializers.py b/taiga/projects/attachments/serializers.py index 92ecdb40..9bf2660f 100644 --- a/taiga/projects/attachments/serializers.py +++ b/taiga/projects/attachments/serializers.py @@ -13,7 +13,11 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . + from os import path +import hashlib + +from django.conf import settings from rest_framework import serializers @@ -39,7 +43,17 @@ class AttachmentSerializer(serializers.ModelSerializer): return "" def get_url(self, obj): - return reverse("attachment-url", kwargs={"pk": obj.pk}) + token = None + + url = reverse("attachment-url", kwargs={"pk": obj.pk}) + if "request" in self.context and self.context["request"].user.is_authenticated(): + user_id = self.context["request"].user.id + token_src = "{}-{}-{}".format(settings.ATTACHMENTS_TOKEN_SALT, user_id, obj.id) + token = hashlib.sha1(token_src.encode("utf-8")) + + return "{}?user={}&token={}".format(url, user_id, token.hexdigest()) + + return url def get_size(self, obj): if obj.attached_file: