summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorlpsolit%gmail.com <>2006-07-25 08:22:53 +0200
committerlpsolit%gmail.com <>2006-07-25 08:22:53 +0200
commit2904ac3261ff9bb59e29b74d55d4ada294986ffe (patch)
treec3c5b3a99f23f76502eac1e652044a550ba19371 /Bugzilla
parentbea873a66d06670af744b29d9e8d357ae3b5ceed (diff)
downloadbugzilla-2904ac3261ff9bb59e29b74d55d4ada294986ffe.tar.gz
bugzilla-2904ac3261ff9bb59e29b74d55d4ada294986ffe.tar.xz
Bug 174039: Set flags on bug entry - Patch by Frédéric Buclin <LpSolit@gmail.com> r=wurblzap r=myk a=myk
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Attachment.pm124
-rw-r--r--Bugzilla/Component.pm32
-rw-r--r--Bugzilla/Error.pm2
-rw-r--r--Bugzilla/Product.pm28
4 files changed, 176 insertions, 10 deletions
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index f012c3f2e..90ec68974 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -51,7 +51,8 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Flag;
use Bugzilla::User;
-use Bugzilla::Util qw(trick_taint);
+use Bugzilla::Util;
+use Bugzilla::Field;
sub get {
my $invocant = shift;
@@ -594,12 +595,89 @@ sub validate_content_type {
=pod
-=item C<insert_attachment_for_bug($throw_error, $bug_id, $user, $timestamp, $hr_vars)>
+=item C<validate_can_edit()>
+
+Description: validates if the user is allowed to edit the attachment.
+ Only the submitter or someone with editbugs privs can edit it.
+
+Returns: 1 on success. Else an error is thrown.
+
+=cut
+
+sub validate_can_edit {
+ my ($class, $attach_id) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+
+ # People in editbugs can edit all attachments
+ return if $user->in_group('editbugs');
+
+ # Bug 97729 - the submitter can edit their attachments
+ my ($ref) = $dbh->selectrow_array('SELECT attach_id FROM attachments
+ WHERE attach_id = ? AND submitter_id = ?',
+ undef, ($attach_id, $user->id));
+
+ $ref || ThrowUserError('illegal_attachment_edit', { attach_id => $attach_id });
+}
+
+=item C<validate_obsolete($bug_id)>
+
+Description: validates if attachments the user wants to mark as obsolete
+ really belong to the given bug and are not already obsolete.
+
+Params: $bug_id - The bug ID obsolete attachments should belong to.
+
+Returns: 1 on success. Else an error is thrown.
+
+=cut
+
+sub validate_obsolete {
+ my ($class, $bug_id) = @_;
+ my $cgi = Bugzilla->cgi;
+
+ # Make sure the attachment id is valid and the user has permissions to view
+ # the bug to which it is attached.
+ my @obsolete_attachments;
+ foreach my $attachid ($cgi->param('obsolete')) {
+ my $vars = {};
+ $vars->{'attach_id'} = $attachid;
+
+ detaint_natural($attachid)
+ || ThrowCodeError('invalid_attach_id_to_obsolete', $vars);
+
+ my $attachment = Bugzilla::Attachment->get($attachid);
+
+ # Make sure the attachment exists in the database.
+ ThrowUserError('invalid_attach_id', $vars) unless $attachment;
+
+ $vars->{'description'} = $attachment->description;
+
+ if ($attachment->bug_id != $bug_id) {
+ $vars->{'my_bug_id'} = $bug_id;
+ $vars->{'attach_bug_id'} = $attachment->bug_id;
+ ThrowCodeError('mismatched_bug_ids_on_obsolete', $vars);
+ }
+
+ if ($attachment->isobsolete) {
+ ThrowCodeError('attachment_already_obsolete', $vars);
+ }
+
+ # Check that the user can modify this attachment.
+ $class->validate_can_edit($attachid);
+ push(@obsolete_attachments, $attachment);
+ }
+ return @obsolete_attachments;
+}
+
+
+=pod
+
+=item C<insert_attachment_for_bug($throw_error, $bug, $user, $timestamp, $hr_vars)>
Description: inserts an attachment from CGI input for the given bug.
-Params: C<$bug_id> - integer - the ID of the bug for which
- to insert the attachment.
+Params: C<$bug> - Bugzilla::Bug object - the bug for which to insert
+ the attachment.
C<$user> - Bugzilla::User object - the user we're inserting an
attachment for.
C<$timestamp> - scalar - timestamp of the insert as returned
@@ -614,7 +692,7 @@ Returns: the ID of the new attachment.
=cut
sub insert_attachment_for_bug {
- my ($class, $throw_error, $bug_id, $user, $timestamp, $hr_vars) = @_;
+ my ($class, $throw_error, $bug, $user, $timestamp, $hr_vars) = @_;
my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
@@ -671,8 +749,8 @@ sub insert_attachment_for_bug {
# Setting the third param to -1 will force this function to check this
# point.
# XXX needs $throw_error treatment
- Bugzilla::Flag::validate($cgi, $bug_id, -1);
- Bugzilla::FlagType::validate($cgi, $bug_id, -1);
+ Bugzilla::Flag::validate($cgi, $bug->bug_id, -1);
+ Bugzilla::FlagType::validate($cgi, $bug->bug_id, -1);
# Escape characters in strings that will be used in SQL statements.
my $description = $cgi->param('description');
@@ -684,7 +762,7 @@ sub insert_attachment_for_bug {
"INSERT INTO attachments
(bug_id, creation_ts, filename, description,
mimetype, ispatch, isurl, isprivate, submitter_id)
- VALUES (?,?,?,?,?,?,?,?,?)", undef, ($bug_id, $timestamp, $filename,
+ VALUES (?,?,?,?,?,?,?,?,?)", undef, ($bug->bug_id, $timestamp, $filename,
$description, $contenttype, $cgi->param('ispatch'),
$isurl, $isprivate, $user->id));
# Retrieve the ID of the newly created attachment record.
@@ -724,6 +802,36 @@ sub insert_attachment_for_bug {
close AH;
close $fh;
}
+
+ # Now handle flags.
+ my @obsolete_attachments;
+ if ($cgi->param('obsolete')) {
+ @obsolete_attachments = $class->validate_obsolete($bug->bug_id);
+ }
+
+ # Make existing attachments obsolete.
+ my $fieldid = get_field_id('attachments.isobsolete');
+
+ foreach my $obsolete_attachment (@obsolete_attachments) {
+ # If the obsolete attachment has request flags, cancel them.
+ # This call must be done before updating the 'attachments' table.
+ Bugzilla::Flag::CancelRequests($bug, $obsolete_attachment, $timestamp);
+
+ $dbh->do('UPDATE attachments SET isobsolete = 1 WHERE attach_id = ?',
+ undef, $obsolete_attachment->id);
+
+ $dbh->do('INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
+ fieldid, removed, added)
+ VALUES (?,?,?,?,?,?,?)',
+ undef, ($bug->bug_id, $obsolete_attachment->id, $user->id,
+ $timestamp, $fieldid, 0, 1));
+ }
+
+ # Create flags.
+ my $attachment = Bugzilla::Attachment->get($attachid);
+ Bugzilla::Flag::process($bug, $attachment, $timestamp, $cgi);
+
+ # Return the ID of the new attachment.
return $attachid;
}
diff --git a/Bugzilla/Component.pm b/Bugzilla/Component.pm
index 827be789d..abd3711f5 100644
--- a/Bugzilla/Component.pm
+++ b/Bugzilla/Component.pm
@@ -13,7 +13,7 @@
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Tiago R. Mello <timello@async.com.br>
-#
+# Frédéric Buclin <LpSolit@gmail.com>
use strict;
@@ -22,6 +22,7 @@ package Bugzilla::Component;
use Bugzilla::Util;
use Bugzilla::Error;
use Bugzilla::User;
+use Bugzilla::FlagType;
###############################
#### Initialization ####
@@ -135,6 +136,24 @@ sub default_qa_contact {
return $self->{'default_qa_contact'};
}
+sub flag_types {
+ my $self = shift;
+
+ if (!defined $self->{'flag_types'}) {
+ $self->{'flag_types'} = {};
+ $self->{'flag_types'}->{'bug'} =
+ Bugzilla::FlagType::match({ 'target_type' => 'bug',
+ 'product_id' => $self->product_id,
+ 'component_id' => $self->id });
+
+ $self->{'flag_types'}->{'attachment'} =
+ Bugzilla::FlagType::match({ 'target_type' => 'attachment',
+ 'product_id' => $self->product_id,
+ 'component_id' => $self->id });
+ }
+ return $self->{'flag_types'};
+}
+
###############################
#### Accessors ####
###############################
@@ -193,6 +212,8 @@ Bugzilla::Component - Bugzilla product component class.
my $product_id = $component->product_id;
my $default_assignee = $component->default_assignee;
my $default_qa_contact = $component->default_qa_contact;
+ my $bug_flag_types = $component->flag_types->{'bug'};
+ my $attach_flag_types = $component->flag_types->{'attachment'};
my $component = Bugzilla::Component::check_component($product, 'AcmeComp');
@@ -252,6 +273,15 @@ Component.pm represents a Product Component object.
Returns: A Bugzilla::User object.
+=item C<flag_types()>
+
+ Description: Returns all bug and attachment flagtypes available for
+ the component.
+
+ Params: none.
+
+ Returns: Two references to an array of flagtype objects.
+
=back
=head1 SUBROUTINES
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm
index 5498f7670..b88c4eeb8 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -78,7 +78,7 @@ sub _throw_error {
my $message;
$template->process($name, $vars, \$message)
|| ThrowTemplateError($template->error());
- die("$message");
+ die("$message\n");
} else {
print Bugzilla->cgi->header();
$template->process($name, $vars)
diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm
index 995369130..b025cd7cb 100644
--- a/Bugzilla/Product.pm
+++ b/Bugzilla/Product.pm
@@ -177,6 +177,24 @@ sub user_has_access {
undef, $self->id);
}
+sub flag_types {
+ my $self = shift;
+
+ if (!defined $self->{'flag_types'}) {
+ $self->{'flag_types'} = {};
+ foreach my $type ('bug', 'attachment') {
+ my %flagtypes;
+ foreach my $component (@{$self->components}) {
+ foreach my $flagtype (@{$component->flag_types->{$type}}) {
+ $flagtypes{$flagtype->{'id'}} ||= $flagtype;
+ }
+ }
+ $self->{'flag_types'}->{$type} = [sort { $a->{'sortkey'} <=> $b->{'sortkey'}
+ || $a->{'name'} cmp $b->{'name'} } values %flagtypes];
+ }
+ }
+ return $self->{'flag_types'};
+}
###############################
#### Accessors ######
@@ -231,6 +249,7 @@ Bugzilla::Product - Bugzilla product class.
my $bugcount = $product->bug_count();
my $bug_ids = $product->bug_ids();
my $has_access = $product->user_has_access($user);
+ my $flag_types = $product->flag_types();
my $id = $product->id;
my $name = $product->name;
@@ -320,6 +339,15 @@ below.
Returns C<1> If this user's groups allow him C<entry> access to
this Product, C<0> otherwise.
+=item C<flag_types()>
+
+ Description: Returns flag types available for at least one of
+ its components.
+
+ Params: none.
+
+ Returns: Two references to an array of flagtype objects.
+
=back
=head1 SUBROUTINES