Delete comments functionality
parent
15bdd06d4f
commit
688e047ff8
|
@ -207,6 +207,11 @@ class IsProjectOwner(PermissionComponent):
|
||||||
return is_project_owner(request.user, obj)
|
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.
|
# Generic permissions.
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
|
@ -186,6 +186,7 @@ class HistoryExportSerializer(serializers.ModelSerializer):
|
||||||
snapshot = JsonField(required=False)
|
snapshot = JsonField(required=False)
|
||||||
values = HistoryValuesField(required=False)
|
values = HistoryValuesField(required=False)
|
||||||
comment = CommentField(required=False)
|
comment = CommentField(required=False)
|
||||||
|
delete_comment_user = HistoryUserField(required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = history_models.HistoryEntry
|
model = history_models.HistoryEntry
|
||||||
|
|
|
@ -16,9 +16,12 @@
|
||||||
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from rest_framework.response import Response
|
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 taiga.base.api import ReadOnlyListViewSet
|
||||||
|
|
||||||
from . import permissions
|
from . import permissions
|
||||||
|
@ -53,6 +56,44 @@ class HistoryViewSet(ReadOnlyListViewSet):
|
||||||
|
|
||||||
return Response(serializer.data)
|
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
|
# Just for restframework! Because it raises
|
||||||
# 404 on main api root if this method not exists.
|
# 404 on main api root if this method not exists.
|
||||||
def list(self, request):
|
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 import models
|
||||||
from django.db.models.loading import get_model
|
from django.db.models.loading import get_model
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
from django.conf import settings
|
||||||
from django_pgjson.fields import JsonField
|
from django_pgjson.fields import JsonField
|
||||||
|
|
||||||
from taiga.mdrender.service import get_diff_of_htmls
|
from taiga.mdrender.service import get_diff_of_htmls
|
||||||
|
@ -64,6 +65,10 @@ class HistoryEntry(models.Model):
|
||||||
comment = models.TextField(blank=True)
|
comment = models.TextField(blank=True)
|
||||||
comment_html = 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
|
@cached_property
|
||||||
def is_comment(self):
|
def is_comment(self):
|
||||||
return self.type == HistoryType.comment
|
return self.type == HistoryType.comment
|
||||||
|
|
|
@ -15,20 +15,34 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
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):
|
class UserStoryHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
retrieve_perms = HasProjectPerm('view_project')
|
||||||
|
delete_comment_perms = IsProjectOwner() | IsObjectOwner()
|
||||||
|
undelete_comment_perms = IsProjectOwner() | IsCommentDeleter()
|
||||||
|
|
||||||
|
|
||||||
class TaskHistoryPermission(TaigaResourcePermission):
|
class TaskHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
retrieve_perms = HasProjectPerm('view_project')
|
||||||
|
delete_comment_perms = IsProjectOwner() | IsObjectOwner()
|
||||||
|
undelete_comment_perms = IsProjectOwner() | IsCommentDeleter()
|
||||||
|
|
||||||
|
|
||||||
class IssueHistoryPermission(TaigaResourcePermission):
|
class IssueHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
retrieve_perms = HasProjectPerm('view_project')
|
||||||
|
delete_comment_perms = IsProjectOwner() | IsObjectOwner()
|
||||||
|
undelete_comment_perms = IsProjectOwner() | IsCommentDeleter()
|
||||||
|
|
||||||
|
|
||||||
class WikiHistoryPermission(TaigaResourcePermission):
|
class WikiHistoryPermission(TaigaResourcePermission):
|
||||||
retrieve_perms = HasProjectPerm('view_project')
|
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')
|
upvote_perms = IsAuthenticated() & HasProjectPerm('vote_issues')
|
||||||
downvote_perms = IsAuthenticated() & HasProjectPerm('vote_issues')
|
downvote_perms = IsAuthenticated() & HasProjectPerm('vote_issues')
|
||||||
bulk_create_perms = HasProjectPerm('add_issue')
|
bulk_create_perms = HasProjectPerm('add_issue')
|
||||||
|
delete_comment_perms= HasProjectPerm('modify_issue')
|
||||||
|
|
||||||
|
|
||||||
class HasIssueIdUrlParam(PermissionComponent):
|
class HasIssueIdUrlParam(PermissionComponent):
|
||||||
|
|
Loading…
Reference in New Issue