summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgerv%gerv.net <>2002-08-20 06:17:18 +0200
committergerv%gerv.net <>2002-08-20 06:17:18 +0200
commit9c0a26d3a5a35788694f5f284c69b995a3298c86 (patch)
tree15cc4cfb1e5e9fb7bcc3898530776f44c7b52492
parente6fff23fcd99b09511b62c4db4eca658fe5257c4 (diff)
downloadbugzilla-9c0a26d3a5a35788694f5f284c69b995a3298c86.tar.gz
bugzilla-9c0a26d3a5a35788694f5f284c69b995a3298c86.tar.xz
Bug 143286 - Add support for Insiders, Private comments, Private Attachments. Patch by bugreport@peshkin.net; r=gerv.
-rw-r--r--Attachment.pm5
-rw-r--r--Bugzilla/Attachment.pm5
-rw-r--r--Bugzilla/Search.pm3
-rw-r--r--CGI.pl2
-rwxr-xr-xattachment.cgi99
-rwxr-xr-xchecksetup.pl10
-rw-r--r--defparams.pl6
-rw-r--r--globals.pl27
-rwxr-xr-xprocess_bug.cgi21
-rwxr-xr-xprocessmail23
-rw-r--r--template/en/default/attachment/create.html.tmpl17
-rw-r--r--template/en/default/attachment/edit.html.tmpl3
-rw-r--r--template/en/default/attachment/list.html.tmpl6
-rw-r--r--template/en/default/bug/comments.html.tmpl32
-rw-r--r--template/en/default/bug/edit.html.tmpl7
-rw-r--r--template/en/default/bug/show-multiple.html.tmpl2
16 files changed, 194 insertions, 74 deletions
diff --git a/Attachment.pm b/Attachment.pm
index 23e634276..b4216d4c6 100644
--- a/Attachment.pm
+++ b/Attachment.pm
@@ -49,7 +49,7 @@ sub query
# of hashes in which each hash represents a single attachment.
&::SendSQL("
SELECT attach_id, creation_ts, mimetype, description, ispatch,
- isobsolete, submitter_id
+ isobsolete, isprivate, submitter_id
FROM attachments WHERE bug_id = $bugid ORDER BY attach_id
");
my @attachments = ();
@@ -57,7 +57,8 @@ sub query
my %a;
my $submitter_id;
($a{'attachid'}, $a{'date'}, $a{'contenttype'}, $a{'description'},
- $a{'ispatch'}, $a{'isobsolete'}, $submitter_id) = &::FetchSQLData();
+ $a{'ispatch'}, $a{'isobsolete'}, $a{'isprivate'}, $submitter_id)
+ = &::FetchSQLData();
# Format the attachment's creation/modification date into a standard
# format (YYYY-MM-DD HH:MM)
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index 23e634276..b4216d4c6 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -49,7 +49,7 @@ sub query
# of hashes in which each hash represents a single attachment.
&::SendSQL("
SELECT attach_id, creation_ts, mimetype, description, ispatch,
- isobsolete, submitter_id
+ isobsolete, isprivate, submitter_id
FROM attachments WHERE bug_id = $bugid ORDER BY attach_id
");
my @attachments = ();
@@ -57,7 +57,8 @@ sub query
my %a;
my $submitter_id;
($a{'attachid'}, $a{'date'}, $a{'contenttype'}, $a{'description'},
- $a{'ispatch'}, $a{'isobsolete'}, $submitter_id) = &::FetchSQLData();
+ $a{'ispatch'}, $a{'isobsolete'}, $a{'isprivate'}, $submitter_id)
+ = &::FetchSQLData();
# Format the attachment's creation/modification date into a standard
# format (YYYY-MM-DD HH:MM)
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 257b7656d..9ce9d78f4 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -312,6 +312,9 @@ sub init {
"^long_?desc," => sub {
my $table = "longdescs_$chartid";
push(@supptables, "longdescs $table");
+ if (Param("insidergroup") && !UserInGroup(Param("insidergroup"))) {
+ push(@wherepart, "$table.isprivate < 1") ;
+ }
push(@wherepart, "$table.bug_id = bugs.bug_id");
$f = "$table.thetext";
},
diff --git a/CGI.pl b/CGI.pl
index 2a10a335a..76b88d452 100644
--- a/CGI.pl
+++ b/CGI.pl
@@ -937,7 +937,7 @@ sub CheckIfVotedConfirmed {
}
AppendComment($id, DBID_to_name($who),
- "*** This bug has been confirmed by popular vote. ***");
+ "*** This bug has been confirmed by popular vote. ***", 0);
$vars->{'type'} = "votes";
$vars->{'id'} = $id;
diff --git a/attachment.cgi b/attachment.cgi
index 5614549e4..9f3b39fcc 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -109,6 +109,7 @@ elsif ($action eq "update")
validateIsPatch();
validateContentType() unless $::FORM{'ispatch'};
validateIsObsolete();
+ validatePrivate();
validateStatuses();
update();
}
@@ -125,22 +126,25 @@ exit;
sub validateID
{
- # Validate the value of the "id" form field, which must contain an
- # integer that is the ID of an existing attachment.
+ # Validate the value of the "id" form field, which must contain an
+ # integer that is the ID of an existing attachment.
- detaint_natural($::FORM{'id'})
- || DisplayError("You did not enter a valid attachment number.")
+ detaint_natural($::FORM{'id'})
+ || DisplayError("You did not enter a valid attachment number.")
&& exit;
- # Make sure the attachment exists in the database.
- SendSQL("SELECT bug_id FROM attachments WHERE attach_id = $::FORM{'id'}");
- MoreSQLData()
- || DisplayError("Attachment #$::FORM{'id'} does not exist.")
- && exit;
+ # Make sure the attachment exists in the database.
+ SendSQL("SELECT bug_id, isprivate FROM attachments WHERE attach_id = $::FORM{'id'}");
+ MoreSQLData()
+ || DisplayError("Attachment #$::FORM{'id'} does not exist.")
+ && exit;
- # Make sure the user is authorized to access this attachment's bug.
- my ($bugid) = FetchSQLData();
- ValidateBugID($bugid);
+ # Make sure the user is authorized to access this attachment's bug.
+ my ($bugid, $isprivate) = FetchSQLData();
+ ValidateBugID($bugid);
+ if (($isprivate > 0 ) && Param("insidergroup") && !(UserInGroup(Param("insidergroup")))) {
+ ThrowUserError("You are not permitted access to this attachment.");
+ }
}
sub validateCanEdit
@@ -244,6 +248,14 @@ sub validateIsObsolete
$::FORM{'isobsolete'} = $::FORM{'isobsolete'} ? 1 : 0;
}
+sub validatePrivate
+{
+ # Set the isprivate flag to zero if it is undefined, since the UI uses
+ # an HTML checkbox to represent this flag, and unchecked HTML checkboxes
+ # do not get sent in HTML requests.
+ $::FORM{'isprivate'} = $::FORM{'isprivate'} ? 1 : 0;
+}
+
sub validateStatuses
{
# Get a list of attachment statuses that are valid for this attachment.
@@ -354,16 +366,16 @@ sub validateObsolete
sub view
{
- # Display an attachment.
+ # Display an attachment.
- # Retrieve the attachment content and its content type from the database.
- SendSQL("SELECT mimetype, thedata FROM attachments WHERE attach_id = $::FORM{'id'}");
- my ($contenttype, $thedata) = FetchSQLData();
+ # Retrieve the attachment content and its content type from the database.
+ SendSQL("SELECT mimetype, thedata FROM attachments WHERE attach_id = $::FORM{'id'}");
+ my ($contenttype, $thedata) = FetchSQLData();
- # Return the appropriate HTTP response headers.
- print "Content-Type: $contenttype\n\n";
+ # Return the appropriate HTTP response headers.
+ print "Content-Type: $contenttype\n\n";
- print $thedata;
+ print $thedata;
}
@@ -373,14 +385,20 @@ sub viewall
# Retrieve the attachments from the database and write them into an array
# of hashes where each hash represents one attachment.
- SendSQL("SELECT attach_id, creation_ts, mimetype, description, ispatch, isobsolete
- FROM attachments WHERE bug_id = $::FORM{'bugid'} ORDER BY attach_id");
+ my $privacy = "";
+ if (Param("insidergroup") && !(UserInGroup(Param("insidergroup")))) {
+ $privacy = "AND isprivate < 1 ";
+ }
+ SendSQL("SELECT attach_id, creation_ts, mimetype, description,
+ ispatch, isobsolete, isprivate
+ FROM attachments WHERE bug_id = $::FORM{'bugid'} $privacy
+ ORDER BY attach_id");
my @attachments; # the attachments array
while (MoreSQLData())
{
my %a; # the attachment hash
($a{'attachid'}, $a{'date'}, $a{'contenttype'},
- $a{'description'}, $a{'ispatch'}, $a{'isobsolete'}) = FetchSQLData();
+ $a{'description'}, $a{'ispatch'}, $a{'isobsolete'}, $a{'isprivate'}) = FetchSQLData();
# Flag attachments as to whether or not they can be viewed (as opposed to
# being downloaded). Currently I decide they are viewable if their MIME type
@@ -432,7 +450,7 @@ sub enter
if (!UserInGroup("editbugs")) {
$canEdit = "AND submitter_id = $::userid";
}
- SendSQL("SELECT attach_id, description
+ SendSQL("SELECT attach_id, description, isprivate
FROM attachments
WHERE bug_id = $::FORM{'bugid'}
AND isobsolete = 0 $canEdit
@@ -440,7 +458,7 @@ sub enter
my @attachments; # the attachments array
while ( MoreSQLData() ) {
my %a; # the attachment hash
- ($a{'id'}, $a{'description'}) = FetchSQLData();
+ ($a{'id'}, $a{'description'}, $a{'isprivate'}) = FetchSQLData();
# Add the hash representing the attachment to the array of attachments.
push @attachments, \%a;
@@ -473,10 +491,11 @@ sub insert
my $description = SqlQuote($::FORM{'description'});
my $contenttype = SqlQuote($::FORM{'contenttype'});
my $thedata = SqlQuote($::FORM{'data'});
+ my $isprivate = $::FORM{'isprivate'} ? 1 : 0;
# Insert the attachment into the database.
- SendSQL("INSERT INTO attachments (bug_id, creation_ts, filename, description, mimetype, ispatch, submitter_id, thedata)
- VALUES ($::FORM{'bugid'}, now(), $filename, $description, $contenttype, $::FORM{'ispatch'}, $::userid, $thedata)");
+ SendSQL("INSERT INTO attachments (bug_id, creation_ts, filename, description, mimetype, ispatch, isprivate, submitter_id, thedata)
+ VALUES ($::FORM{'bugid'}, now(), $filename, $description, $contenttype, $::FORM{'ispatch'}, $isprivate, $::userid, $thedata)");
# Retrieve the ID of the newly created attachment record.
SendSQL("SELECT LAST_INSERT_ID()");
@@ -493,14 +512,15 @@ sub insert
AppendComment($::FORM{'bugid'},
$::COOKIE{"Bugzilla_login"},
- $comment);
+ $comment,
+ $isprivate);
# Make existing attachments obsolete.
my $fieldid = GetFieldID('attachments.isobsolete');
foreach my $attachid (@{$::MFORM{'obsolete'}}) {
- SendSQL("UPDATE attachments SET isobsolete = 1 WHERE attach_id = $attachid");
- SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
- VALUES ($::FORM{'bugid'}, $attachid, $::userid, NOW(), $fieldid, '0', '1')");
+ SendSQL("UPDATE attachments SET isobsolete = 1 WHERE attach_id = $attachid");
+ SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
+ VALUES ($::FORM{'bugid'}, $attachid, $::userid, NOW(), $fieldid, '0', '1')");
}
# Send mail to let people know the attachment has been created. Uses a
@@ -540,9 +560,9 @@ sub edit
# Users cannot edit the content of the attachment itself.
# Retrieve the attachment from the database.
- SendSQL("SELECT description, mimetype, bug_id, ispatch, isobsolete
+ SendSQL("SELECT description, mimetype, bug_id, ispatch, isobsolete, isprivate
FROM attachments WHERE attach_id = $::FORM{'id'}");
- my ($description, $contenttype, $bugid, $ispatch, $isobsolete) = FetchSQLData();
+ my ($description, $contenttype, $bugid, $ispatch, $isobsolete, $isprivate) = FetchSQLData();
# Flag attachment as to whether or not it can be viewed (as opposed to
# being downloaded). Currently I decide it is viewable if its content
@@ -592,6 +612,7 @@ sub edit
$vars->{'bugsummary'} = $bugsummary;
$vars->{'ispatch'} = $ispatch;
$vars->{'isobsolete'} = $isobsolete;
+ $vars->{'isprivate'} = $isprivate;
$vars->{'isviewable'} = $isviewable;
$vars->{'statuses'} = \%statuses;
$vars->{'statusdefs'} = \@statusdefs;
@@ -619,12 +640,12 @@ sub update
# Lock database tables in preparation for updating the attachment.
SendSQL("LOCK TABLES attachments WRITE , attachstatuses WRITE ,
attachstatusdefs READ , fielddefs READ , bugs_activity WRITE");
-
# Get a copy of the attachment record before we make changes
# so we can record those changes in the activity table.
- SendSQL("SELECT description, mimetype, ispatch, isobsolete
+ SendSQL("SELECT description, mimetype, ispatch, isobsolete, isprivate
FROM attachments WHERE attach_id = $::FORM{'id'}");
- my ($olddescription, $oldcontenttype, $oldispatch, $oldisobsolete) = FetchSQLData();
+ my ($olddescription, $oldcontenttype, $oldispatch, $oldisobsolete,
+ $oldisprivate ) = FetchSQLData();
# Get the list of old status flags.
SendSQL("SELECT attachstatusdefs.name
@@ -672,6 +693,7 @@ sub update
mimetype = $quotedcontenttype ,
ispatch = $::FORM{'ispatch'} ,
isobsolete = $::FORM{'isobsolete'}
+ isprivate = $::FORM{'isprivate'} ,
WHERE attach_id = $::FORM{'id'}
");
@@ -698,6 +720,11 @@ sub update
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
VALUES ($bugid, $::FORM{'id'}, $::userid, NOW(), $fieldid, $oldisobsolete, $::FORM{'isobsolete'})");
}
+ if ($oldisprivate ne $::FORM{'isprivate'}) {
+ my $fieldid = GetFieldID('attachments.isprivate');
+ SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added)
+ VALUES ($bugid, $::FORM{'id'}, $::userid, NOW(), $fieldid, $oldisprivate, $::FORM{'isprivate'})");
+ }
if ($oldstatuslist ne $newstatuslist) {
my ($removed, $added) = DiffStrings($oldstatuslist, $newstatuslist);
my $quotedremoved = SqlQuote($removed);
@@ -759,7 +786,7 @@ sub update
my $neverused = $::userid;
# Append the comment to the list of comments in the database.
- AppendComment($bugid, $who, $wrappedcomment);
+ AppendComment($bugid, $who, $wrappedcomment, $::FORM{'isprivate'});
}
diff --git a/checksetup.pl b/checksetup.pl
index 34b487443..0a37174dd 100755
--- a/checksetup.pl
+++ b/checksetup.pl
@@ -1316,6 +1316,7 @@ $table{attachments} =
thedata longblob not null,
submitter_id mediumint not null,
isobsolete tinyint not null default 0,
+ isprivate tinyint not null default 0,
index(bug_id),
index(creation_ts)';
@@ -1414,7 +1415,7 @@ $table{longdescs} =
who mediumint not null,
bug_when datetime not null,
thetext mediumtext,
-
+ isprivate tinyint not null default 0,
index(bug_id),
index(who),
index(bug_when)';
@@ -1794,6 +1795,7 @@ AddFDef("attachments.thedata", "Attachment data", 0);
AddFDef("attachments.mimetype", "Attachment mime type", 0);
AddFDef("attachments.ispatch", "Attachment is patch", 0);
AddFDef("attachments.isobsolete", "Attachment is obsolete", 0);
+AddFDef("attachments.isprivate", "Attachment is private", 0);
AddFDef("attachstatusdefs.name", "Attachment Status", 0);
AddFDef("target_milestone", "Target Milestone", 0);
AddFDef("delta_ts", "Last changed date", 0);
@@ -2503,6 +2505,12 @@ if (GetFieldDef('bugs_activity', 'field')) {
DropField('bugs_activity', 'field');
}
+
+# 2002-05-10 - enhanchment bug 143826
+# Add private comments and private attachments on less-private bugs
+AddField('longdescs', 'isprivate', 'tinyint not null default 0');
+AddField('attachments', 'isprivate', 'tinyint not null default 0');
+
# 2000-01-18 New email-notification scheme uses a new field in the bug to
diff --git a/defparams.pl b/defparams.pl
index bc73de600..4f30f85a9 100644
--- a/defparams.pl
+++ b/defparams.pl
@@ -717,4 +717,10 @@ DefParam("maxattachmentsize" ,
"t" ,
'1000');
+DefParam("insidergroup",
+ "The name of the group of users who can see/change private comments
+ and attachments.",
+ "t",
+ '');
1;
+
diff --git a/globals.pl b/globals.pl
index 9f15976b2..b437d343f 100644
--- a/globals.pl
+++ b/globals.pl
@@ -323,7 +323,7 @@ sub FetchOneColumn {
"status", "resolution", "summary");
sub AppendComment {
- my ($bugid,$who,$comment) = (@_);
+ my ($bugid,$who,$comment,$isprivate) = (@_);
$comment =~ s/\r\n/\n/g; # Get rid of windows-style line endings.
$comment =~ s/\r/\n/g; # Get rid of mac-style line endings.
if ($comment =~ /^\s*$/) { # Nothin' but whitespace.
@@ -331,9 +331,10 @@ sub AppendComment {
}
my $whoid = DBNameToIdAndCheck($who);
-
- SendSQL("INSERT INTO longdescs (bug_id, who, bug_when, thetext) " .
- "VALUES($bugid, $whoid, now(), " . SqlQuote($comment) . ")");
+ my $privacyval = $isprivate ? 1 : 0 ;
+ SendSQL("INSERT INTO longdescs (bug_id, who, bug_when, thetext, isprivate) " .
+ "VALUES($bugid, $whoid, now(), " . SqlQuote($comment) . ", " .
+ $privacyval . ")");
SendSQL("UPDATE bugs SET delta_ts = now() WHERE bug_id = $bugid");
}
@@ -1137,8 +1138,9 @@ sub GetLongDescriptionAsText {
my ($id, $start, $end) = (@_);
my $result = "";
my $count = 0;
+ my $anyprivate = 0;
my ($query) = ("SELECT profiles.login_name, longdescs.bug_when, " .
- " longdescs.thetext " .
+ " longdescs.thetext, longdescs.isprivate " .
"FROM longdescs, profiles " .
"WHERE profiles.userid = longdescs.who " .
"AND longdescs.bug_id = $id ");
@@ -1156,25 +1158,29 @@ sub GetLongDescriptionAsText {
$query .= "ORDER BY longdescs.bug_when";
SendSQL($query);
while (MoreSQLData()) {
- my ($who, $when, $text) = (FetchSQLData());
+ my ($who, $when, $text, $isprivate) = (FetchSQLData());
if ($count) {
$result .= "\n\n------- Additional Comments From $who".Param('emailsuffix')." ".
time2str("%Y-%m-%d %H:%M", str2time($when)) . " -------\n";
}
+ if (($isprivate > 0) && Param("insidergroup")) {
+ $anyprivate = 1;
+ }
$result .= $text;
$count++;
}
- return $result;
+ return ($result, $anyprivate);
}
sub GetComments {
my ($id) = (@_);
my @comments;
-
SendSQL("SELECT profiles.realname, profiles.login_name,
date_format(longdescs.bug_when,'%Y-%m-%d %H:%i'),
- longdescs.thetext
+ longdescs.thetext,
+ isprivate,
+ date_format(longdescs.bug_when,'%Y%m%d%H%i%s')
FROM longdescs, profiles
WHERE profiles.userid = longdescs.who
AND longdescs.bug_id = $id
@@ -1182,7 +1188,8 @@ sub GetComments {
while (MoreSQLData()) {
my %comment;
- ($comment{'name'}, $comment{'email'}, $comment{'time'}, $comment{'body'}) = FetchSQLData();
+ ($comment{'name'}, $comment{'email'}, $comment{'time'}, $comment{'body'},
+ $comment{'isprivate'}, $comment{'when'}) = FetchSQLData();
$comment{'email'} .= Param('emailsuffix');
$comment{'name'} = $comment{'name'} || $comment{'email'};
diff --git a/process_bug.cgi b/process_bug.cgi
index 85522b66d..02089297a 100755
--- a/process_bug.cgi
+++ b/process_bug.cgi
@@ -630,6 +630,22 @@ if ( $::FORM{'id'} ) {
}
}
+if ($::FORM{'id'} &&
+ (Param("insidergroup") && UserInGroup(Param("insidergroup")))) {
+ detaint_natural($::FORM{'id'});
+ foreach my $field (keys %::FORM) {
+ if ($field =~ /when-([0-9]+)/) {
+ my $sequence = $1;
+ my $private = $::FORM{"isprivate-$sequence"} ? 1 : 0 ;
+ if ($private != $::FORM{"oisprivate-$sequence"}) {
+ detaint_natural($::FORM{"$field"});
+ SendSQL("UPDATE longdescs SET isprivate = $private
+ WHERE bug_id = $::FORM{'id'} AND bug_when = " . $::FORM{"$field"});
+ }
+ }
+
+ }
+}
my $duplicate = 0;
@@ -1098,7 +1114,8 @@ foreach my $id (@idlist) {
$timestamp = FetchOneColumn();
if (defined $::FORM{'comment'}) {
- AppendComment($id, $::COOKIE{'Bugzilla_login'}, $::FORM{'comment'});
+ AppendComment($id, $::COOKIE{'Bugzilla_login'}, $::FORM{'comment'},
+ $::FORM{'commentprivacy'});
}
my $removedCcString = "";
@@ -1368,7 +1385,7 @@ foreach my $id (@idlist) {
LogActivityEntry($duplicate,"cc","",DBID_to_name($reporter));
SendSQL("INSERT INTO cc (who, bug_id) VALUES ($reporter, " . SqlQuote($duplicate) . ")");
}
- AppendComment($duplicate, $::COOKIE{'Bugzilla_login'}, "*** Bug $::FORM{'id'} has been marked as a duplicate of this bug. ***");
+ AppendComment($duplicate, $::COOKIE{'Bugzilla_login'}, "*** Bug $::FORM{'id'} has been marked as a duplicate of this bug. ***", 1);
CheckFormFieldDefined(\%::FORM,'comment');
SendSQL("INSERT INTO duplicates VALUES ($duplicate, $::FORM{'id'})");
diff --git a/processmail b/processmail
index 20833a4f4..8d4dc4b69 100755
--- a/processmail
+++ b/processmail
@@ -225,7 +225,7 @@ sub ProcessOneBug {
}
- my $newcomments = GetLongDescriptionAsText($id, $start, $end);
+ my ($newcomments, $anyprivate) = GetLongDescriptionAsText($id, $start, $end);
#
# Start of email filtering code
@@ -303,7 +303,8 @@ sub ProcessOneBug {
\@reasons, \%values,
\%defmailhead,
\%fielddescription, $difftext,
- $newcomments, $start, $id,
+ $newcomments, $anyprivate,
+ $start, $id,
\@depbugs)))
{
@@ -612,9 +613,9 @@ sub filterEmailGroup ($$$) {
return @recipients;
}
-sub NewProcessOnePerson ($$$$$$$$$$$$) {
+sub NewProcessOnePerson ($$$$$$$$$$$$$) {
my ($person, $count, $hlRef, $reasonsRef, $valueRef, $dmhRef, $fdRef, $difftext,
- $newcomments, $start, $id, $depbugsRef) = @_;
+ $newcomments, $anyprivate, $start, $id, $depbugsRef) = @_;
my %values = %$valueRef;
my @headerlist = @$hlRef;
@@ -650,7 +651,19 @@ sub NewProcessOnePerson ($$$$$$$$$$$$) {
# quietly disappear from their radar.
#
return unless CanSeeBug($id, $userid, $groupset);
-
+
+ # Drop any non-insiders if the comment is private
+ if (Param("insidergroup") && ($anyprivate != 0)) {
+ ConnectToDatabase();
+ PushGlobalSQLState();
+ SendSQL("select (bit & $groupset ) != 0 from groups where name = " . SqlQuote(Param("insidergroup")));
+ my $bit = FetchOneColumn();
+ PopGlobalSQLState();
+ if (!$bit) {
+ return;
+ }
+ }
+
# We shouldn't send changedmail if this is a dependency mail, and any of
# the depending bugs is not visible to the user.
foreach my $dep_id (@depbugs) {
diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl
index a80708ee3..1c00146e5 100644
--- a/template/en/default/attachment/create.html.tmpl
+++ b/template/en/default/attachment/create.html.tmpl
@@ -94,15 +94,28 @@
onchange="if (this.value) this.form.contenttypemethod[2].checked = true;">
</td>
</tr>
+ [% IF (Param("insidergroup") && UserInGroup(Param("insidergroup"))) %]
+ <tr>
+ <th>Privacy:</th>
+ <td>
+ <em>If the attachment is private, check the box below.</em><br>
+ <input type="checkbox" name="isprivate" id="isprivate" value="1">
+ <label for="isprivate">Private</label>
+ </td>
+ </tr>
+ [% END %]
<tr>
<th>Obsoletes:</th>
<td>
<em>(optional) Check each existing attachment made obsolete by your new attachment.</em><br>
[% IF attachments.size %]
[% FOREACH attachment = attachments %]
- <input type="checkbox" id="[% attachment.id %]"
+ [% IF ((attachment.isprivate == 0) || (Param("insidergroup")
+ && UserInGroup(Param("insidergroup")))) %]
+ <input type="checkbox" id="[% attachment.id %]"
name="obsolete" value="[% attachment.id %]">
- <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">[% attachment.id %]: [% attachment.description FILTER html %]</a><br>
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">[% attachment.id %]: [% attachment.description FILTER html %]</a><br>
+ [% END %]
[% END %]
[% ELSE %]
[no attachments can be made obsolete]
diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl
index 5d01d2898..c9bc7c1cd 100644
--- a/template/en/default/attachment/edit.html.tmpl
+++ b/template/en/default/attachment/edit.html.tmpl
@@ -163,6 +163,9 @@
<input type="checkbox" id="isobsolete" name="isobsolete" value="1"
[% 'checked="checked"' IF isobsolete %]>
<label for="isobsolete">obsolete</label><br>
+ [% IF (Param("insidergroup") && UserInGroup(Param("insidergroup"))) %]
+ <input type="checkbox" name="isprivate" value="1"[% " checked" IF isprivate %]> private<br><br>
+ [% END %]
[% IF statusdefs.size %]
<b>Status:</b><br>
diff --git a/template/en/default/attachment/list.html.tmpl b/template/en/default/attachment/list.html.tmpl
index bc25c5721..e7aa8b0ef 100644
--- a/template/en/default/attachment/list.html.tmpl
+++ b/template/en/default/attachment/list.html.tmpl
@@ -28,9 +28,10 @@
<th bgcolor="#cccccc" align="left">Status</th>
<th bgcolor="#cccccc" align="left">Actions</th>
</tr>
-
+ [% canseeprivate = !Param("insidergroup") || UserInGroup(Param("insidergroup")) %]
[% FOREACH attachment = attachments %]
- <tr>
+ [% IF !attachment.isprivate || canseeprivate %]
+ <tr [% "class=\"bz_private\"" IF attachment.isprivate %]>
<td valign="top">
[% IF attachment.isobsolete %]
<strike><a href="attachment.cgi?id=[% attachment.attachid %]&amp;action=view">[% attachment.description FILTER html %]</a></strike>
@@ -67,6 +68,7 @@
[% END %]
</td>
</tr>
+ [% END %]
[% END %]
<tr>
diff --git a/template/en/default/bug/comments.html.tmpl b/template/en/default/bug/comments.html.tmpl
index f1f8e762e..7a8ae73db 100644
--- a/template/en/default/bug/comments.html.tmpl
+++ b/template/en/default/bug/comments.html.tmpl
@@ -19,8 +19,9 @@
# Contributor(s): Gervase Markham <gerv@gerv.net>
#%]
-[% DEFAULT start_at = 0 %]
+[% DEFAULT start_at = 0 mode = "show" %]
[% count = 0 %]
+[% isinsider = Param("insidergroup") && UserInGroup(Param("insidergroup")) %]
[% FOREACH comment = comments %]
[% IF count >= start_at %]
[% PROCESS a_comment %]
@@ -35,14 +36,25 @@
[%############################################################################%]
[% BLOCK a_comment %]
- [% IF count > 0 %]
- <br>
- <i>------- Additional Comment
- <a name="c[% count %]" href="#c[% count %]">#[% count %]</a> From
- <a href="mailto:[% comment.email FILTER html %]">[% comment.name FILTER html %]</a>
- [%+ comment.time %] -------
- </i>
- [% END %]
+ [% IF NOT comment.isprivate || isinsider %]
+ <div [% "class=\"bz_private\"" IF comment.isprivate %]>
+ [% IF count > 0 %]
+ <br>
+ <i>------- Additional Comment
+ <a name="c[% count %]" href="#c[% count %]">#[% count %]</a> From
+ <a href="mailto:[% comment.email FILTER html %]">[% comment.name FILTER html %]</a>
+ [%+ comment.time %] -------
+ </i>
+ [% END %]
+ [% IF mode == "edit" && isinsider %]
+ <i>
+ <input type=hidden name="oisprivate-[% count %]"
+ value="[% comment.isprivate %]">
+ <input type=hidden name="when-[% count %]" value="[% comment.when %]">
+ <input type=checkbox name="isprivate-[% count %]" value="1"
+ [% " checked=\"checked\"" IF comment.isprivate %]> Private
+ </i>
+ [% END %]
[%# Don't indent the <pre> block, since then the spaces are displayed in the
# generated HTML
@@ -50,4 +62,6 @@
<pre>
[%- quoteUrls(comment.body) -%]
</pre>
+ </div>
+ [% END %]
[% END %]
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
index 502952ef2..9cf33b8b5 100644
--- a/template/en/default/bug/edit.html.tmpl
+++ b/template/en/default/bug/edit.html.tmpl
@@ -28,6 +28,7 @@
h2 = filtered_desc
h3 = "Last modified: $bug.calc_disp_date"
header_html = navigation_links
+ style_urls = [ "css/edit_bug.css" ]
%]
[% END %]
@@ -310,6 +311,9 @@
<br>
<b>Additional <u>C</u>omments:</b>
+ [% IF Param("insidergroup") && UserInGroup(Param("insidergroup")) %]
+ <input type="checkbox" name="commentprivacy" value="1"> Private
+ [% END %]
<br>
<textarea wrap="hard" name="comment" rows="10" cols="80"
accesskey="c"></textarea>
@@ -482,7 +486,6 @@
value="[% Param("move-button-text") %]">
[% END %]
</p>
-</form>
[%# *** Additional Comments *** %]
@@ -502,8 +505,10 @@
[% PROCESS bug/comments.html.tmpl
comments = bug.comments
+ mode = "edit"
%]
+</form>
<hr>
[% PROCESS bug/navigate.html.tmpl %]
diff --git a/template/en/default/bug/show-multiple.html.tmpl b/template/en/default/bug/show-multiple.html.tmpl
index 7c3e7407f..0c089e9c5 100644
--- a/template/en/default/bug/show-multiple.html.tmpl
+++ b/template/en/default/bug/show-multiple.html.tmpl
@@ -22,8 +22,8 @@
[% PROCESS global/header.html.tmpl
title = "Full Text Bug Listing"
+ style_urls = [ "css/show_multiple.css" ]
%]
-
[% IF bugs.first %]
[% FOREACH bug = bugs %]
[% PROCESS bug_display %]