diff options
Diffstat (limited to 'Bugzilla/Config.pm')
-rw-r--r-- | Bugzilla/Config.pm | 527 |
1 files changed, 267 insertions, 260 deletions
diff --git a/Bugzilla/Config.pm b/Bugzilla/Config.pm index 458616701..1aa944985 100644 --- a/Bugzilla/Config.pm +++ b/Bugzilla/Config.pm @@ -25,316 +25,323 @@ use File::Basename; # Don't export localvars by default - people should have to explicitly # ask for it, as a (probably futile) attempt to stop code using it # when it shouldn't -%Bugzilla::Config::EXPORT_TAGS = - ( - admin => [qw(update_params SetParam write_params)], - ); +%Bugzilla::Config::EXPORT_TAGS + = (admin => [qw(update_params SetParam write_params)],); Exporter::export_ok_tags('admin'); # INITIALISATION CODE # Perl throws a warning if we use bz_locations() directly after do. our %params; + # Load in the param definitions sub _load_params { - my $panels = param_panels(); - my %hook_panels; - foreach my $panel (keys %$panels) { - my $module = $panels->{$panel}; - eval("require $module") || die $@; - my @new_param_list = $module->get_param_list(); - $hook_panels{lc($panel)} = { params => \@new_param_list }; - } - # This hook is also called in editparams.cgi. This call here is required - # to make SetParam work. - Bugzilla::Hook::process('config_modify_panels', - { panels => \%hook_panels }); - - foreach my $panel (keys %hook_panels) { - foreach my $item (@{$hook_panels{$panel}->{params}}) { - $params{$item->{'name'}} = $item; - } + my $panels = param_panels(); + my %hook_panels; + foreach my $panel (keys %$panels) { + my $module = $panels->{$panel}; + eval("require $module") || die $@; + my @new_param_list = $module->get_param_list(); + $hook_panels{lc($panel)} = {params => \@new_param_list}; + } + + # This hook is also called in editparams.cgi. This call here is required + # to make SetParam work. + Bugzilla::Hook::process('config_modify_panels', {panels => \%hook_panels}); + + foreach my $panel (keys %hook_panels) { + foreach my $item (@{$hook_panels{$panel}->{params}}) { + $params{$item->{'name'}} = $item; } + } } + # END INIT CODE # Subroutines go here sub param_panels { - my $param_panels = {}; - my $libpath = bz_locations()->{'libpath'}; - foreach my $item ((glob "$libpath/Bugzilla/Config/*.pm")) { - $item =~ m#/([^/]+)\.pm$#; - my $module = $1; - $param_panels->{$module} = "Bugzilla::Config::$module" unless $module eq 'Common'; - } - # Now check for any hooked params - Bugzilla::Hook::process('config_add_panels', - { panel_modules => $param_panels }); - return $param_panels; + my $param_panels = {}; + my $libpath = bz_locations()->{'libpath'}; + foreach my $item ((glob "$libpath/Bugzilla/Config/*.pm")) { + $item =~ m#/([^/]+)\.pm$#; + my $module = $1; + $param_panels->{$module} = "Bugzilla::Config::$module" + unless $module eq 'Common'; + } + + # Now check for any hooked params + Bugzilla::Hook::process('config_add_panels', {panel_modules => $param_panels}); + return $param_panels; } sub SetParam { - my ($name, $value) = @_; + my ($name, $value) = @_; - _load_params unless %params; - die "Unknown param $name" unless (exists $params{$name}); + _load_params unless %params; + die "Unknown param $name" unless (exists $params{$name}); - my $entry = $params{$name}; + my $entry = $params{$name}; - # sanity check the value + # sanity check the value - # XXX - This runs the checks. Which would be good, except that - # check_shadowdb creates the database as a side effect, and so the - # checker fails the second time around... - if ($name ne 'shadowdb' && exists $entry->{'checker'}) { - my $err = $entry->{'checker'}->($value, $entry); - die "Param $name is not valid: $err" unless $err eq ''; - } + # XXX - This runs the checks. Which would be good, except that + # check_shadowdb creates the database as a side effect, and so the + # checker fails the second time around... + if ($name ne 'shadowdb' && exists $entry->{'checker'}) { + my $err = $entry->{'checker'}->($value, $entry); + die "Param $name is not valid: $err" unless $err eq ''; + } - Bugzilla->params->{$name} = $value; + Bugzilla->params->{$name} = $value; } sub update_params { - my ($params) = @_; - my $answer = Bugzilla->installation_answers; - my $datadir = bz_locations()->{'datadir'}; - my $param; - - # If the old data/params file using Data::Dumper output still exists, - # read it. It will be deleted once the parameters are stored in the new - # data/params.json file. - my $old_file = "$datadir/params"; - - if (-e $old_file) { - require Safe; - my $s = new Safe; - - $s->rdo($old_file); - die "Error reading $old_file: $!" if $!; - die "Error evaluating $old_file: $@" if $@; - - # Now read the param back out from the sandbox. - $param = \%{ $s->varglob('param') }; + my ($params) = @_; + my $answer = Bugzilla->installation_answers; + my $datadir = bz_locations()->{'datadir'}; + my $param; + + # If the old data/params file using Data::Dumper output still exists, + # read it. It will be deleted once the parameters are stored in the new + # data/params.json file. + my $old_file = "$datadir/params"; + + if (-e $old_file) { + require Safe; + my $s = new Safe; + + $s->rdo($old_file); + die "Error reading $old_file: $!" if $!; + die "Error evaluating $old_file: $@" if $@; + + # Now read the param back out from the sandbox. + $param = \%{$s->varglob('param')}; + } + else { + # Rename params.js to params.json if checksetup.pl + # was executed with an earlier version of this change + rename "$old_file.js", "$old_file.json" + if -e "$old_file.js" && !-e "$old_file.json"; + + # Read the new data/params.json file. + $param = read_param_file(); + } + + my %new_params; + + # If we didn't return any param values, then this is a new installation. + my $new_install = !(keys %$param); + + # --- UPDATE OLD PARAMS --- + + # Change from usebrowserinfo to defaultplatform/defaultopsys combo + if (exists $param->{'usebrowserinfo'}) { + if (!$param->{'usebrowserinfo'}) { + if (!exists $param->{'defaultplatform'}) { + $new_params{'defaultplatform'} = 'Other'; + } + if (!exists $param->{'defaultopsys'}) { + $new_params{'defaultopsys'} = 'Other'; + } } - else { - # Rename params.js to params.json if checksetup.pl - # was executed with an earlier version of this change - rename "$old_file.js", "$old_file.json" - if -e "$old_file.js" && !-e "$old_file.json"; - - # Read the new data/params.json file. - $param = read_param_file(); + } + + # Change from a boolean for quips to multi-state + if (exists $param->{'usequip'} && !exists $param->{'enablequips'}) { + $new_params{'enablequips'} = $param->{'usequip'} ? 'on' : 'off'; + } + + # Change from old product groups to controls for group_control_map + # 2002-10-14 bug 147275 bugreport@peshkin.net + if (exists $param->{'usebuggroups'} && !exists $param->{'makeproductgroups'}) { + $new_params{'makeproductgroups'} = $param->{'usebuggroups'}; + } + + # Modularise auth code + if (exists $param->{'useLDAP'} && !exists $param->{'loginmethod'}) { + $new_params{'loginmethod'} = $param->{'useLDAP'} ? "LDAP" : "DB"; + } + + # set verify method to whatever loginmethod was + if (exists $param->{'loginmethod'} && !exists $param->{'user_verify_class'}) { + $new_params{'user_verify_class'} = $param->{'loginmethod'}; + } + + # Remove quip-display control from parameters + # and give it to users via User Settings (Bug 41972) + if (exists $param->{'enablequips'} + && !exists $param->{'quip_list_entry_control'}) + { + my $new_value; + ($param->{'enablequips'} eq 'on') && do { $new_value = 'open'; }; + ($param->{'enablequips'} eq 'approved') && do { $new_value = 'moderated'; }; + ($param->{'enablequips'} eq 'frozen') && do { $new_value = 'closed'; }; + ($param->{'enablequips'} eq 'off') && do { $new_value = 'closed'; }; + $new_params{'quip_list_entry_control'} = $new_value; + } + + # Old mail_delivery_method choices contained no uppercase characters + my $mta = $param->{'mail_delivery_method'}; + if ($mta) { + if ($mta !~ /[A-Z]/) { + my %translation = ( + 'sendmail' => 'Sendmail', + 'smtp' => 'SMTP', + 'qmail' => 'Qmail', + 'testfile' => 'Test', + 'none' => 'None' + ); + $param->{'mail_delivery_method'} = $translation{$mta}; } - my %new_params; - - # If we didn't return any param values, then this is a new installation. - my $new_install = !(keys %$param); - - # --- UPDATE OLD PARAMS --- - - # Change from usebrowserinfo to defaultplatform/defaultopsys combo - if (exists $param->{'usebrowserinfo'}) { - if (!$param->{'usebrowserinfo'}) { - if (!exists $param->{'defaultplatform'}) { - $new_params{'defaultplatform'} = 'Other'; - } - if (!exists $param->{'defaultopsys'}) { - $new_params{'defaultopsys'} = 'Other'; - } - } + # This will force the parameter to be reset to its default value. + delete $param->{'mail_delivery_method'} + if $param->{'mail_delivery_method'} eq 'Qmail'; + } + + # Convert the old "ssl" parameter to the new "ssl_redirect" parameter. + # Both "authenticated sessions" and "always" turn on "ssl_redirect" + # when upgrading. + if (exists $param->{'ssl'} and $param->{'ssl'} ne 'never') { + $new_params{'ssl_redirect'} = 1; + } + +# "specific_search_allow_empty_words" has been renamed to "search_allow_no_criteria". + if (exists $param->{'specific_search_allow_empty_words'}) { + $new_params{'search_allow_no_criteria'} + = $param->{'specific_search_allow_empty_words'}; + } + + # --- DEFAULTS FOR NEW PARAMS --- + + _load_params unless %params; + foreach my $name (keys %params) { + my $item = $params{$name}; + unless (exists $param->{$name}) { + print "New parameter: $name\n" unless $new_install; + if (exists $new_params{$name}) { + $param->{$name} = $new_params{$name}; + } + elsif (exists $answer->{$name}) { + $param->{$name} = $answer->{$name}; + } + else { + $param->{$name} = $item->{'default'}; + } } + } - # Change from a boolean for quips to multi-state - if (exists $param->{'usequip'} && !exists $param->{'enablequips'}) { - $new_params{'enablequips'} = $param->{'usequip'} ? 'on' : 'off'; - } + $param->{'utf8'} = 1 if $new_install; - # Change from old product groups to controls for group_control_map - # 2002-10-14 bug 147275 bugreport@peshkin.net - if (exists $param->{'usebuggroups'} && - !exists $param->{'makeproductgroups'}) - { - $new_params{'makeproductgroups'} = $param->{'usebuggroups'}; - } + # Bug 452525: OR based groups are on by default for new installations + $param->{'or_groups'} = 1 if $new_install; - # Modularise auth code - if (exists $param->{'useLDAP'} && !exists $param->{'loginmethod'}) { - $new_params{'loginmethod'} = $param->{'useLDAP'} ? "LDAP" : "DB"; - } + # --- REMOVE OLD PARAMS --- - # set verify method to whatever loginmethod was - if (exists $param->{'loginmethod'} - && !exists $param->{'user_verify_class'}) - { - $new_params{'user_verify_class'} = $param->{'loginmethod'}; - } + my %oldparams; - # Remove quip-display control from parameters - # and give it to users via User Settings (Bug 41972) - if ( exists $param->{'enablequips'} - && !exists $param->{'quip_list_entry_control'}) - { - my $new_value; - ($param->{'enablequips'} eq 'on') && do {$new_value = 'open';}; - ($param->{'enablequips'} eq 'approved') && do {$new_value = 'moderated';}; - ($param->{'enablequips'} eq 'frozen') && do {$new_value = 'closed';}; - ($param->{'enablequips'} eq 'off') && do {$new_value = 'closed';}; - $new_params{'quip_list_entry_control'} = $new_value; + # Remove any old params + foreach my $item (keys %$param) { + if (!exists $params{$item}) { + $oldparams{$item} = delete $param->{$item}; } - - # Old mail_delivery_method choices contained no uppercase characters - my $mta = $param->{'mail_delivery_method'}; - if ($mta) { - if ($mta !~ /[A-Z]/) { - my %translation = ( - 'sendmail' => 'Sendmail', - 'smtp' => 'SMTP', - 'qmail' => 'Qmail', - 'testfile' => 'Test', - 'none' => 'None'); - $param->{'mail_delivery_method'} = $translation{$mta}; - } - # This will force the parameter to be reset to its default value. - delete $param->{'mail_delivery_method'} if $param->{'mail_delivery_method'} eq 'Qmail'; + } + + # Write any old parameters to old-params.txt + my $old_param_file = "$datadir/old-params.txt"; + if (scalar(keys %oldparams)) { + my $op_file = new IO::File($old_param_file, '>>', 0600) + || die "Couldn't create $old_param_file: $!"; + + print "The following parameters are no longer used in Bugzilla,", + " and so have been\nmoved from your parameters file into", + " $old_param_file:\n"; + + my $comma = ""; + foreach my $item (keys %oldparams) { + print $op_file "\n\n$item:\n" . $oldparams{$item} . "\n"; + print "${comma}$item"; + $comma = ", "; } + print "\n"; + $op_file->close; + } - # Convert the old "ssl" parameter to the new "ssl_redirect" parameter. - # Both "authenticated sessions" and "always" turn on "ssl_redirect" - # when upgrading. - if (exists $param->{'ssl'} and $param->{'ssl'} ne 'never') { - $new_params{'ssl_redirect'} = 1; - } + write_params($param); - # "specific_search_allow_empty_words" has been renamed to "search_allow_no_criteria". - if (exists $param->{'specific_search_allow_empty_words'}) { - $new_params{'search_allow_no_criteria'} = $param->{'specific_search_allow_empty_words'}; - } + if (-e $old_file) { + unlink $old_file; + say "$old_file has been converted into $old_file.json, using the JSON format."; + } - # --- DEFAULTS FOR NEW PARAMS --- - - _load_params unless %params; - foreach my $name (keys %params) { - my $item = $params{$name}; - unless (exists $param->{$name}) { - print "New parameter: $name\n" unless $new_install; - if (exists $new_params{$name}) { - $param->{$name} = $new_params{$name}; - } - elsif (exists $answer->{$name}) { - $param->{$name} = $answer->{$name}; - } - else { - $param->{$name} = $item->{'default'}; - } - } - } - - $param->{'utf8'} = 1 if $new_install; - - # Bug 452525: OR based groups are on by default for new installations - $param->{'or_groups'} = 1 if $new_install; - - # --- REMOVE OLD PARAMS --- - - my %oldparams; - # Remove any old params - foreach my $item (keys %$param) { - if (!exists $params{$item}) { - $oldparams{$item} = delete $param->{$item}; - } - } - - # Write any old parameters to old-params.txt - my $old_param_file = "$datadir/old-params.txt"; - if (scalar(keys %oldparams)) { - my $op_file = new IO::File($old_param_file, '>>', 0600) - || die "Couldn't create $old_param_file: $!"; - - print "The following parameters are no longer used in Bugzilla,", - " and so have been\nmoved from your parameters file into", - " $old_param_file:\n"; - - my $comma = ""; - foreach my $item (keys %oldparams) { - print $op_file "\n\n$item:\n" . $oldparams{$item} . "\n"; - print "${comma}$item"; - $comma = ", "; - } - print "\n"; - $op_file->close; - } - - write_params($param); - - if (-e $old_file) { - unlink $old_file; - say "$old_file has been converted into $old_file.json, using the JSON format."; - } - - # Return deleted params and values so that checksetup.pl has a chance - # to convert old params to new data. - return %oldparams; + # Return deleted params and values so that checksetup.pl has a chance + # to convert old params to new data. + return %oldparams; } sub write_params { - my ($param_data) = @_; - $param_data ||= Bugzilla->params; - my $param_file = bz_locations()->{'datadir'} . '/params.json'; + my ($param_data) = @_; + $param_data ||= Bugzilla->params; + my $param_file = bz_locations()->{'datadir'} . '/params.json'; - my $json_data = JSON::XS->new->canonical->pretty->encode($param_data); - write_text($param_file, $json_data); + my $json_data = JSON::XS->new->canonical->pretty->encode($param_data); + write_text($param_file, $json_data); - # It's not common to edit parameters and loading - # Bugzilla::Install::Filesystem is slow. - require Bugzilla::Install::Filesystem; - Bugzilla::Install::Filesystem::fix_file_permissions($param_file); + # It's not common to edit parameters and loading + # Bugzilla::Install::Filesystem is slow. + require Bugzilla::Install::Filesystem; + Bugzilla::Install::Filesystem::fix_file_permissions($param_file); - # And now we have to reset the params cache so that Bugzilla will re-read - # them. - delete Bugzilla->request_cache->{params}; + # And now we have to reset the params cache so that Bugzilla will re-read + # them. + delete Bugzilla->request_cache->{params}; } sub read_param_file { - my %params; - my $file = bz_locations()->{'datadir'} . '/params.json'; - - if (-e $file) { - my $data = read_text($file); - trick_taint($data); - - # If params.json has been manually edited and e.g. some quotes are - # missing, we don't want JSON::XS to leak the content of the file - # to all users in its error message, so we have to eval'uate it. - %params = eval { %{JSON::XS->new->decode($data)} }; - if ($@) { - my $error_msg = (basename($0) eq 'checksetup.pl') ? - $@ : 'run checksetup.pl to see the details.'; - die "Error parsing $file: $error_msg"; - } - # JSON::XS doesn't detaint data for us. - foreach my $key (keys %params) { - if (ref($params{$key}) eq "ARRAY") { - foreach my $item (@{$params{$key}}) { - trick_taint($item); - } - } else { - trick_taint($params{$key}) if defined $params{$key}; - } - } + my %params; + my $file = bz_locations()->{'datadir'} . '/params.json'; + + if (-e $file) { + my $data = read_text($file); + trick_taint($data); + + # If params.json has been manually edited and e.g. some quotes are + # missing, we don't want JSON::XS to leak the content of the file + # to all users in its error message, so we have to eval'uate it. + %params = eval { %{JSON::XS->new->decode($data)} }; + if ($@) { + my $error_msg + = (basename($0) eq 'checksetup.pl') + ? $@ + : 'run checksetup.pl to see the details.'; + die "Error parsing $file: $error_msg"; } - elsif ($ENV{'SERVER_SOFTWARE'}) { - # We're in a CGI, but the params file doesn't exist. We can't - # Template Toolkit, or even install_string, since checksetup - # might not have thrown an error. Bugzilla::CGI->new - # hasn't even been called yet, so we manually use CGI::Carp here - # so that the user sees the error. - require CGI::Carp; - CGI::Carp->import('fatalsToBrowser'); - die "The $file file does not exist." - . ' You probably need to run checksetup.pl.', + + # JSON::XS doesn't detaint data for us. + foreach my $key (keys %params) { + if (ref($params{$key}) eq "ARRAY") { + foreach my $item (@{$params{$key}}) { + trick_taint($item); + } + } + else { + trick_taint($params{$key}) if defined $params{$key}; + } } - return \%params; + } + elsif ($ENV{'SERVER_SOFTWARE'}) { + + # We're in a CGI, but the params file doesn't exist. We can't + # Template Toolkit, or even install_string, since checksetup + # might not have thrown an error. Bugzilla::CGI->new + # hasn't even been called yet, so we manually use CGI::Carp here + # so that the user sees the error. + require CGI::Carp; + CGI::Carp->import('fatalsToBrowser'); + die "The $file file does not exist." + . ' You probably need to run checksetup.pl.',; + } + return \%params; } 1; |