Commit a86ee3a1 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 432907: Create a JSON frontend for WebServices

Patch by Max Kanat-Alexander <mkanat@bugzilla.org> r=dkl, a=mkanat
parent 470f355d
......@@ -360,6 +360,15 @@ sub error_mode {
|| (i_am_cgi() ? ERROR_MODE_WEBPAGE : ERROR_MODE_DIE);
}
# This is used only by Bugzilla::Error to throw errors.
sub _json_server {
my ($class, $newval) = @_;
if (defined $newval) {
$class->request_cache->{_json_server} = $newval;
}
return $class->request_cache->{_json_server};
}
sub usage_mode {
my ($class, $newval) = @_;
if (defined $newval) {
......@@ -369,9 +378,12 @@ sub usage_mode {
elsif ($newval == USAGE_MODE_CMDLINE) {
$class->error_mode(ERROR_MODE_DIE);
}
elsif ($newval == USAGE_MODE_WEBSERVICE) {
elsif ($newval == USAGE_MODE_XMLRPC) {
$class->error_mode(ERROR_MODE_DIE_SOAP_FAULT);
}
elsif ($newval == USAGE_MODE_JSON) {
$class->error_mode(ERROR_MODE_JSON_RPC);
}
elsif ($newval == USAGE_MODE_EMAIL) {
$class->error_mode(ERROR_MODE_DIE);
}
......@@ -667,10 +679,11 @@ usage mode changes.
=item C<usage_mode>
Call either C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)>
or C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_WEBSERVICE)> near the
or C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_XMLRPC)> near the
beginning of your script to change this flag's default of
C<Bugzilla::Constants::USAGE_MODE_BROWSER> and to indicate that Bugzilla is
being called in a non-interactive manner.
This influences error handling because on usage mode changes, C<usage_mode>
calls C<Bugzilla->error_mode> to set an error mode which makes sense for the
usage mode.
......
......@@ -347,10 +347,10 @@ sub require_https {
my ($self, $url) = @_;
# Do not create query string if data submitted via XMLRPC
# since we want the data to be resubmitted over POST method.
my $query = Bugzilla->usage_mode == USAGE_MODE_WEBSERVICE ? 0 : 1;
my $query = Bugzilla->usage_mode == USAGE_MODE_XMLRPC ? 0 : 1;
# XMLRPC clients (SOAP::Lite at least) requires 301 to redirect properly
# and do not work with 302.
my $status = Bugzilla->usage_mode == USAGE_MODE_WEBSERVICE ? 301 : 302;
my $status = Bugzilla->usage_mode == USAGE_MODE_XMLRPC ? 301 : 302;
if (defined $url) {
$url .= $self->url('-path_info' => 1, '-query' => $query, '-relative' => 1);
} else {
......
......@@ -128,12 +128,14 @@ use File::Basename;
USAGE_MODE_BROWSER
USAGE_MODE_CMDLINE
USAGE_MODE_WEBSERVICE
USAGE_MODE_XMLRPC
USAGE_MODE_EMAIL
USAGE_MODE_JSON
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
ERROR_MODE_DIE_SOAP_FAULT
ERROR_MODE_JSON_RPC
INSTALLATION_MODE_INTERACTIVE
INSTALLATION_MODE_NON_INTERACTIVE
......@@ -378,14 +380,16 @@ use constant SAFE_PROTOCOLS => ('afs', 'cid', 'ftp', 'gopher', 'http', 'https',
# Usage modes. Default USAGE_MODE_BROWSER. Use with Bugzilla->usage_mode.
use constant USAGE_MODE_BROWSER => 0;
use constant USAGE_MODE_CMDLINE => 1;
use constant USAGE_MODE_WEBSERVICE => 2;
use constant USAGE_MODE_XMLRPC => 2;
use constant USAGE_MODE_EMAIL => 3;
use constant USAGE_MODE_JSON => 4;
# Error modes. Default set by Bugzilla->usage_mode (so ERROR_MODE_WEBPAGE
# usually). Use with Bugzilla->error_mode.
use constant ERROR_MODE_WEBPAGE => 0;
use constant ERROR_MODE_DIE => 1;
use constant ERROR_MODE_DIE_SOAP_FAULT => 2;
use constant ERROR_MODE_JSON_RPC => 3;
# The various modes that checksetup.pl can run in.
use constant INSTALLATION_MODE_INTERACTIVE => 0;
......
......@@ -101,7 +101,9 @@ sub _throw_error {
if (Bugzilla->error_mode == ERROR_MODE_DIE) {
die("$message\n");
}
elsif (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) {
elsif (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT
|| Bugzilla->error_mode == ERROR_MODE_JSON_RPC)
{
# Clone the hash so we aren't modifying the constant.
my %error_map = %{ WS_ERROR_CODE() };
require Bugzilla::Hook;
......@@ -112,8 +114,20 @@ sub _throw_error {
$code = ERROR_UNKNOWN_FATAL if $name =~ /code/i;
$code = ERROR_UNKNOWN_TRANSIENT if $name =~ /user/i;
}
if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) {
die SOAP::Fault->faultcode($code)->faultstring($message);
}
else {
my $server = Bugzilla->_json_server;
# Technically JSON-RPC isn't allowed to have error numbers
# higher than 999, but we do this to avoid conflicts with
# the internal JSON::RPC error codes.
$server->raise_error(code => 100000 + $code,
message => $message);
$server->response($server->error_response_header);
}
}
}
exit;
}
......
......@@ -226,6 +226,12 @@ sub OPTIONAL_MODULES {
feature => 'XML-RPC Interface'
},
{
package => 'JSON-RPC',
module => 'JSON::RPC',
version => 0,
feature => 'JSON-RPC Interface'
},
{
# We need the 'utf8_mode' method of HTML::Parser, for HTML::Scrubber.
package => 'HTML-Parser',
module => 'HTML::Parser',
......
......@@ -219,7 +219,12 @@ sub _do_list_select {
$sql .= " $postamble" if $postamble;
my $dbh = Bugzilla->dbh;
my $objects = $dbh->selectall_arrayref($sql, {Slice=>{}}, @$values);
# Sometimes the values are tainted, but we don't want to untaint them
# for the caller. So we copy the array. It's safe to untaint because
# they're only used in placeholders here.
my @untainted = @{ $values || [] };
trick_taint($_) foreach @untainted;
my $objects = $dbh->selectall_arrayref($sql, {Slice=>{}}, @untainted);
bless ($_, $class) foreach @$objects;
return $objects
}
......
......@@ -22,17 +22,8 @@ use strict;
use Date::Parse;
use XMLRPC::Lite;
sub datetime_format {
my ($self, $date_string) = @_;
my $time = str2time($date_string);
my ($sec, $min, $hour, $mday, $mon, $year) = localtime $time;
# This format string was stolen from SOAP::Utils->format_datetime,
# which doesn't work but which has almost the right format string.
my $iso_datetime = sprintf('%d%02d%02dT%02d:%02d:%02d',
$year + 1900, $mon + 1, $mday, $hour, $min, $sec);
return $iso_datetime;
}
# Used by the JSON-RPC server to convert incoming date fields apprpriately.
use constant DATE_FIELDS => {};
# For some methods, we shouldn't call Bugzilla->login before we call them
use constant LOGIN_EXEMPT => { };
......@@ -63,85 +54,84 @@ Bugzilla::WebService - The Web Service interface to Bugzilla
This is the standard API for external programs that want to interact
with Bugzilla. It provides various methods in various modules.
Currently the only method of accessing the API is via XML-RPC. The XML-RPC
standard is described here: L<http://www.xmlrpc.com/spec>
The endpoint for Bugzilla WebServices is the C<xmlrpc.cgi> script in
your Bugzilla installation. For example, if your Bugzilla is at
C<bugzilla.yourdomain.com>, then your XML-RPC client would access the
API via: C<http://bugzilla.yourdomain.com/xmlrpc.cgi>
You can interact with this API via
L<XML-RPC|Bugzilla::WebService::Server::XMLRPC> or
L<JSON-RPC|Bugzilla::WebService::Server::JSONRPC>.
=head1 CALLING METHODS
Methods are called in the normal XML-RPC fashion. Bugzilla does not currently
implement any extensions to the standard method of XML-RPC method calling.
Methods are grouped into "packages", like C<Bug> for
L<Bugzilla::WebService::Bug>. So, for example,
L<Bugzilla::WebService::Bug/get>, is called as C<Bug.get> in XML-RPC.
L<Bugzilla::WebService::Bug/get>, is called as C<Bug.get>.
=head1 PARAMETERS
In addition to the standard parameter types like C<int>, C<string>, etc.,
XML-RPC has two data structures, a C<< <struct> >> and an C<< <array> >>.
The Bugzilla API takes the following various types of parameters:
=over
=head2 Structs
=item C<int>
In Perl, we call a C<< <struct> >> a "hash" or a "hashref". You may see
us refer to it that way in the API documentation.
Integer. May be null.
In example code, you will see the characters C<{> and C<}> used to represent
the beginning and end of structs.
=item C<double>
For example, here's a struct in XML-RPC:
A floating-point number. May be null.
<struct>
<member>
<name>fruit</name>
<value><string>oranges</string></value>
</member>
<member>
<name>vegetable</name>
<value><string>lettuce</string></value>
</member>
</struct>
=item C<string>
In our example code in these API docs, that would look like:
A string. May be null.
{ fruit => 'oranges', vegetable => 'lettuce' }
=item C<dateTime>
=head2 Arrays
A date/time. Represented differently in different interfaces to this API.
May be null.
=item C<boolean>
True or false.
=item C<array>
An array. There may be mixed types in an array.
In example code, you will see the characters C<[> and C<]> used to
represent the beginning and end of arrays.
For example, here's an array in XML-RPC:
In our example code in these API docs, an array that contains the numbers
1, 2, and 3 would look like:
<array>
<data>
<value><i4>1</i4></value>
<value><i4>2</i4></value>
<value><i4>3</i4></value>
</data>
</array>
[1, 2, 3]
In our example code in these API docs, that would look like:
=item C<struct>
[1, 2, 3]
A mapping of keys to values. Called a "hash", "dict", or "map" in some
other programming languages. We sometimes call this a "hash" in the API
documentation.
The keys are strings, and the values can be any type.
In example code, you will see the characters C<{> and C<}> used to represent
the beginning and end of structs.
For example, a struct with an "fruit" key whose value is "oranges",
and a "vegetable" key whose value is "lettuce" would look like:
{ fruit => 'oranges', vegetable => 'lettuce' }
=back
=head2 How Bugzilla WebService Methods Take Parameters
B<All> Bugzilla WebServices functions take their parameters in
a C<< <struct> >>. Another way of saying this would be: All functions
take a single argument, a C<< <struct> >> that contains all parameters.
The names of the parameters listed in the API docs for each function are
the C<name> element for the struct C<member>s.
B<All> Bugzilla WebService functions use I<named> parameters.
The individual C<Bugzilla::WebService::Server> modules explain
how this is implemented for those frontends.
=head1 LOGGING IN
You can use L<Bugzilla::WebService::User/login> to log in as a Bugzilla
user. This issues standard HTTP cookies that you must then use in future
calls, so your XML-RPC client must be capable of receiving and transmitting
calls, so your client must be capable of receiving and transmitting
cookies.
=head1 STABLE, EXPERIMENTAL, and UNSTABLE
......@@ -164,18 +154,17 @@ Bugzilla versions.
=head1 ERRORS
If a particular webservice call fails, it will throw a standard XML-RPC
error. There will be a numeric error code, and then the description
field will contain descriptive text of the error. Each error that Bugzilla
can throw has a specific code that will not change between versions of
Bugzilla.
If a particular webservice call fails, it will throw an error in the
appropriate format for the frontend that you are using. For all frontends,
there is at least a numeric error code and descriptive text for the error.
The various errors that functions can throw are specified by the
documentation of those functions.
If your code needs to know what error Bugzilla threw, use the numeric
code. Don't try to parse the description, because that may change
from version to version of Bugzilla.
Each error that Bugzilla can throw has a specific numeric code that will
not change between versions of Bugzilla. If your code needs to know what
error Bugzilla threw, use the numeric code. Don't try to parse the
description, because that may change from version to version of Bugzilla.
Note that if you display the error to the user in an HTML program, make
sure that you properly escape the error, as it will not be HTML-escaped.
......@@ -259,21 +248,3 @@ would return something like:
{ users => [{ id => 1, real_name => 'John Smith' }] }
=back
=head1 EXTENSIONS TO THE XML-RPC STANDARD
=head2 Undefined Values
Normally, XML-RPC does not allow empty values for C<int>, C<double>, or
C<dateTime.iso8601> fields. Bugzilla does--it treats empty values as
C<undef> (called C<NULL> or C<None> in some programming languages).
Bugzilla also accepts a type called C<< <nil> >>, which is always considered
to be C<undef>, no matter what it contains.
=begin private
nil is implemented by XMLRPC::Lite, in XMLRPC::Deserializer::decode_value.
=end private
......@@ -56,6 +56,11 @@ use constant FIELD_MAP => {
use constant PRODUCT_SPECIFIC_FIELDS => qw(version target_milestone component);
use constant DATE_FIELDS => {
comments => ['new_since'],
search => ['last_change_time', 'creation_time'],
};
######################################################
# Add aliases here for old method name compatibility #
######################################################
......
......@@ -133,5 +133,4 @@ sub WS_DISPATCH {
return $dispatch;
};
1;
The class structure of these files is a little strange, and this README
explains it.
Our goal is to make JSON::RPC and XMLRPC::Lite both work with the same code.
(That is, we want to have one WebService API, and have two frontends for it.)
The problem is that these both pass different things for $self to WebService
methods.
When XMLRPC::Lite calls a method, $self is the name of the *class* the
method is in. For example, if we call Bugzilla.version(), the first argument
is Bugzilla::WebService::Bugzilla. So in order to have $self
(our first argument) act correctly in XML-RPC, we make all WebService
classes use base qw(Bugzilla::WebService).
When JSON::RPC calls a method, $self is the JSON-RPC *server object*. In other
words, it's an instance of Bugzilla::WebService::Server::JSONRPC. So we have
Bugzilla::WebService::Server::JSONRPC inherit from Bugzilla::WebService.
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# 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 JSON Webservices Interface.
#
# The Initial Developer of the Original Code is the San Jose State
# University Foundation. Portions created by the Initial Developer
# are Copyright (C) 2008 the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Max Kanat-Alexander <mkanat@bugzilla.org>
package Bugzilla::WebService::Server::JSONRPC;
use strict;
use base qw(JSON::RPC::Server::CGI Bugzilla::WebService::Server);
use Bugzilla::Error;
use Bugzilla::WebService::Constants;
use Date::Parse;
use DateTime;
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
Bugzilla->_json_server($self);
$self->dispatch(WS_DISPATCH);
$self->return_die_message(1);
$self->json->allow_blessed(1);
$self->json->convert_blessed(1);
# Default to JSON-RPC 1.0
$self->version(0);
return $self;
}
# Override the JSON::RPC method to return our CGI object instead of theirs.
sub cgi { return Bugzilla->cgi; }
sub type {
my ($self, $type, $value) = @_;
# This is the only type that does something special with undef.
if ($type eq 'boolean') {
return $value ? JSON::true : JSON::false;
}
return JSON::null if !defined $value;
my $retval = $value;
if ($type eq 'int') {
$retval = int($value);
}
if ($type eq 'double') {
$retval = 0.0 + $value;
}
elsif ($type eq 'string') {
# Forces string context, so that JSON will make it a string.
$retval = "$value";
}
elsif ($type eq 'dateTime') {
# str2time uses Time::Local internally, so I believe it should
# always return seconds based on the *Unix* epoch, even if the
# system doesn't use the Unix epoch.
$retval = str2time($value) * 1000;
}
# XXX Will have to implement base64 if Bugzilla starts using it.
return $retval;
}
##################
# Login Handling #
##################
# This handles dispatching our calls to the appropriate class based on
# the name of the method.
sub _find_procedure {
my $self = shift;
# This is also a good place to deny GET requests, since we can
# safely call ThrowUserError at this point.
if ($self->request->method ne 'POST') {
ThrowUserError('json_rpc_post_only');
}
my $method = shift;
$self->{_bz_method_name} = $method;
# This tricks SUPER::_find_procedure into finding the right class.
$method =~ /^(\S+)\.(\S+)$/;
$self->path_info($1);
unshift(@_, $2);
return $self->SUPER::_find_procedure(@_);
}
# This is a hacky way to do something right before methods are called.
# This is the last thing that JSON::RPC::Server::_handle calls right before
# the method is actually called.
sub _argument_type_check {
my $self = shift;
my $params = $self->SUPER::_argument_type_check(@_);
# This is the best time to do login checks.
$self->handle_login();
# If there are no parameters, we don't need to parse them.
return $params if !ref $params;
# JSON-RPC 1.0 requires all parameters to be passed as an array, so
# we just pull out the first item and assume it's an object.
if (ref $params eq 'ARRAY') {
$params = $params->[0];
}
# Now, convert dateTime fields on input.
$self->_bz_method_name =~ /^(\S+)\.(\S+)$/;
my ($class, $method) = ($1, $2);
my $pkg = $self->{dispatch_path}->{$class};
my @date_fields = @{ $pkg->DATE_FIELDS->{$method} || [] };
foreach my $field (@date_fields) {
if (defined $params->{$field}) {
my $value = $params->{$field};
if (ref $value eq 'ARRAY') {
$params->{$field} =
[ map { $self->_bz_convert_datetime($_) } @$value ];
}
else {
$params->{$field} = $self->_bz_convert_datetime($value);
}
}
}
# Bugzilla::WebService packages call internal methods like
# $self->_some_private_method. So we have to inherit from
# that class as well as this Server class.
my $new_class = ref($self) . '::' . $pkg;
my $isa_string = 'our @ISA = qw(' . ref($self) . " $pkg)";
eval "package $new_class;$isa_string;";
bless $self, $new_class;
return $params;
}
sub _bz_convert_datetime {
my ($self, $time) = @_;
my $dt = DateTime->from_epoch(epoch => ($time / 1000),
time_zone => Bugzilla->local_timezone);
return $dt->strftime('%Y-%m-%d %T');
}
sub handle_login {
my $self = shift;
my $path = $self->path_info;
my $class = $self->{dispatch_path}->{$path};
my $full_method = $self->_bz_method_name;
$full_method =~ /^\S+\.(\S+)/;
my $method = $1;
$self->SUPER::handle_login($class, $method, $full_method);
}
# _bz_method_name is stored by _find_procedure for later use.
sub _bz_method_name {
return $_[0]->{_bz_method_name};
}
1;
__END__
=head1 NAME
Bugzilla::WebService::Server::JSONRPC - The JSON-RPC Interface to Bugzilla
=head1 DESCRIPTION
This documentation describes things about the Bugzilla WebService that
are specific to JSON-RPC. For a general overview of the Bugzilla WebServices,
see L<Bugzilla::WebService>.
Please note that I<everything> about this JSON-RPC interface is
B<UNSTABLE>. If you want a stable API, please use the
C<XML-RPC|Bugzilla::WebService::Server::XMLRPC> interface.
=head1 JSON-RPC
Bugzilla supports both JSON-RPC 1.0 and 1.1. We recommend that you use
JSON-RPC 1.0 instead of 1.1, though, because 1.1 is deprecated.
At some point in the future, Bugzilla may also support JSON-RPC 2.0.
The JSON-RPC standards are described at L<http://json-rpc.org/>.
=head1 CONNECTING
The endpoint for the JSON-RPC interface is the C<jsonrpc.cgi> script in
your Bugzilla installation. For example, if your Bugzilla is at
C<bugzilla.yourdomain.com>, then your JSON-RPC client would access the
API via: C<http://bugzilla.yourdomain.com/jsonrpc.cgi>
Bugzilla only allows JSON-RPC requests over C<POST>. C<GET> requests
(or any other type of request, such as C<HEAD>) will be denied.
=head1 PARAMETERS
For JSON-RPC 1.0, the very first parameter should be an object containing
the named parameters. For example, if you were passing two named parameters,
one called C<foo> and the other called C<bar>, the C<params> element of
your JSON-RPC call would look like:
"params": [{ "foo": 1, "bar": "something" }]
For JSON-RPC 1.1, you can pass parameters either in the above fashion
or using the standard named-parameters mechanism of JSON-RPC 1.1.
C<dateTime> fields are represented as an integer number of microseconds
since the Unix epoch (January 1, 1970 UTC). They are always in the UTC
timezone.
All other types are standard JSON types.
=head1 ERRORS
All errors thrown by Bugzilla itself have 100000 added to their numeric
code. So, if the documentation says that an error is C<302>, then
it will be C<100302> when it is thrown via JSON-RPC.
Errors less than 100000 are errors thrown by the JSON-RPC library that
Bugzilla uses, not by Bugzilla.
=head1 SEE ALSO
=head2 Server Types
=over
=item L<Bugzilla::WebService::Server::XMLRPC>
=item L<Bugzilla::WebService::Server::JSONRPC>
=back
=head2 WebService Methods
=over
=item L<Bugzilla::WebService::Bug>
=item L<Bugzilla::WebService::Bugzilla>
=item L<Bugzilla::WebService::Product>
=item L<Bugzilla::WebService::User>
=back
......@@ -168,3 +168,56 @@ sub as_string {
}
1;
__END__
=head1 NAME
Bugzilla::WebService::Server::XMLRPC - The XML-RPC Interface to Bugzilla
=head1 DESCRIPTION
This documentation describes things about the Bugzilla WebService that
are specific to XML-RPC. For a general overview of the Bugzilla WebServices,
see L<Bugzilla::WebService>.
=head1 XML-RPC
The XML-RPC standard is described here: L<http://www.xmlrpc.com/spec>
=head1 CONNECTING
The endpoint for the XML-RPC interface is the C<xmlrpc.cgi> script in
your Bugzilla installation. For example, if your Bugzilla is at
C<bugzilla.yourdomain.com>, then your XML-RPC client would access the
API via: C<http://bugzilla.yourdomain.com/xmlrpc.cgi>
=head1 PARAMETERS
C<dateTime> fields are the standard C<dateTime.iso8601> XML-RPC field. They
should be in C<YYYY-MM-DDTHH:MM:SS> format (where C<T> is a literal T).
All other fields are standard XML-RPC types.
=head2 How XML-RPC WebService Methods Take Parameters
All functions take a single argument, a C<< <struct> >> that contains all parameters.
The names of the parameters listed in the API docs for each function are the
C<< <name> >> element for the struct C<< <member> >>s.
=head1 EXTENSIONS TO THE XML-RPC STANDARD
=head2 Undefined Values
Normally, XML-RPC does not allow empty values for C<int>, C<double>, or
C<dateTime.iso8601> fields. Bugzilla does--it treats empty values as
C<undef> (called C<NULL> or C<None> in some programming languages).
Bugzilla also accepts a type called C<< <nil> >>, which is always considered
to be C<undef>, no matter what it contains.
=begin private
nil is implemented by XMLRPC::Lite, in XMLRPC::Deserializer::decode_value.
=end private
\ No newline at end of file
......@@ -24,7 +24,7 @@ use warnings;
use base qw(Bugzilla::WebService);
use Bugzilla::Error;
# This can be called as Example.hello() from XML-RPC.
# This can be called as Example.hello() from the WebService.
sub hello { return 'Hello!'; }
sub throw_an_error { ThrowUserError('example_my_error') }
......
#!/usr/bin/perl -wT
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# 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 JSON Webservices Interface.
#
# The Initial Developer of the Original Code is the San Jose State
# University Foundation. Portions created by the Initial Developer
# are Copyright (C) 2008 the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Max Kanat-Alexander <mkanat@bugzilla.org>
use strict;
use lib qw(. lib);
use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::WebService::Constants;
# This eval allows runtests to pass even if JSON::RPC isn't
# installed.
eval { require Bugzilla::WebService::Server::JSONRPC; };
$@ && ThrowCodeError('json_rpc_not_installed');
Bugzilla->usage_mode(USAGE_MODE_JSON);
local @INC = (bz_locations()->{extensionsdir}, @INC);
my $server = new Bugzilla::WebService::Server::JSONRPC;
$server->dispatch(WS_DISPATCH)->handle();
......@@ -292,6 +292,13 @@
the job "[% job FILTER html %]". You need to add this job type
to the <code>JOB_MAP</code> constant in <code>Bugzilla::JobQueue</code>.
[% ELSIF error == "json_rpc_not_installed" %]
[% admindocslinks = { 'installation.html#install-perlmodules'
=> 'Installing Perl modules' } %]
The JSON-RPC interface will not work without the <code>JSON::RPC</code>
Perl module being installed. Run <code>checksetup.pl</code> for
installation instructions.
[% ELSIF error == "ldap_bind_failed" %]
Failed to bind to the LDAP server. The error message was:
<code>[% errstr FILTER html %]</code>
......
......@@ -949,6 +949,10 @@
[% title = "Invalid Username Or Password" %]
The username or password you entered is not valid.
[% ELSIF error == "json_rpc_post_only" %]
For security reasons, you may only use JSON-RPC with the POST
HTTP method.
[% ELSIF error == "keyword_already_exists" %]
[% title = "Keyword Already Exists" %]
A keyword with the name [% name FILTER html %] already exists.
......
......@@ -28,7 +28,7 @@ use Bugzilla::WebService::Constants;
eval { require Bugzilla::WebService::Server::XMLRPC; };
$@ && ThrowCodeError('soap_not_installed');
Bugzilla->usage_mode(USAGE_MODE_WEBSERVICE);
Bugzilla->usage_mode(USAGE_MODE_XMLRPC);
# Fix the error code that SOAP::Lite uses for Perl errors.
local $SOAP::Constants::FAULT_SERVER;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment