зеркало из https://github.com/mozilla/pjs.git
Bug 44595: Implement an interface for administrators to delete attachments - Patch by Fr�d�ric Buclin <LpSolit@gmail.com> r=wicked, justdave a=justdave
This commit is contained in:
Родитель
afb6491f16
Коммит
34f85c2686
|
@ -339,16 +339,16 @@ sub datasize {
|
|||
# If we have already retrieved the data, return its size.
|
||||
return length($self->{data}) if exists $self->{data};
|
||||
|
||||
($self->{datasize}) =
|
||||
$self->{datasize} =
|
||||
Bugzilla->dbh->selectrow_array("SELECT LENGTH(thedata)
|
||||
FROM attach_data
|
||||
WHERE id = ?",
|
||||
undef,
|
||||
$self->{id});
|
||||
undef, $self->{id}) || 0;
|
||||
|
||||
# If there's no attachment data in the database, the attachment
|
||||
# is stored in a local file, so retrieve its size from the file.
|
||||
if ($self->{datasize} == 0) {
|
||||
# If there's no attachment data in the database, either the attachment
|
||||
# is stored in a local file, and so retrieve its size from the file,
|
||||
# or the attachment has been deleted.
|
||||
unless ($self->{datasize}) {
|
||||
if (open(AH, $self->_get_local_filename())) {
|
||||
binmode AH;
|
||||
$self->{datasize} = (stat(AH))[7];
|
||||
|
|
|
@ -41,6 +41,11 @@ sub get_param_list {
|
|||
my $class = shift;
|
||||
my @param_list = (
|
||||
{
|
||||
name => 'allow_attachment_deletion',
|
||||
type => 'b',
|
||||
default => 0
|
||||
},
|
||||
{
|
||||
name => 'allow_attach_url',
|
||||
type => 'b',
|
||||
default => 0
|
||||
|
|
|
@ -49,6 +49,7 @@ use Bugzilla::Util;
|
|||
use Bugzilla::Bug;
|
||||
use Bugzilla::Field;
|
||||
use Bugzilla::Attachment;
|
||||
use Bugzilla::Token;
|
||||
|
||||
Bugzilla->login();
|
||||
|
||||
|
@ -103,6 +104,9 @@ elsif ($action eq "update")
|
|||
Bugzilla->login(LOGIN_REQUIRED);
|
||||
update();
|
||||
}
|
||||
elsif ($action eq "delete") {
|
||||
delete_attachment();
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowCodeError("unknown_action", { action => $action });
|
||||
|
@ -1329,3 +1333,82 @@ sub update
|
|||
$template->process("attachment/updated.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
|
||||
# Only administrators can delete attachments.
|
||||
sub delete_attachment {
|
||||
my $user = Bugzilla->login(LOGIN_REQUIRED);
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
print $cgi->header();
|
||||
|
||||
$user->in_group('admin')
|
||||
|| ThrowUserError('auth_failure', {group => 'admin',
|
||||
action => 'delete',
|
||||
object => 'attachment'});
|
||||
|
||||
Param('allow_attachment_deletion')
|
||||
|| ThrowUserError('attachment_deletion_disabled');
|
||||
|
||||
# Make sure the administrator is allowed to edit this attachment.
|
||||
my ($attach_id, $bug_id) = validateID();
|
||||
validateCanEdit($attach_id);
|
||||
validateCanChangeAttachment($attach_id);
|
||||
|
||||
my $attachment = Bugzilla::Attachment->get($attach_id);
|
||||
$attachment->datasize || ThrowUserError('attachment_removed');
|
||||
|
||||
# We don't want to let a malicious URL accidentally delete an attachment.
|
||||
my $token = trim($cgi->param('token'));
|
||||
if ($token) {
|
||||
my ($creator_id, $date, $event) = Bugzilla::Token::GetTokenData($token);
|
||||
unless ($creator_id
|
||||
&& ($creator_id == $user->id)
|
||||
&& ($event eq "attachment$attach_id"))
|
||||
{
|
||||
# The token is invalid.
|
||||
ThrowUserError('token_inexistent');
|
||||
}
|
||||
|
||||
# The token is valid. Delete the content of the attachment.
|
||||
my $msg;
|
||||
$vars->{'attachid'} = $attach_id;
|
||||
$vars->{'bugid'} = $bug_id;
|
||||
$vars->{'date'} = $date;
|
||||
$vars->{'reason'} = clean_text($cgi->param('reason') || '');
|
||||
$vars->{'mailrecipients'} = { 'changer' => $user->login };
|
||||
|
||||
$template->process("attachment/delete_reason.txt.tmpl", $vars, \$msg)
|
||||
|| ThrowTemplateError($template->error());
|
||||
|
||||
$dbh->bz_lock_tables('attachments WRITE', 'attach_data WRITE', 'flags WRITE');
|
||||
$dbh->do('DELETE FROM attach_data WHERE id = ?', undef, $attach_id);
|
||||
$dbh->do('UPDATE attachments SET mimetype = ?, ispatch = ?, isurl = ?
|
||||
WHERE attach_id = ?', undef, ('text/plain', 0, 0, $attach_id));
|
||||
$dbh->do('DELETE FROM flags WHERE attach_id = ?', undef, $attach_id);
|
||||
$dbh->bz_unlock_tables;
|
||||
|
||||
# If the attachment is stored locally, remove it.
|
||||
if (-e $attachment->_get_local_filename) {
|
||||
unlink $attachment->_get_local_filename;
|
||||
}
|
||||
|
||||
# Now delete the token.
|
||||
Bugzilla::Token::DeleteToken($token);
|
||||
|
||||
# Paste the reason provided by the admin into a comment.
|
||||
AppendComment($bug_id, $user->id, $msg);
|
||||
|
||||
$template->process("attachment/updated.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
else {
|
||||
# Create a token.
|
||||
$token = Bugzilla::Token::IssueSessionToken('attachment' . $attach_id);
|
||||
|
||||
$vars->{'a'} = $attachment;
|
||||
$vars->{'token'} = $token;
|
||||
|
||||
$template->process("attachment/confirm-delete.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,13 @@
|
|||
%]
|
||||
|
||||
[% param_descs = {
|
||||
allow_attachment_deletion => "If this option is on, administrators will be able to delete " _
|
||||
"the content of attachments.",
|
||||
|
||||
allow_attach_url => "If this option is on, it will be possible to " _
|
||||
"specify a URL when creating an attachment and " _
|
||||
"treat the URL itself as if it were an attachment.",
|
||||
|
||||
maxpatchsize => "The maximum size (in kilobytes) of patches. $terms.Bugzilla will not " _
|
||||
"accept patches greater than this number of kilobytes in size. " _
|
||||
"To accept patches of any size (subject to the limitations of " _
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
[%# 1.0@bugzilla.org %]
|
||||
[%# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Bugzilla Bug Tracking System.
|
||||
#
|
||||
# Contributor(s): Frédéric Buclin <LpSolit@gmail.com>
|
||||
#%]
|
||||
|
||||
[%# INTERFACE:
|
||||
# a: attachment object; attachment the user wants to delete.
|
||||
# token: string; The token used to identify the session.
|
||||
#%]
|
||||
|
||||
[% PROCESS global/variables.none.tmpl %]
|
||||
|
||||
[% title = BLOCK %]
|
||||
Delete Attachment [% a.id FILTER html %] of
|
||||
[%+ "$terms.Bug " _ a.bug_id FILTER bug_link(a.bug_id) FILTER none %]
|
||||
[% END %]
|
||||
|
||||
[% PROCESS global/header.html.tmpl title = title %]
|
||||
|
||||
<table border="1" cellpadding="4" cellspacing="0">
|
||||
<tr bgcolor="#6666FF">
|
||||
<th valign="top" align="left">Field</th>
|
||||
<th valign="top" align="left">Value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">Attachment ID:</td>
|
||||
<td valign="top">
|
||||
<a href="attachment.cgi?id=[% a.id FILTER html %]">[% a.id FILTER html %]</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">File name:</td>
|
||||
<td valign="top">[% a.filename FILTER html %]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">Description:</td>
|
||||
<td valign="top">[% a.description FILTER html %]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">Contained in [% terms.Bug %]:</td>
|
||||
<td valign="top">[% a.bug_id FILTER bug_link(a.bug_id) FILTER none %]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">Creator:</td>
|
||||
<td valign="top">[% a.attacher.identity FILTER html %]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">Creation Date:</td>
|
||||
<td valign="top">[% a.attached FILTER time %]</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Confirmation</h2>
|
||||
|
||||
<table border="0" cellpadding="20" width="70%" bgcolor="red">
|
||||
<tr>
|
||||
<td>
|
||||
The content of this attachment will be deleted in a <b>irreversible</b> way.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Do you really want to delete this attachment?</p>
|
||||
|
||||
<form action="attachment.cgi" method="POST">
|
||||
<label for="reason">Reason of the deletion:</label>
|
||||
<input type="text" id="reason" name="reason" value="" size="80" maxlength="200">
|
||||
<p>
|
||||
<input type="submit" value="Yes, delete">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<input type="hidden" name="id" value="[% a.id FILTER html %]">
|
||||
<input type="hidden" name="token" value="[% token FILTER html %]">
|
||||
</form>
|
||||
|
||||
<p>
|
||||
No, cancel this deletion and return to
|
||||
[%+ "$terms.bug " _ a.bug_id FILTER bug_link(a.bug_id) FILTER none %].
|
||||
</p>
|
||||
|
||||
[% PROCESS global/footer.html.tmpl %]
|
|
@ -0,0 +1,33 @@
|
|||
[%# 1.0@bugzilla.org %]
|
||||
[%# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Bugzilla Bug Tracking System.
|
||||
#
|
||||
# Contributor(s): Frédéric Buclin <LpSolit@gmail.com>
|
||||
#%]
|
||||
|
||||
[%# INTERFACE:
|
||||
# attachid: ID of the attachment the user wants to delete.
|
||||
# reason: string; The reason provided by the user.
|
||||
# date: the date when the request to delete the attachment was made.
|
||||
#%]
|
||||
|
||||
The content of attachment [% attachid %] has been deleted by
|
||||
[%+ user.identity %]
|
||||
[% IF reason %]
|
||||
who provided the following reason:
|
||||
|
||||
[%+ reason %]
|
||||
[% ELSE %]
|
||||
without providing any reason.
|
||||
[% END %]
|
||||
|
||||
The token used to delete this attachment was generated at [% date FILTER time %].
|
|
@ -229,7 +229,12 @@
|
|||
<b>Filename:</b><br>
|
||||
<input type="text" size="20" name="filename"
|
||||
value="[% attachment.filename FILTER html %]"><br>
|
||||
<b>Size: </b>[% attachment.datasize FILTER unitconvert %]<br>
|
||||
<b>Size:</b>
|
||||
[% IF attachment.datasize %]
|
||||
[%+ attachment.datasize FILTER unitconvert %]
|
||||
[% ELSE %]
|
||||
<em>deleted</em>
|
||||
[% END %]<br>
|
||||
|
||||
<b>MIME Type:</b><br>
|
||||
<input type="text" size="20" name="contenttypeentry"
|
||||
|
@ -269,10 +274,17 @@
|
|||
[% IF attachment.ispatch && patchviewerinstalled %]
|
||||
| <a href="attachment.cgi?id=[% attachment.id %]&action=diff">Diff</a>
|
||||
[% END %]
|
||||
[% IF Param("allow_attachment_deletion")
|
||||
&& user.groups.admin
|
||||
&& attachment.datasize > 0 %]
|
||||
| <a href="attachment.cgi?id=[% attachment.id %]&action=delete">Delete</a>
|
||||
[% END %]
|
||||
</small>
|
||||
</td>
|
||||
|
||||
[% IF isviewable %]
|
||||
[% IF !attachment.datasize %]
|
||||
<td width="75%"><b>The content of this attachment has been deleted.</b></td>
|
||||
[% ELSIF isviewable %]
|
||||
<td width="75%">
|
||||
[% INCLUDE global/textarea.html.tmpl
|
||||
id = 'editFrame'
|
||||
|
|
|
@ -56,7 +56,13 @@
|
|||
</a>
|
||||
</td>
|
||||
<td valign="top">[% attachment.attached FILTER time %]</td>
|
||||
<td valign="top">[% attachment.datasize FILTER unitconvert %]</td>
|
||||
<td valign="top">
|
||||
[% IF attachment.datasize %]
|
||||
[% attachment.datasize FILTER unitconvert %]
|
||||
[% ELSE %]
|
||||
<em>deleted</em>
|
||||
[% END %]
|
||||
</td>
|
||||
|
||||
[% IF show_attachment_flags %]
|
||||
<td valign="top">
|
||||
|
|
|
@ -194,6 +194,10 @@
|
|||
versions
|
||||
[% END %].
|
||||
|
||||
[% ELSIF error == "attachment_deletion_disabled" %]
|
||||
[% title = "Attachment Deletion Disabled" %]
|
||||
Attachment deletion is disabled on this installation.
|
||||
|
||||
[% ELSIF error == "attachment_removed" %]
|
||||
[% title = "Attachment Removed" %]
|
||||
The attachment you are attempting to access has been removed.
|
||||
|
|
Загрузка…
Ссылка в новой задаче