From f617b2ff0a1ef840ec004fb7669ff14f455058aa Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Fri, 3 Nov 2006 03:59:15 +0000 Subject: Bug 355837: Make the webservice able to create bugs Patch By Max Kanat-Alexander r=mbd, a=justdave --- Bugzilla/Bug.pm | 35 ++++--- Bugzilla/WebService/Bug.pm | 200 +++++++++++++++++++++++++++++++++++++++ Bugzilla/WebService/Constants.pm | 22 +++++ 3 files changed, 246 insertions(+), 11 deletions(-) diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index bddd11b47..18f8316a9 100755 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -100,8 +100,8 @@ sub DB_COLUMNS { use constant REQUIRED_CREATE_FIELDS => qw( bug_severity + comment component - creation_ts op_sys priority product @@ -319,9 +319,18 @@ sub create { # And insert the comment. We always insert a comment on bug creation, # but sometimes it's blank. - $dbh->do('INSERT INTO longdescs (bug_id, who, bug_when, thetext, isprivate) - VALUES (?, ?, ?, ?, ?)', undef, - $bug->bug_id, $bug->{reporter_id}, $timestamp, $comment, $privacy); + my @columns = qw(bug_id who bug_when thetext); + my @values = ($bug->bug_id, $bug->{reporter_id}, $timestamp, $comment); + # We don't include the "isprivate" column unless it was specified. + # This allows it to fall back to its database default. + if (defined $privacy) { + push(@columns, 'isprivate'); + push(@values, $privacy); + } + my $qmarks = "?," x @columns; + chop($qmarks); + $dbh->do('INSERT INTO longdescs (' . join(',', @columns) . ") + VALUES ($qmarks)", undef, @values); $dbh->bz_unlock_tables(); @@ -361,8 +370,12 @@ sub run_create_validators { # Callers cannot set Reporter, currently. $params->{reporter} = Bugzilla->user->id; + $params->{creation_ts} ||= Bugzilla->dbh->selectrow_array('SELECT NOW()'); $params->{delta_ts} = $params->{creation_ts}; - $params->{remaining_time} = $params->{estimated_time}; + + if ($params->{estimated_time}) { + $params->{remaining_time} = $params->{estimated_time}; + } $class->_check_strict_isolation($product, $params->{cc}, $params->{assigned_to}, $params->{qa_contact}); @@ -370,6 +383,12 @@ sub run_create_validators { ($params->{dependson}, $params->{blocked}) = $class->_check_dependencies($params->{dependson}, $params->{blocked}); + # You can't set these fields on bug creation (or sometimes ever). + delete $params->{resolution}; + delete $params->{votes}; + delete $params->{lastdiffed}; + delete $params->{bug_id}; + return $params; } @@ -562,9 +581,6 @@ sub _check_component { $name = trim($name); $name || ThrowUserError("require_component"); my $obj = Bugzilla::Component::check_component($product, $name); - # XXX Right now, post_bug needs this to return an object. However, - # when we move to Bugzilla::Bug->create, this should just return - # what it was passed. return $obj; } @@ -682,9 +698,6 @@ sub _check_product { # can_enter_product already does everything that check_product # would do for us, so we don't need to use it. my $obj = new Bugzilla::Product({ name => $name }); - # XXX Right now, post_bug needs this to return an object. However, - # when we move to Bugzilla::Bug->create, this should just return - # what it was passed. return $obj; } diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index 6698fdc97..d61448d7d 100755 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -13,15 +13,38 @@ # The Original Code is the Bugzilla Bug Tracking System. # # Contributor(s): Marc Schumann +# Max Kanat-Alexander package Bugzilla::WebService::Bug; use strict; use base qw(Bugzilla::WebService); +import SOAP::Data qw(type); use Bugzilla::WebService::Constants; use Bugzilla::Util qw(detaint_natural); use Bugzilla::Bug; +use Bugzilla::BugMail; +use Bugzilla::Constants; + +############# +# Constants # +############# + +# This maps the names of internal Bugzilla bug fields to things that would +# make sense to somebody who's not intimately familiar with the inner workings +# of Bugzilla. (These are the field names that the WebService uses.) +use constant FIELD_MAP => { + status => 'bug_status', + severity => 'bug_severity', + description => 'comment', + summary => 'short_desc', + platform => 'rep_platform', +}; + +########### +# Methods # +########### sub get_bug { my $self = shift; @@ -33,4 +56,181 @@ sub get_bug { return new Bugzilla::Bug($bug_id); } + +sub create { + my ($self, $params) = @_; + + Bugzilla->login(LOGIN_REQUIRED); + + my %field_values; + foreach my $field (keys %$params) { + my $field_name = FIELD_MAP->{$field} || $field; + $field_values{$field_name} = $params->{$field}; + } + + # Make sure all the required fields are in the hash. + foreach my $field (Bugzilla::Bug::REQUIRED_CREATE_FIELDS) { + $field_values{$field} = undef unless exists $field_values{$field}; + } + + # WebService users can't set the creation date of a bug. + delete $field_values{'creation_ts'}; + + my $bug = Bugzilla::Bug->create(\%field_values); + + Bugzilla::BugMail::Send($bug->bug_id, { changer => $bug->reporter->login }); + + return { id => type('int')->value($bug->bug_id) }; +} + 1; + +__END__ + +=head1 NAME + +Bugzilla::Webservice::Bug - The API for creating, changing, and getting the +details of bugs. + +=head1 DESCRIPTION + +This part of the Bugzilla API allows you to file a new bug in Bugzilla. + +=head1 METHODS + +See L for a description of B, B, +and B. + +=over + +=item C B + +=over + +=item B + +This allows you to create a new bug in Bugzilla. If you specify any +invalid fields, they will be ignored. If you specify any fields you +are not allowed to set, they will just be set to their defaults or ignored. + +You cannot currently set all the items here that you can set on enter_bug.cgi. + +The WebService interface may allow you to set things other than those listed +here, but realize that anything undocumented is B and will very +likely change in the future. + +=item B + +Some params must be set, or an error will be thrown. These params are +marked B. + +Some parameters can have defaults set in Bugzilla, by the administrator. +If these parameters have defaults set, you can omit them. These parameters +are marked B. + +Clients that want to be able to interact uniformly with multiple +Bugzillas should always set both the params marked B and those +marked B, because some Bugzillas may not have defaults set +for B parameters, and then this method will throw an error +if you don't specify them. + +The descriptions of the parameters below are what they mean when Bugzilla is +being used to track software bugs. They may have other meanings in some +installations. + +=over + +=item C (string) B - The name of the product the bug +is being filed against. + +=item C (string) B - The name of a component in the +product above. + +=item C (string) B - A brief description of the bug being +filed. + +=item C (string) B - A version of the product above; +the version the bug was found in. + +=item C (string) B - The initial description for +this bug. Some Bugzilla installations require this to not be blank. + +=item C (string) B - The operating system the bug was +discovered on. + +=item C (string) B - What type of hardware the bug was +experienced on. + +=item C (string) B - What order the bug will be fixed +in by the developer, compared to the developer's other bugs. + +=item C (string) B - How severe the bug is. + +=item C (string) - A brief alias for the bug that can be used +instead of a bug number when accessing this bug. Must be unique in +all of this Bugzilla. + +=item C (username) - A user to assign this bug to, if you +don't want it to be assigned to the component owner. + +=item C (array) - An array of usernames to CC on this bug. + +=item C (username) - If this installation has QA Contacts +enabled, you can set the QA Contact here if you don't want to use +the component's default QA Contact. + +=item C (string) - The status that this bug should start out as. +Note that only certain statuses can be set on bug creation. + +=item C (string) - A valid target milestone for this +product. + +=back + +In addition to the above parameters, if your installation has any custom +fields, you can set them just by passing in the name of the field and +its value as a string. + +=item B + +A hash with one element, C. This is the id of the newly-filed bug. + +=item B + +=over + +=item 103 (Invalid Alias) + +The alias you specified is invalid for some reason. See the error message +for more details. + +=item 104 (Invalid Field) + +One of the drop-down fields has an invalid value. The error message will +have more detail. + +=item 105 (Invalid Component) + +Either you didn't specify a component, or the component you specified was +invalid. + +=item 106 (Invalid Product) + +Either you didn't specify a product, this product doesn't exist, or +you don't have permission to enter bugs in this product. + +=item 107 (Invalid Summary) + +You didn't specify a summary for the bug. + +=item 504 (Invalid User) + +Either the QA Contact, Assignee, or CC lists have some invalid user +in them. The error message will have more details. + +=back + +=back + + +=back diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm index ba26f3bfa..e0bb05e5a 100755 --- a/Bugzilla/WebService/Constants.pm +++ b/Bugzilla/WebService/Constants.pm @@ -52,6 +52,24 @@ use constant WS_ERROR_CODE => { invalid_bug_id_or_alias => 100, invalid_bug_id_non_existent => 101, bug_access_denied => 102, + # These all mean "invalid alias" + alias_not_defined => 103, + alias_too_long => 103, + alias_in_use => 103, + alias_is_numeric => 103, + alias_has_comma_or_space => 103, + # Misc. bug field errors + illegal_field => 104, + # Component errors + require_component => 105, + component_name_too_long => 105, + component_not_valid => 105, + # Invalid Product + no_products => 106, + entry_access_denied => 106, + product_disabled => 106, + # Invalid Summary + require_summary => 107, # Authentication errors are usually 300-400. invalid_username_or_password => 300, @@ -64,6 +82,10 @@ use constant WS_ERROR_CODE => { illegal_email_address => 501, password_too_short => 502, password_too_long => 503, + invalid_username => 504, + # This is from strict_isolation, but it also basically means + # "invalid user." + invalid_user_group => 504, }; # These are the fallback defaults for errors not in ERROR_CODE. -- cgit v1.2.3-24-g4f1b