summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorByron Jones <bjones@mozilla.com>2013-02-13 17:23:29 +0100
committerByron Jones <bjones@mozilla.com>2013-02-13 17:23:29 +0100
commit8076cbac92c228d086e84ebedef01dfff106cd62 (patch)
tree5c0661e1e874ad9386fd897e01ab58f4d58ee7c1
parent6beadee1270482d38ec4b500340af1b28df9b165 (diff)
downloadbugzilla-8076cbac92c228d086e84ebedef01dfff106cd62.tar.gz
bugzilla-8076cbac92c228d086e84ebedef01dfff106cd62.tar.xz
Bug 690833: Add the ability to restrict who can add comments to a bug report
-rw-r--r--Bugzilla/Bug.pm4
-rw-r--r--Bugzilla/Flag.pm6
-rw-r--r--extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl112
-rw-r--r--extensions/RestrictComments/Config.pm16
-rw-r--r--extensions/RestrictComments/Extension.pm95
-rw-r--r--extensions/RestrictComments/lib/Config.pm47
-rw-r--r--extensions/RestrictComments/template/en/default/admin/params/restrictcomments.html.tmpl23
-rw-r--r--extensions/RestrictComments/template/en/default/hook/bug/edit-after_comment_commit_button.html.tmpl21
-rw-r--r--extensions/RestrictComments/template/en/default/pages/restrict_comments_guidelines.html.tmpl62
-rw-r--r--template/en/default/bug/comments.html.tmpl14
-rw-r--r--template/en/default/bug/edit.html.tmpl29
-rw-r--r--template/en/default/flag/list.html.tmpl2
12 files changed, 363 insertions, 68 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index 0484ab8f4..3d3a92838 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -4029,8 +4029,8 @@ sub check_can_change_field {
return 1;
}
- # Allow anyone to change comments.
- if ($field =~ /^longdesc/) {
+ # Allow anyone to change comments, or set flags
+ if ($field =~ /^longdesc/ || $field eq 'flagtypes.name') {
return 1;
}
diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm
index 0828ddc7c..2f6ee526f 100644
--- a/Bugzilla/Flag.pm
+++ b/Bugzilla/Flag.pm
@@ -312,6 +312,12 @@ sub set_flag {
ThrowCodeError('flag_unexpected_object', { 'caller' => ref $obj });
}
+ # Make sure the user can change flags
+ my $privs;
+ $bug->check_can_change_field('flagtypes.name', 0, 1, \$privs)
+ || ThrowUserError('illegal_change',
+ { field => 'flagtypes.name', privs => $privs });
+
# Update (or delete) an existing flag.
if ($params->{id}) {
my $flag = $class->check({ id => $params->{id} });
diff --git a/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl b/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
index de97706b0..f72267246 100644
--- a/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
@@ -41,29 +41,36 @@
<label>Project Flags:</label>
</td>
<td>
- <table id="project-flags">
- [% FOREACH field = project_flags %]
- [% NEXT IF NOT user.id AND field.value == "---" %]
- <tr id="row_[% field.name FILTER js %]">
- <td>&nbsp;</td>
- <td>
- <label for="[% field.name FILTER html %]">
- [% field_descs.${field.name} FILTER html %]:
- </label>
- </td>
- <td>
- [% PROCESS bug/field.html.tmpl value = bug.${field.name}
- editable = user.id
- no_tds = 1 %]
- [% IF user.id %]
- <span id="ro_[% field.name FILTER html %]" class="bz_hidden">
- [% bug.${field.name} FILTER html %]
- </span>
- [% END %]
- </td>
- </tr>
+ [% IF bug.check_can_change_field('flagtypes.name', 0, 1) %]
+ <table id="project-flags">
+ [% FOREACH field = project_flags %]
+ [% NEXT IF NOT user.id AND field.value == "---" %]
+ <tr id="row_[% field.name FILTER js %]">
+ <td>&nbsp;</td>
+ <td>
+ <label for="[% field.name FILTER html %]">
+ [% field_descs.${field.name} FILTER html %]:
+ </label>
+ </td>
+ <td>
+ [% PROCESS bug/field.html.tmpl value = bug.${field.name}
+ editable = user.id
+ no_tds = 1 %]
+ [% IF user.id %]
+ <span id="ro_[% field.name FILTER html %]" class="bz_hidden">
+ [% bug.${field.name} FILTER html %]
+ </span>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ [% FOREACH field = project_flags %]
+ [% NEXT IF bug.${field.name} == "---" %]
+ [% field_descs.${field.name} FILTER html %]: [% bug.${field.name} FILTER html %]<br>
+ [% END %]
[% END %]
- </table>
</td>
</tr>
[% END %]
@@ -74,34 +81,41 @@
<label>Tracking Flags:</label>
</td>
<td>
- [% IF user.id %]
- <span id="edit_tracking_fields_action">
- (<a onclick="bmo_show_tracking_flags()" href="javascript:void(0)">edit</a>)
- </span>
+ [% IF bug.check_can_change_field('flagtypes.name', 0, 1) %]
+ [% IF user.id %]
+ <span id="edit_tracking_fields_action">
+ (<a onclick="bmo_show_tracking_flags()" href="javascript:void(0)">edit</a>)
+ </span>
+ [% END %]
+ <table id="custom-flags">
+ [% FOREACH field = tracking_flags %]
+ [% NEXT IF NOT user.id AND field.value == "---" %]
+ <tr id="row_[% field.name FILTER js %]">
+ <td>&nbsp;</td>
+ <td>
+ <label for="[% field.name FILTER html %]">
+ [% field_descs.${field.name} FILTER html %]:
+ </label>
+ </td>
+ <td>
+ [% PROCESS bug/field.html.tmpl value = bug.${field.name}
+ editable = user.id
+ no_tds = 1 %]
+ [% IF user.id %]
+ <span id="ro_[% field.name FILTER html %]" class="bz_hidden">
+ [% bug.${field.name} FILTER html %]
+ </span>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ [% FOREACH field = tracking_flags %]
+ [% NEXT IF bug.${field.name} == "---" %]
+ [% field_descs.${field.name} FILTER html %]: [% bug.${field.name} FILTER html %]<br>
+ [% END %]
[% END %]
- <table id="custom-flags">
- [% FOREACH field = tracking_flags %]
- [% NEXT IF NOT user.id AND field.value == "---" %]
- <tr id="row_[% field.name FILTER js %]">
- <td>&nbsp;</td>
- <td>
- <label for="[% field.name FILTER html %]">
- [% field_descs.${field.name} FILTER html %]:
- </label>
- </td>
- <td>
- [% PROCESS bug/field.html.tmpl value = bug.${field.name}
- editable = user.id
- no_tds = 1 %]
- [% IF user.id %]
- <span id="ro_[% field.name FILTER html %]" class="bz_hidden">
- [% bug.${field.name} FILTER html %]
- </span>
- [% END %]
- </td>
- </tr>
- [% END %]
- </table>
</td>
</tr>
<script type="text/javascript">
diff --git a/extensions/RestrictComments/Config.pm b/extensions/RestrictComments/Config.pm
new file mode 100644
index 000000000..bef472cc1
--- /dev/null
+++ b/extensions/RestrictComments/Config.pm
@@ -0,0 +1,16 @@
+# 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.
+
+package Bugzilla::Extension::RestrictComments;
+
+use strict;
+
+use constant NAME => 'RestrictComments';
+use constant REQUIRED_MODULES => [];
+use constant OPTIONAL_MODULES => [];
+
+__PACKAGE__->NAME;
diff --git a/extensions/RestrictComments/Extension.pm b/extensions/RestrictComments/Extension.pm
new file mode 100644
index 000000000..001332a8e
--- /dev/null
+++ b/extensions/RestrictComments/Extension.pm
@@ -0,0 +1,95 @@
+# 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.
+
+package Bugzilla::Extension::RestrictComments;
+
+use strict;
+use warnings;
+
+use base qw(Bugzilla::Extension);
+
+use Bugzilla::Constants;
+
+BEGIN {
+ *Bugzilla::Bug::restrict_comments = \&_bug_restrict_comments;
+}
+
+sub _bug_restrict_comments {
+ my ($self) = @_;
+ return $self->{restrict_comments};
+}
+
+sub bug_check_can_change_field {
+ my ($self, $args) = @_;
+ my ($bug, $priv_results) = @$args{qw(bug priv_results)};
+ my $user = Bugzilla->user;
+
+ if ($user->id
+ && $bug->restrict_comments
+ && !$user->in_group(Bugzilla->params->{'restrict_comments_group'}))
+ {
+ push(@$priv_results, PRIVILEGES_REQUIRED_EMPOWERED);
+ return;
+ }
+}
+
+sub _can_restrict_comments {
+ my ($self, $object) = @_;
+ return unless $object->isa('Bugzilla::Bug');
+ $self->{setter_group} ||= Bugzilla->params->{'restrict_comments_enable_group'};
+ return Bugzilla->user->in_group($self->{setter_group});
+}
+
+sub object_end_of_set_all {
+ my ($self, $args) = @_;
+ my $object = $args->{object};
+ if ($self->_can_restrict_comments($object)) {
+ my $input = Bugzilla->input_params;
+ $object->set('restrict_comments', $input->{restrict_comments} ? 1 : undef);
+ }
+}
+
+sub object_update_columns {
+ my ($self, $args) = @_;
+ my ($object, $columns) = @$args{qw(object columns)};
+ if ($self->_can_restrict_comments($object)) {
+ push(@$columns, 'restrict_comments');
+ }
+}
+
+sub object_columns {
+ my ($self, $args) = @_;
+ my ($class, $columns) = @$args{qw(class columns)};
+ if ($class->isa('Bugzilla::Bug')) {
+ push(@$columns, 'restrict_comments');
+ }
+}
+
+sub bug_fields {
+ my ($self, $args) = @_;
+ my $fields = $args->{'fields'};
+ push (@$fields, 'restrict_comments')
+}
+
+sub config_add_panels {
+ my ($self, $args) = @_;
+ my $modules = $args->{panel_modules};
+ $modules->{RestrictComments} = "Bugzilla::Extension::RestrictComments::Config";
+}
+
+sub install_update_db {
+ my $dbh = Bugzilla->dbh;
+
+ my $field = new Bugzilla::Field({ name => 'restrict_comments' });
+ if (!$field) {
+ Bugzilla::Field->create({ name => 'restrict_comments', description => 'Restrict Comments' });
+ }
+
+ $dbh->bz_add_column('bugs', 'restrict_comments', { TYPE => 'BOOLEAN' });
+}
+
+__PACKAGE__->NAME;
diff --git a/extensions/RestrictComments/lib/Config.pm b/extensions/RestrictComments/lib/Config.pm
new file mode 100644
index 000000000..33607e680
--- /dev/null
+++ b/extensions/RestrictComments/lib/Config.pm
@@ -0,0 +1,47 @@
+# 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.
+
+package Bugzilla::Extension::RestrictComments::Config;
+
+use strict;
+use warnings;
+
+use Bugzilla::Config::Common;
+use Bugzilla::Group;
+
+our $sortkey = 510;
+
+sub get_param_list {
+ my ($class) = @_;
+
+ my @param_list = (
+ {
+ name => 'restrict_comments_group',
+ type => 's',
+ choices => \&_get_all_group_names,
+ default => '',
+ checker => \&check_group
+ },
+ {
+ name => 'restrict_comments_enable_group',
+ type => 's',
+ choices => \&_get_all_group_names,
+ default => '',
+ checker => \&check_group
+ },
+ );
+
+ return @param_list;
+}
+
+sub _get_all_group_names {
+ my @group_names = map {$_->name} Bugzilla::Group->get_all;
+ unshift(@group_names, '');
+ return \@group_names;
+}
+
+1;
diff --git a/extensions/RestrictComments/template/en/default/admin/params/restrictcomments.html.tmpl b/extensions/RestrictComments/template/en/default/admin/params/restrictcomments.html.tmpl
new file mode 100644
index 000000000..d2a050563
--- /dev/null
+++ b/extensions/RestrictComments/template/en/default/admin/params/restrictcomments.html.tmpl
@@ -0,0 +1,23 @@
+[%# 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.
+ #%]
+
+[%
+ title = "Restrict Comments"
+ desc = "Edit Restrict Comments Configuration"
+%]
+
+[% param_descs =
+{
+ restrict_comments_group => "Users must be a member of this group to " _
+ "comment on bug with restricted commenting " _
+ "enabled."
+
+ restrict_comments_enable_group => "Members of this group can toggle " _
+ "'restrict comments' on bugs."
+}
+%]
diff --git a/extensions/RestrictComments/template/en/default/hook/bug/edit-after_comment_commit_button.html.tmpl b/extensions/RestrictComments/template/en/default/hook/bug/edit-after_comment_commit_button.html.tmpl
new file mode 100644
index 000000000..0cc24e289
--- /dev/null
+++ b/extensions/RestrictComments/template/en/default/hook/bug/edit-after_comment_commit_button.html.tmpl
@@ -0,0 +1,21 @@
+[%# 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.
+ #%]
+
+
+[% RETURN UNLESS user.in_group(Param('restrict_comments_enable_group')) %]
+
+<div>
+ <input type="checkbox" name="restrict_comments" id="restrict_comments"
+ [% " checked" IF bug.restrict_comments %]>
+ <label for="restrict_comments">
+ Restrict commenting on this [% terms.bug %] to users in the
+ <b>[% Param('restrict_comments_group') FILTER html %]</b> group.
+ </label>
+ (<a href="page.cgi?id=restrict_comments_guidelines.html"
+ target="_blank">guidelines</a>)
+</div>
diff --git a/extensions/RestrictComments/template/en/default/pages/restrict_comments_guidelines.html.tmpl b/extensions/RestrictComments/template/en/default/pages/restrict_comments_guidelines.html.tmpl
new file mode 100644
index 000000000..694681ad7
--- /dev/null
+++ b/extensions/RestrictComments/template/en/default/pages/restrict_comments_guidelines.html.tmpl
@@ -0,0 +1,62 @@
+[%# 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.
+ #%]
+
+[% USE Bugzilla %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Restrict Comments - Guidelines"
+%]
+
+<h3>Restricting Comments</h3>
+
+<p>
+ Some [% terms.bug %] reports are inundated with comments that make it
+ difficult for developers to conduct technical discussions. Restricting
+ comments provides the ability for users in the
+ [%+ Param('restrict_comments_enable_group') FILTER html %] group to prevent
+ users who are not in the [% Param('restrict_comments_group') FILTER html %]
+ from making additional comments.
+</p>
+
+<h3>Guidelines</h3>
+
+<ul>
+ <li>
+ Restrictions may be applied to [% terms.bugs %] which are subject to high
+ volumes of off topic comments, or [% terms.bugs %] which contain high volumes
+ of violations of [% terms.Bugzilla %]
+ <a href="page.cgi?id=etiquette.html">etiquette guidelines</a>.
+ </li>
+ <li>
+ Restrictions should not be used as a preemptive measure against comments
+ which have not yet occurred.
+ </li>
+ <li>
+ Restrictions should not be used to privilege
+ [%+ Param('restrict_comments_group') FILTER html %] users over other users
+ in valid disputes/discussions.
+ </li>
+</ul>
+
+<h3>Impact</h3>
+
+<ul>
+ <li>
+ Users who are not in the [% Param('restrict_comments_group') FILTER html %]
+ group will not be able to comment on the [% terms.bug %], nor will they be
+ able to change the value of any field.
+ </li>
+ <li>
+ All users will still be able to CC themselves to the [% terms.bug %].
+ </li>
+ <li>
+ All users will still be able to vote for the [% terms.bug %].
+ </li>
+</ul>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/comments.html.tmpl b/template/en/default/bug/comments.html.tmpl
index 23f024ae1..a876fb081 100644
--- a/template/en/default/bug/comments.html.tmpl
+++ b/template/en/default/bug/comments.html.tmpl
@@ -170,18 +170,20 @@
[<a class="bz_wrap_link" href="#"
onclick="return toggleCommentWrap(this, [% count %])">wrap</a>]
[% END %]
- [<a class="bz_reply_link" href="#add_comment"
- [% IF user.settings.quote_replies.value != 'off' %]
- onclick="replyToComment('[% count %]', '[% comment.id %]', '[% comment.author.name || comment.author.nick FILTER html FILTER js %]'); return false;"
- [% END %]
- >reply</a>]
+ [% IF bug.check_can_change_field('longdesc', 1, 0) %]
+ [<a class="bz_reply_link" href="#add_comment"
+ [% IF user.settings.quote_replies.value != 'off' %]
+ onclick="replyToComment('[% count %]', '[% comment.id %]', '[% comment.author.name || comment.author.nick FILTER html FILTER js %]'); return false;"
+ [% END %]
+ >reply</a>]
+ [% END %]
<script type="text/javascript"><!--
addCollapseLink([% count %], 'Toggle comment display'); // -->
</script>
</span>
[% END %]
- [% IF mode == "edit" && user.is_insider %]
+ [% IF mode == "edit" && user.is_insider && bug.check_can_change_field('longdesc', 0, 1) %]
<div class="bz_private_checkbox">
<input type="hidden" value="1"
name="defined_isprivate_[% comment.id %]">
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
index 52e5865b8..d57d9641c 100644
--- a/template/en/default/bug/edit.html.tmpl
+++ b/template/en/default/bug/edit.html.tmpl
@@ -903,7 +903,7 @@
flag_types = bug.flag_types
any_flags_requesteeble = bug.any_flags_requesteeble %]
[% END %]
- [% IF show_more_flags %]
+ [% IF show_more_flags && bug.check_can_change_field('flagtypes.name', 0, 1) %]
<span id="bz_flags_more_container" class="bz_default_hidden">
[% IF !bug_flags_set %]<em>None yet set</em>[% END %]
(<a href="#" id="bz_flags_more_action">[% IF !bug_flags_set %]set[% ELSE %]more[% END %] flags</a>)
@@ -1090,7 +1090,7 @@
<label for="comment" accesskey="c"><b>Additional
<u>C</u>omments</b></label>:
- [% IF user.is_insider %]
+ [% IF user.is_insider && bug.check_can_change_field('longdesc', 0, 1) %]
<input type="checkbox" name="comment_is_private" value="1"
id="newcommentprivacy"
onClick="updateCommentTagControl(this, 'comment')">
@@ -1102,14 +1102,23 @@
<!-- This table keeps the submit button aligned with the box. -->
<table><tr><td>
- [% INCLUDE global/textarea.html.tmpl
- name = 'comment'
- id = 'comment'
- minrows = 10
- maxrows = 25
- cols = constants.COMMENT_COLS
- %]
- [% Hook.process("after_comment_textarea", 'bug/edit.html.tmpl') %]
+ [% IF bug.check_can_change_field('longdesc', 0, 1) %]
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'comment'
+ id = 'comment'
+ minrows = 10
+ maxrows = 25
+ cols = constants.COMMENT_COLS
+ %]
+ [% Hook.process("after_comment_textarea", 'bug/edit.html.tmpl') %]
+ [% ELSE %]
+ <div id="comment">
+ <fieldset>
+ <legend>Note</legend>
+ You are unable to make an additional comment on this [% terms.bug %].
+ </fieldset>
+ </div>
+ [% END %]
<br>
[% PROCESS commit_button id=""%]
diff --git a/template/en/default/flag/list.html.tmpl b/template/en/default/flag/list.html.tmpl
index e670515e0..16775c714 100644
--- a/template/en/default/flag/list.html.tmpl
+++ b/template/en/default/flag/list.html.tmpl
@@ -18,7 +18,7 @@
# Contributor(s): Myk Melez <myk@mozilla.org>
#%]
-[% IF user.id AND !read_only_flags %]
+[% IF user.id && !read_only_flags && bug.check_can_change_field('flagtypes.name', 0, 1) %]
[%# We list flags by looping twice over the flag types relevant for the bug.
# In the first loop, we display existing flags and then, for active types,