diff options
author | Robin H. Johnson <robbat2@orbis-terrarum.net> | 2014-10-06 09:22:17 -0700 |
---|---|---|
committer | Robin H. Johnson <robbat2@orbis-terrarum.net> | 2014-10-06 09:22:17 -0700 |
commit | e4c4605623455bc991e2e5919afece57b02d6c79 (patch) | |
tree | 81a4f02b78fb5df6f5fc3a792e414e14350ad7a5 | |
parent | Merge tag 'bugzilla-4.4.4' into upstream (diff) | |
parent | Bump version to 4.4.5 (corrected) (diff) | |
download | bugzilla-e4c4605623455bc991e2e5919afece57b02d6c79.tar.gz bugzilla-e4c4605623455bc991e2e5919afece57b02d6c79.tar.bz2 bugzilla-e4c4605623455bc991e2e5919afece57b02d6c79.zip |
Merge tag 'bugzilla-4.4.5' into upstream
-rw-r--r-- | .travis.yml | 48 | ||||
-rw-r--r-- | Bugzilla.pm | 2 | ||||
-rw-r--r-- | Bugzilla/Attachment.pm | 10 | ||||
-rw-r--r-- | Bugzilla/Auth/Login/CGI.pm | 2 | ||||
-rw-r--r-- | Bugzilla/Auth/Verify/DB.pm | 4 | ||||
-rw-r--r-- | Bugzilla/Bug.pm | 15 | ||||
-rw-r--r-- | Bugzilla/Constants.pm | 3 | ||||
-rw-r--r-- | Bugzilla/Field.pm | 6 | ||||
-rw-r--r-- | Bugzilla/Install/Localconfig.pm | 10 | ||||
-rw-r--r-- | Bugzilla/Install/Requirements.pm | 6 | ||||
-rw-r--r-- | Bugzilla/Search.pm | 39 | ||||
-rw-r--r-- | Bugzilla/Util.pm | 10 | ||||
-rw-r--r-- | Bugzilla/WebService/Server/JSONRPC.pm | 5 | ||||
-rw-r--r-- | Build.PL | 61 | ||||
-rw-r--r-- | MANIFEST.SKIP | 53 | ||||
-rwxr-xr-x | contrib/bz_webservice_demo.pl | 95 | ||||
-rw-r--r-- | docs/bugzilla.ent.tmpl | 5 | ||||
-rwxr-xr-x | editusers.cgi | 11 | ||||
-rw-r--r-- | template/en/default/pages/release-notes.html.tmpl | 6 |
19 files changed, 296 insertions, 95 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..94c9ce1d2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,48 @@ +language: perl +perl: + - 5.10 + - 5.12 + +env: + - TEST_SUITE=sanity + - TEST_SUITE=docs + - TEST_SUITE=webservices DB=mysql + - TEST_SUITE=selenium DB=mysql + - TEST_SUITE=webservices DB=pg + - TEST_SUITE=selenium DB=pg + +matrix: + exclude: + - perl: 5.12 + env: TEST_SUITE=docs + - perl: 5.10 + env: TEST_SUITE=webservices DB=mysql + - perl: 5.12 + env: TEST_SUITE=selenium DB=mysql + - perl: 5.10 + env: TEST_SUITE=webservices DB=pg + - perl: 5.12 + env: TEST_SUITE=selenium DB=pg + +before_install: + - git clone https://github.com/bugzilla/qa.git -b 4.4 qa + +install: true + +script: ./qa/travis.sh + +after_failure: + - sudo cat /var/log/apache2/error.log + +notifications: + irc: + channels: + - "irc.mozilla.org#qa-bugzilla" + - "irc.mozilla.org#bugzilla" + template: + - "Bugzilla %{branch} : %{author} : %{message}" + - "Commit Message : %{commit_message}" + - "Commit Link : %{compare_url}" + - "Build Link : %{build_url}" + on_success: change + on_failure: always diff --git a/Bugzilla.pm b/Bugzilla.pm index bb99764f2..6e31ba71a 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -67,7 +67,7 @@ use constant SHUTDOWNHTML_RETRY_AFTER => 3600; # Global Code ##################################################################### -# $::SIG{__DIE__} = i_am_cgi() ? \&CGI::Carp::confess : \&Carp::confess; +#$::SIG{__DIE__} = i_am_cgi() ? \&CGI::Carp::confess : \&Carp::confess; # Note that this is a raw subroutine, not a method, so $class isn't available. sub init_page { diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index 380ef3d4c..97cd85008 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -895,16 +895,12 @@ sub update { } # Record changes in the activity table. - my $sth = $dbh->prepare('INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, - fieldid, removed, added) - VALUES (?, ?, ?, ?, ?, ?, ?)'); - + require Bugzilla::Bug; foreach my $field (keys %$changes) { my $change = $changes->{$field}; $field = "attachments.$field" unless $field eq "flagtypes.name"; - my $fieldid = get_field_id($field); - $sth->execute($self->bug_id, $self->id, $user->id, $timestamp, - $fieldid, $change->[0], $change->[1]); + Bugzilla::Bug::LogActivityEntry($self->bug_id, $field, $change->[0], + $change->[1], $user->id, $timestamp, undef, $self->id); } if (scalar(keys %$changes)) { diff --git a/Bugzilla/Auth/Login/CGI.pm b/Bugzilla/Auth/Login/CGI.pm index 090680ebf..f29e8c9c1 100644 --- a/Bugzilla/Auth/Login/CGI.pm +++ b/Bugzilla/Auth/Login/CGI.pm @@ -55,7 +55,7 @@ sub get_login_info { ThrowUserError('auth_untrusted_request', { login => $login }); } - if (!$login || !$password || !$valid) { + if (!defined($login) || !defined($password) || !$valid) { return { failure => AUTH_NODATA }; } diff --git a/Bugzilla/Auth/Verify/DB.pm b/Bugzilla/Auth/Verify/DB.pm index 6ca04f259..99dc48ddc 100644 --- a/Bugzilla/Auth/Verify/DB.pm +++ b/Bugzilla/Auth/Verify/DB.pm @@ -68,7 +68,9 @@ sub check_credentials { # whatever hashing system we're using now. my $current_algorithm = PASSWORD_DIGEST_ALGORITHM; if ($real_password_crypted !~ /{\Q$current_algorithm\E}$/) { - $user->set_password($password); + # We can't call $user->set_password because we don't want the password + # complexity rules to apply here. + $user->{cryptpassword} = bz_crypt($password); $user->update(); } diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 97e81dfdd..d4d94b23f 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -246,7 +246,6 @@ use constant MAX_LINE_LENGTH => 254; # use.) use constant FIELD_MAP => { blocks => 'blocked', - cc_accessible => 'cclist_accessible', commentprivacy => 'comment_is_private', creation_time => 'creation_ts', creator => 'reporter', @@ -3939,7 +3938,8 @@ sub get_activity { # Update the bugs_activity table to reflect changes made in bugs. sub LogActivityEntry { - my ($i, $col, $removed, $added, $whoid, $timestamp, $comment_id) = @_; + my ($i, $col, $removed, $added, $whoid, $timestamp, $comment_id, + $attach_id) = @_; my $dbh = Bugzilla->dbh; # in the case of CCs, deps, and keywords, there's a possibility that someone # might try to add or remove a lot of them at once, which might take more @@ -3964,10 +3964,13 @@ sub LogActivityEntry { trick_taint($addstr); trick_taint($removestr); my $fieldid = get_field_id($col); - $dbh->do("INSERT INTO bugs_activity - (bug_id, who, bug_when, fieldid, removed, added, comment_id) - VALUES (?, ?, ?, ?, ?, ?, ?)", - undef, ($i, $whoid, $timestamp, $fieldid, $removestr, $addstr, $comment_id)); + $dbh->do( + "INSERT INTO bugs_activity + (bug_id, who, bug_when, fieldid, removed, added, comment_id, attach_id) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + undef, + ($i, $whoid, $timestamp, $fieldid, $removestr, $addstr, $comment_id, + $attach_id)); } } diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 33d4a56e2..37931aa16 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -182,7 +182,8 @@ use Memoize; # CONSTANTS # # Bugzilla version -use constant BUGZILLA_VERSION => "4.4.4"; +use constant BUGZILLA_VERSION => "4.4.5"; + # Location of the remote and local XML files to track new releases. use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml'; diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index c4d687afb..0c9da9b56 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -196,6 +196,12 @@ use constant DEFAULT_FIELDS => ( buglist => 1}, {name => 'qa_contact', desc => 'QAContact', in_new_bugmail => 1, buglist => 1}, + {name => 'assigned_to_realname', desc => 'AssignedToName', + in_new_bugmail => 0, buglist => 1}, + {name => 'reporter_realname', desc => 'ReportedByName', + in_new_bugmail => 0, buglist => 1}, + {name => 'qa_contact_realname', desc => 'QAContactName', + in_new_bugmail => 0, buglist => 1}, {name => 'cc', desc => 'CC', in_new_bugmail => 1}, {name => 'dependson', desc => 'Depends on', in_new_bugmail => 1, is_numeric => 1}, diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm index 4f1579c86..881f6c956 100644 --- a/Bugzilla/Install/Localconfig.pm +++ b/Bugzilla/Install/Localconfig.pm @@ -205,14 +205,20 @@ sub update_localconfig { # a 256-character string for site_wide_secret. $value = undef if ($name eq 'site_wide_secret' and defined $value and length($value) == 256); - + if (!defined $value) { - push(@new_vars, $name); $var->{default} = &{$var->{default}} if ref($var->{default}) eq 'CODE'; if (exists $answer->{$name}) { $localconfig->{$name} = $answer->{$name}; } else { + # If the user did not supply an answers file, then they get + # notified about every variable that gets added. If there was + # an answer file, then we don't notify about site_wide_secret + # because we assume the intent was to auto-generate it anyway. + if (!scalar(keys %$answer) || $name ne 'site_wide_secret') { + push(@new_vars, $name); + } $localconfig->{$name} = $var->{default}; } } diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm index e2dc50a8f..fbd7d7882 100644 --- a/Bugzilla/Install/Requirements.pm +++ b/Bugzilla/Install/Requirements.pm @@ -368,6 +368,12 @@ sub OPTIONAL_MODULES { version => 0, feature => ['jobqueue'], }, + { + package => 'File-Slurp', + module => 'File::Slurp', + version => '9999.13', + feature => ['jobqueue'], + }, # mod_perl { diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index f900b3474..b395b3fbf 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -222,6 +222,9 @@ use constant OPERATOR_FIELD_OVERRIDE => { assigned_to => { _non_changed => \&_user_nonchanged, }, + assigned_to_realname => { + _non_changed => \&_user_nonchanged, + }, cc => { _non_changed => \&_user_nonchanged, }, @@ -231,6 +234,9 @@ use constant OPERATOR_FIELD_OVERRIDE => { reporter => { _non_changed => \&_user_nonchanged, }, + reporter_realname => { + _non_changed => \&_user_nonchanged, + }, 'requestees.login_name' => { _non_changed => \&_user_nonchanged, }, @@ -240,7 +246,10 @@ use constant OPERATOR_FIELD_OVERRIDE => { qa_contact => { _non_changed => \&_user_nonchanged, }, - + qa_contact_realname => { + _non_changed => \&_user_nonchanged, + }, + # General Bug Fields alias => { _non_changed => \&_nullable }, 'attach_data.thedata' => MULTI_SELECT_OVERRIDE, @@ -520,9 +529,6 @@ sub COLUMNS { # of short_short_desc.) my %columns = ( relevance => { title => 'Relevance' }, - assigned_to_realname => { title => 'Assignee' }, - reporter_realname => { title => 'Reporter' }, - qa_contact_realname => { title => 'QA Contact' }, ); # Next we define columns that have special SQL instead of just something @@ -575,7 +581,7 @@ sub COLUMNS { $sql = $dbh->sql_string_until($sql, $dbh->quote('@')); } $special_sql{$col} = $sql; - $columns{"${col}_realname"}->{name} = "map_${col}.realname"; + $special_sql{"${col}_realname"} = "map_${col}.realname"; } foreach my $col (@id_fields) { @@ -1968,6 +1974,13 @@ sub _quote_unless_numeric { sub build_subselect { my ($outer, $inner, $table, $cond, $negate) = @_; + if ($table =~ /\battach_data\b/) { + # It takes a long time to scan the whole attach_data table + # unconditionally, so we return the subselect and let the DB optimizer + # restrict the search based on other search criteria. + my $not = $negate ? "NOT" : ""; + return "$outer $not IN (SELECT DISTINCT $inner FROM $table WHERE $cond)"; + } # Execute subselects immediately to avoid dependent subqueries, which are # large performance hits on MySql my $q = "SELECT DISTINCT $inner FROM $table WHERE $cond"; @@ -2283,6 +2296,20 @@ sub _user_nonchanged { if ($args->{value_is_id}) { $null_alternate = 0; } + elsif (substr($field, -9) eq '_realname') { + my $as = "name_${field}_$chart_id"; + # For fields with periods in their name. + $as =~ s/\./_/; + my $join = { + table => 'profiles', + as => $as, + from => substr($args->{full_field}, 0, -9), + to => 'userid', + join => (!$is_in_other_table and !$is_nullable) ? 'INNER' : undef, + }; + push(@$joins, $join); + $args->{full_field} = "$as.realname"; + } else { my $as = "name_${field}_$chart_id"; # For fields with periods in their name. @@ -2297,7 +2324,7 @@ sub _user_nonchanged { push(@$joins, $join); $args->{full_field} = "$as.login_name"; } - + # We COALESCE fields that can be NULL, to make "not"-style operators # continue to work properly. For example, "qa_contact is not equal to bob" # should also show bugs where the qa_contact is NULL. With COALESCE, diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm index 625fee963..164ff40bf 100644 --- a/Bugzilla/Util.pm +++ b/Bugzilla/Util.pm @@ -628,13 +628,13 @@ sub bz_crypt { $algorithm = $1; } + # Wide characters cause crypt and Digest to die. + if (Bugzilla->params->{'utf8'}) { + utf8::encode($password) if utf8::is_utf8($password); + } + my $crypted_password; if (!$algorithm) { - # Wide characters cause crypt to die - if (Bugzilla->params->{'utf8'}) { - utf8::encode($password) if utf8::is_utf8($password); - } - # Crypt the password. $crypted_password = crypt($password, $salt); diff --git a/Bugzilla/WebService/Server/JSONRPC.pm b/Bugzilla/WebService/Server/JSONRPC.pm index 9f5710439..c2d1e8c74 100644 --- a/Bugzilla/WebService/Server/JSONRPC.pm +++ b/Bugzilla/WebService/Server/JSONRPC.pm @@ -77,8 +77,9 @@ sub response { # Implement JSONP. if (my $callback = $self->_bz_callback) { my $content = $response->content; - $response->content("$callback($content)"); - + # Prepend the JSONP response with /**/ in order to protect + # against possible encoding attacks (e.g., affecting Flash). + $response->content("/**/$callback($content)"); } # Use $cgi->header properly instead of just printing text directly. diff --git a/Build.PL b/Build.PL new file mode 100644 index 000000000..024a56024 --- /dev/null +++ b/Build.PL @@ -0,0 +1,61 @@ +#!/usr/bin/perl +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib ($RealBin, "$RealBin/lib"); + +use Module::Build 0.36_14; + +use Bugzilla::Install::Requirements qw(REQUIRED_MODULES OPTIONAL_MODULES); +use Bugzilla::Constants qw(BUGZILLA_VERSION); + +sub requires { + my $requirements = REQUIRED_MODULES(); + my $hrequires = {}; + foreach my $module (@$requirements) { + $hrequires->{$module->{module}} = $module->{version}; + } + return $hrequires; +}; + +sub build_requires { + return requires(); +} + +sub recommends { + my $recommends = OPTIONAL_MODULES(); + my @blacklist = ('Apache-SizeLimit', 'mod_perl'); # Does not compile properly on Travis + my $hrecommends = {}; + foreach my $module (@$recommends) { + next if grep($_ eq $module->{package}, @blacklist); + $hrecommends->{$module->{module}} = $module->{version}; + } + return $hrecommends; +} + +my $build = Module::Build->new( + module_name => 'Bugzilla', + dist_abstract => <<END, +Bugzilla is a free bug-tracking system that is developed by an active +community of volunteers. You can install and use it without having to +pay any license fee. +END + dist_version_from => 'Bugzilla/Constants.pm', + dist_version => BUGZILLA_VERSION, + requires => requires(), + recommends => recommends(), + license => 'Mozilla_2_0', + create_readme => 0, + create_makefile_pl => 0 +); + +$build->create_build_script; diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP new file mode 100644 index 000000000..69204e63f --- /dev/null +++ b/MANIFEST.SKIP @@ -0,0 +1,53 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +#!start included /usr/share/perl5/ExtUtils/MANIFEST.SKIP +# Avoid version control files. +\B\.git\b +\B\.bzr\b +\B\.bzrignore\b +\B\.gitignore\b +\B\.gitrev\b +\B\.patch\b + +# Avoid Makemaker generated and utility files. +\bMANIFEST\.bak +\bMakefile$ +\bblib/ +\bMakeMaker-\d +\bpm_to_blib\.ts$ +\bpm_to_blib$ +\bblibdirs\.ts$ # 6.18 through 6.25 generated this + +# Avoid Module::Build generated and utility files. +\bBuild$ +\b_build/ + +# Avoid temp and backup files. +~$ +\.old$ +\#$ +\b\.# +\.bak$ +\.swp$ + +#!end included /usr/share/perl5/ExtUtils/MANIFEST.SKIP + +# Avoid Module::Build generated and utility files. +\bBuild$ +\bBuild.bat$ +\b_build +\bBuild.COM$ +\bBUILD.COM$ +\bbuild.com$ + +# Avoid archives of this distribution +\bBugzilla-[\d\.\_]+ + +# Bugzilla specific avoids +\bdata\/\b +\blocalconfig$ diff --git a/contrib/bz_webservice_demo.pl b/contrib/bz_webservice_demo.pl index 3b87cf5b5..8850d642a 100755 --- a/contrib/bz_webservice_demo.pl +++ b/contrib/bz_webservice_demo.pl @@ -24,7 +24,6 @@ use Getopt::Long; use Pod::Usage; use File::Basename qw(dirname); use File::Spec; -use HTTP::Cookies; use XMLRPC::Lite; # If you want, say “use Bugzilla::WebService::Constants” here to get access @@ -36,7 +35,8 @@ my $help; my $Bugzilla_uri; my $Bugzilla_login; my $Bugzilla_password; -my $Bugzilla_remember; +my $Bugzilla_restrict; +my $Bugzilla_token; my $bug_id; my $product_name; my $create_file_name; @@ -51,7 +51,7 @@ GetOptions('help|h|?' => \$help, 'uri=s' => \$Bugzilla_uri, 'login:s' => \$Bugzilla_login, 'password=s' => \$Bugzilla_password, - 'rememberlogin!' => \$Bugzilla_remember, + 'restrictlogin!' => \$Bugzilla_restrict, 'bug_id:s' => \$bug_id, 'product_name:s' => \$product_name, 'create:s' => \$create_file_name, @@ -86,14 +86,14 @@ Specify this without a value in order to log out. Bugzilla password. Specify this together with B<--login> in order to log in. -=item --rememberlogin +=item --restrictlogin -Gives access to Bugzilla's "Bugzilla_remember" option. -Specify this option while logging in to do the same thing as ticking the -C<Bugzilla_remember> box on Bugilla's log in form. +Gives access to Bugzilla's "Bugzilla_restrictlogin" option. +Specify this option while logging in to restrict the login token to be +only valid from the IP address which called Don't specify this option to do the same thing as unchecking the box. -See Bugzilla's rememberlogin parameter for details. +See Bugzilla's restrictlogin parameter for details. =item --bug_id @@ -151,17 +151,6 @@ my $soapresult; # We will use this variable for function call results. my $result; -# Open our cookie jar. We save it into a file so that we may re-use cookies -# to avoid the need of logging in every time. You're encouraged, but not -# required, to do this in your applications, too. -# Cookies are only saved if Bugzilla's rememberlogin parameter is set to one of -# - on -# - defaulton (and you didn't pass 0 as third parameter to User.login) -# - defaultoff (and you passed 1 as third parameter to User.login) -my $cookie_jar = - new HTTP::Cookies('file' => File::Spec->catdir(dirname($0), 'cookies.txt'), - 'autosave' => 1); - =head2 Initialization Using the XMLRPC::Lite class, you set up a proxy, as shown in this script. @@ -170,8 +159,7 @@ of C<http://your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi>. =cut -my $proxy = XMLRPC::Lite->proxy($Bugzilla_uri, - 'cookie_jar' => $cookie_jar); +my $proxy = XMLRPC::Lite->proxy($Bugzilla_uri); =head2 Debugging @@ -205,25 +193,6 @@ $soapresult = $proxy->call('Bugzilla.timezone'); _die_on_fault($soapresult); print 'Bugzilla\'s timezone is ' . $soapresult->result()->{timezone} . ".\n"; -=head2 Getting Extension Information - -Returns all the information any extensions have decided to provide to the webservice. - -=cut - -if ($fetch_extension_info) { - $soapresult = $proxy->call('Bugzilla.extensions'); - _die_on_fault($soapresult); - my $extensions = $soapresult->result()->{extensions}; - foreach my $extensionname (keys(%$extensions)) { - print "Extension '$extensionname' information\n"; - my $extension = $extensions->{$extensionname}; - foreach my $data (keys(%$extension)) { - print ' ' . $data . ' => ' . $extension->{$data} . "\n"; - } - } -} - =head2 Logging In and Out =head3 Using Bugzilla's Environment Authentication @@ -238,21 +207,20 @@ You don't log out if you're using this kind of authentication. Use the C<User.login> and C<User.logout> calls to log in and out, as shown in this script. -The C<Bugzilla_remember> parameter is optional. -If omitted, Bugzilla's defaults apply (as specified by its C<rememberlogin> +The C<Bugzilla_restrictlogin> parameter is optional. +If omitted, Bugzilla's defaults apply (as specified by its C<restrictlogin> parameter). -Bugzilla hands back cookies you'll need to pass along during your work calls. - =cut if (defined($Bugzilla_login)) { if ($Bugzilla_login ne '') { # Log in. $soapresult = $proxy->call('User.login', - { login => $Bugzilla_login, + { login => $Bugzilla_login, password => $Bugzilla_password, - remember => $Bugzilla_remember } ); + restrict_login => $Bugzilla_restrict } ); + $Bugzilla_token = $soapresult->result->{token}; _die_on_fault($soapresult); print "Login successful.\n"; } @@ -264,17 +232,36 @@ if (defined($Bugzilla_login)) { } } +=head2 Getting Extension Information + +Returns all the information any extensions have decided to provide to the webservice. + +=cut + +if ($fetch_extension_info) { + $soapresult = $proxy->call('Bugzilla.extensions', {token => $Bugzilla_token}); + _die_on_fault($soapresult); + my $extensions = $soapresult->result()->{extensions}; + foreach my $extensionname (keys(%$extensions)) { + print "Extension '$extensionname' information\n"; + my $extension = $extensions->{$extensionname}; + foreach my $data (keys(%$extension)) { + print ' ' . $data . ' => ' . $extension->{$data} . "\n"; + } + } +} + =head2 Retrieving Bug Information Call C<Bug.get> with the ID of the bug you want to know more of. -The call will return a C<Bugzilla::Bug> object. +The call will return a C<Bugzilla::Bug> object. Note: You can also use "Bug.get_bugs" for compatibility with Bugzilla 3.0 API. =cut if ($bug_id) { - $soapresult = $proxy->call('Bug.get', { ids => [$bug_id] }); + $soapresult = $proxy->call('Bug.get', { ids => [$bug_id], token => $Bugzilla_token}); _die_on_fault($soapresult); $result = $soapresult->result; my $bug = $result->{bugs}->[0]; @@ -299,7 +286,7 @@ The call will return a C<Bugzilla::Product> object. =cut if ($product_name) { - $soapresult = $proxy->call('Product.get', {'names' => [$product_name]}); + $soapresult = $proxy->call('Product.get', {'names' => [$product_name], token => $Bugzilla_token}); _die_on_fault($soapresult); $result = $soapresult->result()->{'products'}->[0]; @@ -325,14 +312,16 @@ if ($product_name) { =head2 Creating A Bug Call C<Bug.create> with the settings read from the file indicated on -the command line. The file must contain a valid anonymous hash to use +the command line. The file must contain a valid anonymous hash to use as argument for the call to C<Bug.create>. The call will return a hash with a bug id for the newly created bug. =cut if ($create_file_name) { - $soapresult = $proxy->call('Bug.create', do "$create_file_name" ); + my $bug_fields = do "$create_file_name"; + $bug_fields->{Bugzilla_token} = $Bugzilla_token; + $soapresult = $proxy->call('Bug.create', \%$bug_fields); _die_on_fault($soapresult); $result = $soapresult->result; @@ -356,7 +345,7 @@ list of legal values for this field. =cut if ($legal_field_values) { - $soapresult = $proxy->call('Bug.legal_values', {field => $legal_field_values} ); + $soapresult = $proxy->call('Bug.legal_values', {field => $legal_field_values, token => $Bugzilla_token} ); _die_on_fault($soapresult); $result = $soapresult->result; @@ -374,7 +363,7 @@ or not. if ($add_comment) { if ($bug_id) { $soapresult = $proxy->call('Bug.add_comment', {id => $bug_id, - comment => $add_comment, private => $private, work_time => $work_time}); + comment => $add_comment, private => $private, work_time => $work_time, token => $Bugzilla_token}); _die_on_fault($soapresult); print "Comment added.\n"; } diff --git a/docs/bugzilla.ent.tmpl b/docs/bugzilla.ent.tmpl index 15cd47500..98ec0a7ce 100644 --- a/docs/bugzilla.ent.tmpl +++ b/docs/bugzilla.ent.tmpl @@ -1,7 +1,8 @@ -<!ENTITY bz-ver "4.4.4"> -<!ENTITY bz-date "2014-04-18"> +<!ENTITY bz-ver "4.4.5"> +<!ENTITY bz-date "2014-07-24"> <!ENTITY current-year "2014"> + <!ENTITY min-perl-ver "5.8.1"> <!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-4.4-branch/"> <!ENTITY bzg-bugs "http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla;component=Documentation"> diff --git a/editusers.cgi b/editusers.cgi index d022321f0..a5ba6d1e3 100755 --- a/editusers.cgi +++ b/editusers.cgi @@ -483,10 +483,6 @@ if ($action eq 'search') { my $sth_set_bug_timestamp = $dbh->prepare('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?'); - my $sth_updateFlag = $dbh->prepare('INSERT INTO bugs_activity - (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES (?, ?, ?, ?, ?, ?, ?)'); - # Flags my $flag_ids = $dbh->selectcol_arrayref('SELECT id FROM flags WHERE requestee_id = ?', @@ -501,16 +497,15 @@ if ($action eq 'search') { # so we have to log these changes manually. my %bugs; push(@{$bugs{$_->bug_id}->{$_->attach_id || 0}}, $_) foreach @$flags; - my $fieldid = get_field_id('flagtypes.name'); foreach my $bug_id (keys %bugs) { foreach my $attach_id (keys %{$bugs{$bug_id}}) { my @old_summaries = Bugzilla::Flag->snapshot($bugs{$bug_id}->{$attach_id}); $_->_set_requestee() foreach @{$bugs{$bug_id}->{$attach_id}}; my @new_summaries = Bugzilla::Flag->snapshot($bugs{$bug_id}->{$attach_id}); my ($removed, $added) = - Bugzilla::Flag->update_activity(\@old_summaries, \@new_summaries); - $sth_updateFlag->execute($bug_id, $attach_id || undef, $userid, - $timestamp, $fieldid, $removed, $added); + Bugzilla::Flag->update_activity(\@old_summaries, \@new_summaries); + LogActivityEntry($bug_id, 'flagtypes.name', $removed, $added, + $userid, $timestamp, undef, $attach_id); } $sth_set_bug_timestamp->execute($timestamp, $bug_id); $updatedbugs{$bug_id} = 1; diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl index dfd5c6472..16ddffbe4 100644 --- a/template/en/default/pages/release-notes.html.tmpl +++ b/template/en/default/pages/release-notes.html.tmpl @@ -45,6 +45,12 @@ <h2 id="v44_point">Updates in this 4.4.x Release</h2> +<h3>4.4.5</h3> + +<p>This release fixes a security issue. See the + <a href="http://www.bugzilla.org/security/4.0.13/">Security Advisory</a> + for details.</p> + <h3>4.4.4</h3> <p>This release fixes one regression introduced in [% terms.Bugzilla %] 4.4.3 by |