diff options
-rw-r--r-- | Bugzilla/Bug.pm | 3 | ||||
-rw-r--r-- | Bugzilla/Comment.pm | 27 | ||||
-rwxr-xr-x | contrib/sanitizeme.pl | 17 | ||||
-rw-r--r-- | extensions/BMO/Extension.pm | 75 | ||||
-rw-r--r-- | extensions/BMO/template/en/default/hook/admin/params/editparams-current_panel.html.tmpl | 13 | ||||
-rw-r--r-- | extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl | 10 |
6 files changed, 132 insertions, 13 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 6a5e0966e..295befa9c 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -3463,8 +3463,9 @@ sub comments { $comment->{count} = $count++; $comment->{bug} = $self; } + Bugzilla::Hook::process('bug_comments', { bug => $self, comments => $self->{'comments'} }); # Some bugs may have no comments when upgrading old installations. - Bugzilla::Comment->preload($self->{'comments'}) if $count; + Bugzilla::Comment->preload($self->{'comments'}) if @{ $self->{'comments'} }; } return unless defined wantarray; diff --git a/Bugzilla/Comment.pm b/Bugzilla/Comment.pm index 623796142..30f0252b3 100644 --- a/Bugzilla/Comment.pm +++ b/Bugzilla/Comment.pm @@ -29,6 +29,7 @@ use Bugzilla::Attachment; use Bugzilla::Comment::TagWeights; use Bugzilla::Constants; use Bugzilla::Error; +use Bugzilla::Hook; use Bugzilla::User; use Bugzilla::Util; @@ -165,18 +166,16 @@ sub preload { $comment->{author} = $user_map{$comment->{who}}; } # Tags - if (Bugzilla->params->{'comment_taggers_group'}) { - my $dbh = Bugzilla->dbh; - my @comment_ids = map { $_->id } @$comments; - my %comment_map = map { $_->id => $_ } @$comments; - my $rows = $dbh->selectall_arrayref( - "SELECT comment_id, " . $dbh->sql_group_concat('tag', "','") . " - FROM longdescs_tags - WHERE " . $dbh->sql_in('comment_id', \@comment_ids) . " - GROUP BY comment_id"); - foreach my $row (@$rows) { - $comment_map{$row->[0]}->{tags} = [ split(/,/, $row->[1]) ]; - } + my $dbh = Bugzilla->dbh; + my @comment_ids = map { $_->id } @$comments; + my %comment_map = map { $_->id => $_ } @$comments; + my $rows = $dbh->selectall_arrayref( + "SELECT comment_id, " . $dbh->sql_group_concat('tag', "','") . " + FROM longdescs_tags + WHERE " . $dbh->sql_in('comment_id', \@comment_ids) . " + GROUP BY comment_id"); + foreach my $row (@$rows) { + $comment_map{$row->[0]}->{tags} = [ split(/,/, $row->[1]) ]; } } @@ -294,6 +293,8 @@ sub add_tag { return if grep { lc($tag) eq lc($_) } @$tags; push @$tags, $tag; $self->{'tags'} = [ sort @$tags ]; + Bugzilla::Hook::process("comment_after_add_tag", + { comment => $self, tag => $tag }); } sub remove_tag { @@ -304,6 +305,8 @@ sub remove_tag { my $index = first { lc($tags->[$_]) eq lc($tag) } 0..scalar(@$tags) - 1; return unless defined $index; splice(@$tags, $index, 1); + Bugzilla::Hook::process("comment_after_remove_tag", + { comment => $self, tag => $tag }); } ############## diff --git a/contrib/sanitizeme.pl b/contrib/sanitizeme.pl index 7033006dd..28c2f38f2 100755 --- a/contrib/sanitizeme.pl +++ b/contrib/sanitizeme.pl @@ -27,8 +27,10 @@ use strict; use lib qw(.); use Bugzilla; +use Bugzilla::Bug; use Bugzilla::Constants; use Bugzilla::Util; +use List::MoreUtils qw(uniq); use Getopt::Long; @@ -79,6 +81,7 @@ if ($dry_run) { eval { delete_non_public_products(); delete_secure_bugs(); + delete_deleted_comments(); delete_insider_comments() unless $keep_insider; delete_security_groups(); delete_sensitive_user_data(); @@ -129,6 +132,20 @@ sub delete_secure_bugs { print "\rDone \n" unless $from_cron; } +sub delete_deleted_comments { + # Delete all comments tagged as 'deleted' + my $comment_ids = $dbh->selectcol_arrayref("SELECT comment_id FROM longdescs_tags WHERE tag='deleted'"); + return unless @$comment_ids; + print "Deleting 'deleted' comments...\n"; + my @bug_ids = uniq @{ + $dbh->selectcol_arrayref("SELECT bug_id FROM longdescs WHERE comment_id IN (" . join(',', @$comment_ids) . ")") + }; + $dbh->do("DELETE FROM longdescs WHERE comment_id IN (" . join(',', @$comment_ids) . ")"); + foreach my $bug_id (@bug_ids) { + Bugzilla::Bug->new($bug_id)->_sync_fulltext(update_comments => 1); + } +} + sub delete_insider_comments { # Delete all 'insidergroup' comments and attachments print "Deleting 'insidergroup' comments and attachments...\n"; diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm index c0e8b084b..8d16e2e92 100644 --- a/extensions/BMO/Extension.pm +++ b/extensions/BMO/Extension.pm @@ -1342,4 +1342,79 @@ sub install_filesystem { }; } +# "deleted" comment tag + +sub config_modify_panels { + my ($self, $args) = @_; + push @{ $args->{panels}->{groupsecurity}->{params} }, { + name => 'delete_comments_group', + type => 's', + choices => \&Bugzilla::Config::GroupSecurity::_get_all_group_names, + default => 'admin', + checker => \&check_group + }; +} + +sub comment_after_add_tag { + my ($self, $args) = @_; + my $tag = $args->{tag}; + return unless lc($tag) eq 'deleted'; + + my $group_name = Bugzilla->params->{delete_comments_group}; + if (!$group_name || !Bugzilla->user->in_group($group_name)) { + ThrowUserError('auth_failure', { group => $group_name, + action => 'delete', + object => 'comments' }); + } +} + +sub comment_after_remove_tag { + my ($self, $args) = @_; + my $tag = $args->{tag}; + return unless lc($tag) eq 'deleted'; + + my $group_name = Bugzilla->params->{delete_comments_group}; + if (!$group_name || !Bugzilla->user->in_group($group_name)) { + ThrowUserError('auth_failure', { group => $group_name, + action => 'delete', + object => 'comments' }); + } +} + +BEGIN { + *Bugzilla::Comment::has_tag = \&_comment_has_tag; +} + +sub _comment_has_tag { + my ($self, $test_tag) = @_; + $test_tag = lc($test_tag); + foreach my $tag (@{ $self->tags }) { + return 1 if lc($tag) eq $test_tag; + } + return 0; +} + +sub bug_comments { + my ($self, $args) = @_; + my $can_delete = Bugzilla->user->in_group(Bugzilla->params->{delete_comments_group}); + my $comments = $args->{comments}; + my @deleted = grep { $_->has_tag('deleted') } @$comments; + while (my $comment = pop @deleted) { + for (my $i = scalar(@$comments) - 1; $i >= 0; $i--) { + if ($comment == $comments->[$i]) { + if ($can_delete) { + # don't remove comment from users who can "delete" them + # just collapse it instead + $comment->{collapsed} = 1; + } + else { + # otherwise, remove it from the array + splice(@$comments, $i, 1); + } + last; + } + } + } +} + __PACKAGE__->NAME; diff --git a/extensions/BMO/template/en/default/hook/admin/params/editparams-current_panel.html.tmpl b/extensions/BMO/template/en/default/hook/admin/params/editparams-current_panel.html.tmpl new file mode 100644 index 000000000..39f063464 --- /dev/null +++ b/extensions/BMO/template/en/default/hook/admin/params/editparams-current_panel.html.tmpl @@ -0,0 +1,13 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% IF panel.name == "groupsecurity" %] + [% panel.param_descs.delete_comments_group = + 'The name of the group of users who can delete comments by using the "deleted" comment tag.' + %] +[% END -%] diff --git a/extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl b/extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl index ce855ad97..bf46ed895 100644 --- a/extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl +++ b/extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl @@ -1,7 +1,17 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + [% IF object == 'group_admins' %] the group administrators report [% ELSIF object == 'email_queue' %] the email queue status report [% ELSIF object == 'product_security' %] the product security report +[% ELSIF object == 'comments' %] + comments [% END %] |