Skip to content

Commit da40761

Browse files
authored
Merge pull request #218 from taigaio/seralot/20260102/protect-endpoints-comments-us
Fix: Prevent editing/deleting user story comments in blocked projects
2 parents f1d8141 + 2330a63 commit da40761

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

taiga/projects/history/api.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from django.utils.translation import gettext as _
1010
from django.utils import timezone
1111

12+
from taiga.base import exceptions as exc
1213
from taiga.base import response
1314
from taiga.base.decorators import detail_route
1415
from taiga.base.api import ReadOnlyListViewSet
@@ -53,6 +54,13 @@ def _get_new_mentions(self, obj: object, old_comment: str, new_comment: str):
5354
submitted_mentions = notifications_services.get_mentions(obj, new_comment)
5455
return list(set(submitted_mentions) - set(old_mentions))
5556

57+
def _raise_if_project_blocked_or_archived(self, project):
58+
if project.blocked_code:
59+
raise exc.Blocked(_("Blocked element"))
60+
61+
if project.is_archived:
62+
raise exc.PermissionDenied("Archived element")
63+
5664
@detail_route(methods=['get'])
5765
def comment_versions(self, request, pk):
5866
obj = self.get_object()
@@ -73,8 +81,7 @@ def comment_versions(self, request, pk):
7381
def edit_comment(self, request, pk):
7482
obj = self.get_object()
7583

76-
if obj.project.is_archived:
77-
return response.Forbidden({"error": _("Project is archived")})
84+
self._raise_if_project_blocked_or_archived(obj.project)
7885

7986
history_entry_id = request.QUERY_PARAMS.get('id', None)
8087
history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
@@ -126,8 +133,7 @@ def edit_comment(self, request, pk):
126133
def delete_comment(self, request, pk):
127134
obj = self.get_object()
128135

129-
if obj.project.is_archived:
130-
return response.Forbidden({"error": _("Project is archived")})
136+
self._raise_if_project_blocked_or_archived(obj.project)
131137

132138
history_entry_id = request.QUERY_PARAMS.get('id', None)
133139
history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()

tests/integration/test_history.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .. import factories as f
1616

1717
from taiga.base.utils import json
18-
from taiga.projects.choices import ArchivedCode
18+
from taiga.projects.choices import ArchivedCode, BLOCKED_BY_STAFF
1919
from taiga.projects.history import services
2020
from taiga.projects.history.models import HistoryEntry
2121
from taiga.projects.history.choices import HistoryType
@@ -249,6 +249,23 @@ def test_delete_comment_is_project_archived(client):
249249
response = client.post(url, content_type="application/json")
250250
assert 403 == response.status_code, response.status_code
251251

252+
def test_delete_comment_is_project_blocked(client):
253+
project = f.create_project(blocked_code=BLOCKED_BY_STAFF)
254+
us = f.create_userstory(project=project)
255+
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
256+
key = make_key_from_model_object(us)
257+
history_entry = f.HistoryEntryFactory.create(type=HistoryType.change,
258+
project=project,
259+
comment="testing",
260+
key=key,
261+
diff={},
262+
user={"pk": project.owner.id})
263+
264+
client.login(project.owner)
265+
url = reverse("userstory-history-delete-comment", args=(us.id,))
266+
url = "%s?id=%s" % (url, history_entry.id)
267+
response = client.post(url, content_type="application/json")
268+
assert 451 == response.status_code, response.status_code
252269

253270
def test_edit_comment(client):
254271
project = f.create_project()
@@ -282,6 +299,29 @@ def test_edit_comment(client):
282299
assert history_entry.edit_comment_date != None
283300
assert history_entry.comment_versions[0]["user"]["id"] == project.owner.id
284301

302+
def test_edit_comment_with_project_blocked(client):
303+
project = f.create_project(blocked_code=BLOCKED_BY_STAFF)
304+
us = f.create_userstory(project=project)
305+
f.MembershipFactory.create(project=project, user=project.owner, is_admin=True)
306+
key = make_key_from_model_object(us)
307+
history_entry = f.HistoryEntryFactory.create(type=HistoryType.change,
308+
project=project,
309+
comment="testing",
310+
key=key,
311+
diff={},
312+
user={"pk": project.owner.id})
313+
314+
history_entry_created_at = history_entry.created_at
315+
assert history_entry.comment_versions == None
316+
assert history_entry.edit_comment_date == None
317+
318+
client.login(project.owner)
319+
url = reverse("userstory-history-edit-comment", args=(us.id,))
320+
url = "%s?id=%s" % (url, history_entry.id)
321+
322+
data = json.dumps({"comment": "testing update comment"})
323+
response = client.post(url, data, content_type="application/json")
324+
assert 451 == response.status_code, response.status_code
285325

286326
def test_get_comment_versions(client):
287327
project = f.create_project()

0 commit comments

Comments
 (0)