Fixed numerous bugs

git-svn-id: svn://10.0.0.236/trunk@227922 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
ghendricks%novell.com 2007-06-12 22:10:18 +00:00
parent 11d81feea3
commit 104c9a1930
15 changed files with 544 additions and 24 deletions

View File

@ -1292,8 +1292,7 @@ sub init {
push(@groupby, $field) if !grep($_ eq $field, @groupby);
}
}
unshift(@groupby, "test_${obj}s.${obj}_id");
$query .= " " . $dbh->sql_group_by(join(', ', @groupby)) if @groupby;
$query .= " " . $dbh->sql_group_by("test_${obj}s.${obj}_id", join(', ', @groupby));
if (@having) {

View File

@ -1014,7 +1014,7 @@ sub cases {
FROM test_case_runs
WHERE run_id = ?", undef, $self->id);
foreach my $cr (@$ref){
push @cases, Bugzilla::Testopia::TestCase->new($cr->case_id);
push @cases, Bugzilla::Testopia::TestCase->new($cr);
}
$self->{'cases'} = \@cases;
return $self->{'cases'};

View File

@ -13,6 +13,7 @@
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Marc Schumann <wurblzap@gmail.com>
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Dallas Harken <dharken@novell.com>
package Bugzilla::WebService;
@ -20,6 +21,7 @@ package Bugzilla::WebService;
use strict;
use Bugzilla::Config;
use Bugzilla::WebService::Constants;
use Date::Parse;
sub fail_unimplemented
{
@ -30,12 +32,31 @@ sub fail_unimplemented
->faultstring('Service Unimplemented');
}
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;
}
sub handle_login {
my ($self, $module, $method) = @_;
my $exempt = LOGIN_EXEMPT->{$module};
return if $exempt && grep { $_ eq $method } @$exempt;
Bugzilla->login;
}
sub login
{
my $self = shift;
# Check for use of iChain first
if (Param('user_verify_class') ne 'iChain')
if (Bugzilla->params->{'user_verify_class'} ne 'iChain')
{
#
# Check for use of Basic Authorization
@ -63,9 +84,10 @@ sub login
sub logout
{
my $self = shift;
Bugzilla->logout;
# Testopia's method does not persist anything so logout in unneccessary.
# my $self = shift;
#
# Bugzilla->logout;
}
package Bugzilla::WebService::XMLRPC::Transport::HTTP::CGI;
@ -95,4 +117,70 @@ sub make_response
}
}
1;
1;
__END__
=head1 NAME
Bugzilla::WebService - The Web Service interface to Bugzilla
=head1 DESCRIPTION
This is the standard API for external programs that want to interact
with Bugzilla. It provides various methods in various modules.
=head1 STABLE, EXPERIMENTAL, and UNSTABLE
Methods are marked B<STABLE> if you can expect their parameters and
return values not to change between versions of Bugzilla. You are
best off always using methods marked B<STABLE>. We may add parameters
and additional items to the return values, but your old code will
always continue to work with any new changes we make. If we ever break
a B<STABLE> interface, we'll post a big notice in the Release Notes,
and it will only happen during a major new release.
Methods (or parts of methods) are marked B<EXPERIMENTAL> if
we I<believe> they will be stable, but there's a slight chance that
small parts will change in the future.
Certain parts of a method's description may be marked as B<UNSTABLE>,
in which case those parts are not guaranteed to stay the same between
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.
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.
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.
=head2 Transient vs. Fatal Errors
If the error code is a number greater than 0, the error is considered
"transient," which means that it was an error made by the user, not
some problem with Bugzilla itself.
If the error code is a number less than 0, the error is "fatal," which
means that it's some error in Bugzilla itself that probably requires
administrative attention.
Negative numbers and positive numbers don't overlap. That is, if there's
an error 302, there won't be an error -302.
=head2 Unknown Errors
Sometimes a function will throw an error that doesn't have a specific
error code. In this case, the code will be C<-32000> if it's a "fatal"
error, and C<32000> if it's a "transient" error.

View File

@ -13,6 +13,7 @@
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Marc Schumann <wurblzap@gmail.com>
# Max Kanat-Alexander <mkanat@bugzilla.org>
package Bugzilla::WebService::Constants;
@ -24,8 +25,82 @@ use base qw(Exporter);
ERROR_UNIMPLEMENTED
ERROR_GENERAL
ERROR_FAULT_SERVER
WS_ERROR_CODE
ERROR_UNKNOWN_FATAL
ERROR_UNKNOWN_TRANSIENT
ERROR_AUTH_NODATA
ERROR_UNIMPLEMENTED
LOGIN_EXEMPT
);
# This maps the error names in global/*-error.html.tmpl to numbers.
# Generally, transient errors should have a number above 0, and
# fatal errors should have a number below 0.
#
# This hash should generally contain any error that could be thrown
# by the WebService interface. If it's extremely unlikely that the
# error could be thrown (like some CodeErrors), it doesn't have to
# be listed here.
#
# "Transient" means "If you resubmit that request with different data,
# it may work."
#
# "Fatal" means, "There's something wrong with Bugzilla, probably
# something an administrator would have to fix."
#
# NOTE: Numbers must never be recycled. If you remove a number, leave a
# comment that it was retired. Also, if an error changes its name, you'll
# have to fix it here.
use constant WS_ERROR_CODE => {
# Bug errors usually occupy the 100-200 range.
invalid_bug_id_or_alias => 100,
invalid_bug_id_non_existent => 101,
bug_access_denied => 102,
invalid_field_name => 108,
# 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_access_denied => 106,
product_disabled => 106,
# Invalid Summary
require_summary => 107,
# Authentication errors are usually 300-400.
invalid_username_or_password => 300,
account_disabled => 301,
auth_invalid_email => 302,
extern_id_conflict => -303,
# User errors are 500-600.
account_exists => 500,
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.
use constant ERROR_UNKNOWN_FATAL => -32000;
use constant ERROR_UNKNOWN_TRANSIENT => 32000;
use constant ERROR_AUTH_NODATA => 410;
use constant ERROR_UNIMPLEMENTED => 910;
use constant ERROR_GENERAL => 999;
@ -33,4 +108,13 @@ use constant ERROR_GENERAL => 999;
# RPC Fault Code must be an integer
use constant ERROR_FAULT_SERVER => 998;
1;
# For some methods, we shouldn't call Bugzilla->login before we call them.
# This is a hash--package names pointing to an arrayref of method names.
use constant LOGIN_EXEMPT => {
# Callers may have to know the Bugzilla version before logging in,
# even on a requirelogin installation.
Bugzilla => ['version'],
User => ['offer_account_by_email', 'login'],
};
1;

View File

@ -13,46 +13,320 @@
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Marc Schumann <wurblzap@gmail.com>
# Dallas Harken <dharken@novell.com>
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Mads Bondo Dydensborg <mbd@dbc.dk>
package Bugzilla::WebService::User;
use strict;
use Bugzilla;
use base qw(Bugzilla::WebService);
sub lookup_login_by_id
{
import SOAP::Data qw(type);
use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::User;
use Bugzilla::Util qw(trim);
use Bugzilla::Token;
##############
# User Login #
##############
sub login {
my ($self, $params) = @_;
my $remember = $params->{remember};
# Convert $remember from a boolean 0/1 value to a CGI-compatible one.
if (defined($remember)) {
$remember = $remember? 'on': '';
}
else {
# Use Bugzilla's default if $remember is not supplied.
$remember =
Bugzilla->params->{'rememberlogin'} eq 'defaulton'? 'on': '';
}
# Make sure the CGI user info class works if necessary.
my $cgi = Bugzilla->cgi;
$cgi->param('Bugzilla_login', $params->{login});
$cgi->param('Bugzilla_password', $params->{password});
$cgi->param('Bugzilla_remember', $remember);
Bugzilla->login;
return { id => type('int')->value(Bugzilla->user->id) };
}
sub logout {
my $self = shift;
Bugzilla->logout;
return undef;
}
#################
# User Creation #
#################
sub offer_account_by_email {
my $self = shift;
my ($params) = @_;
my $email = trim($params->{email})
|| ThrowCodeError('param_required', { param => 'email' });
$email = Bugzilla::User->check_login_name_for_creation($email);
# Create and send a token for this new account.
Bugzilla::Token::issue_new_user_account_token($email);
return undef;
}
sub create {
my $self = shift;
my ($params) = @_;
Bugzilla->user->in_group('editusers')
|| ThrowUserError("auth_failure", { group => "editusers",
action => "add",
object => "users"});
my $email = trim($params->{email})
|| ThrowCodeError('param_required', { param => 'email' });
my $realname = trim($params->{full_name});
my $password = trim($params->{password}) || '*';
my $user = Bugzilla::User->create({
login_name => $email,
realname => $realname,
cryptpassword => $password
});
return { id => type('int')->value($user->id) };
}
#################
# User Lookup #
#################
sub lookup_login_by_id {
my $self = shift;
my ($author_id) = @_;
$self->login;
$self->SUPER::login;
my $user = new Bugzilla::User($author_id);
my $result = defined $user ? $user->login : '';
$self->logout;
$self->SUPER::logout;
# Result is user login string or empty string if failed
return $result;
}
sub lookup_id_by_login
{
sub lookup_id_by_login {
my $self = shift;
my ($author) = @_;
$self->login;
$self->SUPER::login;
my $result = Bugzilla::User::login_to_id($author);
$self->logout;
$self->SUPER::logout;
# Result is user id or 0 if failed
return $result;
}
1;
1;
__END__
=head1 NAME
Bugzilla::Webservice::User - The User Account and Login API
=head1 DESCRIPTION
This part of the Bugzilla API allows you to create User Accounts and
log in/out using an existing account.
=head1 METHODS
See L<Bugzilla::WebService> for a description of what B<STABLE>, B<UNSTABLE>,
and B<EXPERIMENTAL> mean, and for more information about error codes.
=head2 Logging In and Out
=over
=item C<login> B<EXPERIMENTAL>
=over
=item B<Description>
Logging in, with a username and password, is required for many
Bugzilla installations, in order to search for bugs, post new bugs,
etc. This method logs in an user.
=item B<Params>
=over
=item C<login> (string) - The user's login name.
=item C<password> (string) - The user's password.
=item C<remember> (bool) B<Optional> - if the cookies returned by the
call to login should expire with the session or not. In order for
this option to have effect the Bugzilla server must be configured to
allow the user to set this option - the Bugzilla parameter
I<rememberlogin> must be set to "defaulton" or
"defaultoff". Addionally, the client application must implement
management of cookies across sessions.
=back
=item B<Returns>
On success, a hash containing one item, C<id>, the numeric id of the
user that was logged in. A set of http cookies is also sent with the
response. These cookies must be sent along with any future requests
to the webservice, for the duration of the session.
=item B<Errors>
=over
=item 300 (Invalid Username or Password)
The username does not exist, or the password is wrong.
=item 301 (Account Disabled)
The account has been disabled. A reason may be specified with the
error.
=back
=back
=item C<logout> B<EXPERIMENTAL>
=over
=item B<Description>
Log out the user. Does nothing if there is no user logged in.
=item B<Params> (none)
=item B<Returns> (nothing)
=item B<Errors> (none)
=back
=back
=head2 Account Creation
=over
=item C<offer_account_by_email> B<EXPERIMENTAL>
=over
=item B<Description>
Sends an email to the user, offering to create an account. The user
will have to click on a URL in the email, and choose their password
and real name.
This is the recommended way to create a Bugzilla account.
=item B<Param>
=over
=item C<email> (string) - the email to send the offer to.
=back
=item B<Returns> (nothing)
=item B<Errors>
=over
=item 500 (Illegal Email Address)
This Bugzilla does not allow you to create accounts with the format of
email address you specified. Account creation may be entirely disabled.
=item 501 (Account Already Exists)
An account with that email address already exists in Bugzilla.
=back
=back
=item C<create> B<EXPERIMENTAL>
=over
=item B<Description>
Creates a user account directly in Bugzilla, password and all.
Instead of this, you should use L</offer_account_by_email> when
possible, because that makes sure that the email address specified can
actually receive an email. This function does not check that.
=item B<Params>
=over
=item C<email> (string) - The email address for the new user.
=item C<full_name> (string) B<Optional> - The user's full name. Will
be set to empty if not specified.
=item C<password> (string) B<Optional> - The password for the new user
account, in plain text. It will be stripped of leading and trailing
whitespace. If blank or not specified, the newly created account will
exist in Bugzilla, but will not be allowed to log in using DB
authentication until a password is set either by the user (through
resetting their password) or by the administrator.
=back
=item B<Returns>
A hash containing one item, C<id>, the numeric id of the user that was
created.
=item B<Errors>
The same as L</offer_account_by_email>. If a password is specified,
the function may also throw:
=over
=item 502 (Password Too Short)
The password specified is too short. (Usually, this means the
password is under three characters.)
=item 503 (Password Too Long)
The password specified is too long. (Usually, this means the
password is over ten characters.)
=back
=back
=back

View File

@ -61,14 +61,14 @@
}
catch(err){}
}
dojo.byId('search_submit').disabled = false;
}
function onProductSelection(){
var prod = document.getElementById("product_id");
var ids = new Array;
dojo.byId( "search_submit").disabled = true;
for (var i=0; i<prod.options.length; i++){
if (prod.options[i].selected == true)
ids.push(prod.options[i].value);

View File

@ -226,3 +226,6 @@
</fieldset>
<input type="submit" value="Submit" id="search_submit">
</form>
<script type="text/javascript">
dojo.addOnLoad(onProductSelection);
</script>

View File

@ -236,3 +236,6 @@
<input name="isactive" type="hidden" value="1">
<input type="submit" value="Submit" id="search_submit">
</form>
<script type="text/javascript">
dojo.addOnLoad(onProductSelection);
</script>

View File

@ -137,3 +137,7 @@
<input type="submit" value="Submit" id="search_submit">
</form>
<script type="text/javascript">
dojo.addOnLoad(onProductSelection);
</script>

View File

@ -180,3 +180,6 @@
<input type="submit" value="Submit" id="search_submit">
</form>
<script type="text/javascript">
dojo.addOnLoad(onProductSelection);
</script>

View File

@ -842,3 +842,22 @@ diff -u -r1.45 Schema.pm
+ },
};
#--------------------------------------------------------------------------
Index: createaccount.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/createaccount.cgi,v
retrieving revision 1.46
diff -u -r1.46 createaccount.cgi
--- createaccount.cgi 20 Dec 2005 22:16:07 -0000 1.46
+++ createaccount.cgi 12 Jun 2007 16:31:57 -0000
@@ -69,8 +69,8 @@
$vars->{'login'} = $login;
- $dbh->bz_lock_tables('profiles WRITE', 'groups READ',
- 'user_group_map WRITE', 'email_setting WRITE',
+ $dbh->bz_lock_tables('profiles WRITE', 'groups READ', 'test_plan_permissions_regexp READ',
+ 'user_group_map WRITE', 'email_setting WRITE', 'test_plan_permissions READ',
'tokens READ');
if (!is_available_username($login)) {

View File

@ -852,3 +852,22 @@ diff -u -r1.9 Pg.pm
SMALLSERIAL => 'serial unique',
MEDIUMSERIAL => 'serial unique',
INTSERIAL => 'serial unique',
Index: createaccount.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/createaccount.cgi,v
retrieving revision 1.46
diff -u -r1.46 createaccount.cgi
--- createaccount.cgi 20 Dec 2005 22:16:07 -0000 1.46
+++ createaccount.cgi 12 Jun 2007 16:31:57 -0000
@@ -69,8 +69,8 @@
$vars->{'login'} = $login;
- $dbh->bz_lock_tables('profiles WRITE', 'groups READ',
- 'user_group_map WRITE', 'email_setting WRITE',
+ $dbh->bz_lock_tables('profiles WRITE', 'groups READ', 'test_plan_permissions_regexp READ',
+ 'user_group_map WRITE', 'email_setting WRITE', 'test_plan_permissions READ',
'tokens READ');
if (!is_available_username($login)) {

View File

@ -852,3 +852,22 @@ diff -u -r1.12.2.1 Mysql.pm
# fields, which have their own special auto-defaults.)
#
# Here's how we handle this: If it exists in the schema
Index: createaccount.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/createaccount.cgi,v
retrieving revision 1.46
diff -u -r1.46 createaccount.cgi
--- createaccount.cgi 20 Dec 2005 22:16:07 -0000 1.46
+++ createaccount.cgi 12 Jun 2007 16:31:57 -0000
@@ -69,8 +69,8 @@
$vars->{'login'} = $login;
- $dbh->bz_lock_tables('profiles WRITE', 'groups READ',
- 'user_group_map WRITE', 'email_setting WRITE',
+ $dbh->bz_lock_tables('profiles WRITE', 'groups READ', 'test_plan_permissions_regexp READ',
+ 'user_group_map WRITE', 'email_setting WRITE', 'test_plan_permissions READ',
'tokens READ');
if (!is_available_username($login)) {

View File

@ -185,6 +185,7 @@ else{
my $search = $cgi->param('search');
my $prod_id = $cgi->param('prod_id');
trick_taint($search);
detaint_natural($prod_id);
$search = "%$search%";
my $dbh = Bugzilla->dbh;
@ -213,6 +214,7 @@ else{
}
print objToJson($ref);
}
# user lookup
elsif ($action eq 'getuser'){
my $search = $cgi->param('search');
$search = "%$search%";

View File

@ -107,6 +107,9 @@ elsif ($action =~ /New Case/){
$caserun->store;
}
}
$cgi->delete_all;
$cgi->param('run_id', $run->id);
display($run);
}
elsif ($action eq 'History'){