Delete comments functionality
parent
15bdd06d4f
commit
688e047ff8
|
@ -207,6 +207,11 @@ class IsProjectOwner(PermissionComponent):
|
|||
return is_project_owner(request.user, obj)
|
||||
|
||||
|
||||
class IsObjectOwner(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
return obj.owner == request.user
|
||||
|
||||
|
||||
######################################################################
|
||||
# Generic permissions.
|
||||
######################################################################
|
||||
|
|
|
@ -186,6 +186,7 @@ class HistoryExportSerializer(serializers.ModelSerializer):
|
|||
snapshot = JsonField(required=False)
|
||||
values = HistoryValuesField(required=False)
|
||||
comment = CommentField(required=False)
|
||||
delete_comment_user = HistoryUserField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = history_models.HistoryEntry
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils import timezone
|
||||
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
from taiga.base.decorators import detail_route
|
||||
from taiga.base.api import ReadOnlyListViewSet
|
||||
|
||||
from . import permissions
|
||||
|
@ -53,6 +56,44 @@ class HistoryViewSet(ReadOnlyListViewSet):
|
|||
|
||||
return Response(serializer.data)
|
||||
|
||||
@detail_route(methods=['post'])
|
||||
def delete_comment(self, request, pk):
|
||||
obj = self.get_object()
|
||||
self.check_permissions(request, 'delete_comment', obj)
|
||||
|
||||
comment_id = request.QUERY_PARAMS.get('id', None)
|
||||
comment = services.get_history_queryset_by_model_instance(obj).filter(id=comment_id).first()
|
||||
|
||||
if comment is None:
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
if comment.delete_comment_date or comment.delete_comment_user:
|
||||
return Response({"error": "Comment already deleted"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
comment.delete_comment_date = timezone.now()
|
||||
comment.delete_comment_user = request.user
|
||||
comment.save()
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
||||
@detail_route(methods=['post'])
|
||||
def undelete_comment(self, request, pk):
|
||||
obj = self.get_object()
|
||||
self.check_permissions(request, 'undelete_comment', obj)
|
||||
|
||||
comment_id = request.QUERY_PARAMS.get('id', None)
|
||||
comment = services.get_history_queryset_by_model_instance(obj).filter(id=comment_id).first()
|
||||
|
||||
if comment is None:
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
if not comment.delete_comment_date and not comment.delete_comment_user:
|
||||
return Response({"error": "Comment not deleted"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
comment.delete_comment_date = None
|
||||
comment.delete_comment_user = None
|
||||
comment.save()
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
||||
# Just for restframework! Because it raises
|
||||
# 404 on main api root if this method not exists.
|
||||
def list(self, request):
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('history', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='historyentry',
|
||||
name='delete_comment_date',
|
||||
field=models.DateTimeField(default=None, null=True, blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historyentry',
|
||||
name='delete_comment_user',
|
||||
field=models.ForeignKey(null=True, default=None, related_name='deleted_comments', to=settings.AUTH_USER_MODEL, blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -19,6 +19,7 @@ from django.utils import timezone
|
|||
from django.db import models
|
||||
from django.db.models.loading import get_model
|
||||
from django.utils.functional import cached_property
|
||||
from django.conf import settings
|
||||
from django_pgjson.fields import JsonField
|
||||
|
||||
from taiga.mdrender.service import get_diff_of_htmls
|
||||
|
@ -64,6 +65,10 @@ class HistoryEntry(models.Model):
|
|||
comment = models.TextField(blank=True)
|
||||
comment_html = models.TextField(blank=True)
|
||||
|
||||
delete_comment_date = models.DateTimeField(null=True, blank=True, default=None)
|
||||
delete_comment_user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, default=None,
|
||||
related_name="deleted_comments")
|
||||
|
||||
@cached_property
|
||||
def is_comment(self):
|
||||
return self.type == HistoryType.comment
|
||||
|
|
|
@ -15,20 +15,34 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
||||
IsProjectOwner, AllowAny)
|
||||
IsProjectOwner, AllowAny,
|
||||
IsObjectOwner, PermissionComponent)
|
||||
|
||||
|
||||
class IsCommentDeleter(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
return obj.delete_comment_user == request.user
|
||||
|
||||
|
||||
class UserStoryHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsProjectOwner() | IsObjectOwner()
|
||||
undelete_comment_perms = IsProjectOwner() | IsCommentDeleter()
|
||||
|
||||
|
||||
class TaskHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsProjectOwner() | IsObjectOwner()
|
||||
undelete_comment_perms = IsProjectOwner() | IsCommentDeleter()
|
||||
|
||||
|
||||
class IssueHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsProjectOwner() | IsObjectOwner()
|
||||
undelete_comment_perms = IsProjectOwner() | IsCommentDeleter()
|
||||
|
||||
|
||||
class WikiHistoryPermission(TaigaResourcePermission):
|
||||
retrieve_perms = HasProjectPerm('view_project')
|
||||
delete_comment_perms = IsProjectOwner() | IsObjectOwner()
|
||||
undelete_comment_perms = IsProjectOwner() | IsCommentDeleter()
|
||||
|
|
|
@ -31,6 +31,7 @@ class IssuePermission(TaigaResourcePermission):
|
|||
upvote_perms = IsAuthenticated() & HasProjectPerm('vote_issues')
|
||||
downvote_perms = IsAuthenticated() & HasProjectPerm('vote_issues')
|
||||
bulk_create_perms = HasProjectPerm('add_issue')
|
||||
delete_comment_perms= HasProjectPerm('modify_issue')
|
||||
|
||||
|
||||
class HasIssueIdUrlParam(PermissionComponent):
|
||||
|
|
Loading…
Reference in New Issue