diff options
author | lpsolit%gmail.com <> | 2006-07-25 08:22:53 +0200 |
---|---|---|
committer | lpsolit%gmail.com <> | 2006-07-25 08:22:53 +0200 |
commit | 2904ac3261ff9bb59e29b74d55d4ada294986ffe (patch) | |
tree | c3c5b3a99f23f76502eac1e652044a550ba19371 /Bugzilla | |
parent | bea873a66d06670af744b29d9e8d357ae3b5ceed (diff) | |
download | bugzilla-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.pm | 124 | ||||
-rw-r--r-- | Bugzilla/Component.pm | 32 | ||||
-rw-r--r-- | Bugzilla/Error.pm | 2 | ||||
-rw-r--r-- | Bugzilla/Product.pm | 28 |
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 |