123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- # -*- 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 Bug Tracking System.
- #
- # The Initial Developer of the Original Code is Netscape Communications
- # Corporation. Portions created by Netscape are
- # Copyright (C) 1998 Netscape Communications Corporation. All
- # Rights Reserved.
- #
- # Contributor(s): Terry Weissman <terry@mozilla.org>
- # Dawn Endico <endico@mozilla.org>
- # Dan Mosedale <dmose@mozilla.org>
- # Joe Robins <jmrobins@tgix.com>
- # Jake <jake@bugzilla.org>
- # J. Paul Reed <preed@sigkill.com>
- # Bradley Baetz <bbaetz@student.usyd.edu.au>
- # Christopher Aillon <christopher@aillon.com>
- # Erik Stambaugh <erik@dasbistro.com>
- # Frédéric Buclin <LpSolit@gmail.com>
- package Bugzilla::Config;
- use strict;
- use base qw(Exporter);
- use Bugzilla::Constants;
- use Data::Dumper;
- use File::Temp;
- # 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)],
- );
- Exporter::export_ok_tags('admin');
- use vars qw(@param_list);
- # 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();
- foreach my $panel (keys %$panels) {
- my $module = $panels->{$panel};
- eval("require $module") || die $@;
- my @new_param_list = "$module"->get_param_list();
- foreach my $item (@new_param_list) {
- $params{$item->{'name'}} = $item;
- }
- push(@param_list, @new_param_list);
- }
- }
- # 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', { config => $param_panels });
- return $param_panels;
- }
- sub SetParam {
- my ($name, $value) = @_;
- _load_params unless %params;
- die "Unknown param $name" unless (exists $params{$name});
- my $entry = $params{$name};
- # 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 '';
- }
- Bugzilla->params->{$name} = $value;
- }
- sub update_params {
- my ($params) = @_;
- my $answer = Bugzilla->installation_answers;
- my $param = read_param_file();
- # If we didn't return any param values, then this is a new installation.
- my $new_install = !(keys %$param);
- # --- UPDATE OLD PARAMS ---
- # Old Bugzilla versions stored the version number in the params file
- # We don't want it, so get rid of it
- delete $param->{'version'};
- # Change from usebrowserinfo to defaultplatform/defaultopsys combo
- if (exists $param->{'usebrowserinfo'}) {
- if (!$param->{'usebrowserinfo'}) {
- if (!exists $param->{'defaultplatform'}) {
- $param->{'defaultplatform'} = 'Other';
- }
- if (!exists $param->{'defaultopsys'}) {
- $param->{'defaultopsys'} = 'Other';
- }
- }
- delete $param->{'usebrowserinfo'};
- }
- # Change from a boolean for quips to multi-state
- if (exists $param->{'usequip'} && !exists $param->{'enablequips'}) {
- $param->{'enablequips'} = $param->{'usequip'} ? 'on' : 'off';
- delete $param->{'usequip'};
- }
- # 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'})
- {
- $param->{'makeproductgroups'} = $param->{'usebuggroups'};
- }
- if (exists $param->{'usebuggroupsentry'}
- && !exists $param->{'useentrygroupdefault'}) {
- $param->{'useentrygroupdefault'} = $param->{'usebuggroupsentry'};
- }
- # Modularise auth code
- if (exists $param->{'useLDAP'} && !exists $param->{'loginmethod'}) {
- $param->{'loginmethod'} = $param->{'useLDAP'} ? "LDAP" : "DB";
- }
- # set verify method to whatever loginmethod was
- if (exists $param->{'loginmethod'}
- && !exists $param->{'user_verify_class'})
- {
- $param->{'user_verify_class'} = $param->{'loginmethod'};
- delete $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';};
- $param->{'quip_list_entry_control'} = $new_value;
- delete $param->{'enablequips'};
- }
- # Old mail_delivery_method choices contained no uppercase characters
- if (exists $param->{'mail_delivery_method'}
- && $param->{'mail_delivery_method'} !~ /[A-Z]/) {
- my $method = $param->{'mail_delivery_method'};
- my %translation = (
- 'sendmail' => 'Sendmail',
- 'smtp' => 'SMTP',
- 'qmail' => 'Qmail',
- 'testfile' => 'Test',
- 'none' => 'None');
- $param->{'mail_delivery_method'} = $translation{$method};
- }
- # --- DEFAULTS FOR NEW PARAMS ---
- _load_params unless %params;
- foreach my $item (@param_list) {
- my $name = $item->{'name'};
- unless (exists $param->{$name}) {
- print "New parameter: $name\n" unless $new_install;
- $param->{$name} = $answer->{$name} || $item->{'default'};
- }
- }
- $param->{'utf8'} = 1 if $new_install;
- # --- REMOVE OLD PARAMS ---
- my %oldparams;
- # Remove any old params, put them in old-params.txt
- foreach my $item (keys %$param) {
- if (!grep($_ eq $item, map ($_->{'name'}, @param_list))) {
- $oldparams{$item} = $param->{$item};
- delete $param->{$item};
- }
- }
- if (scalar(keys %oldparams)) {
- my $op_file = new IO::File('old-params.txt', '>>', 0600)
- || die "old-params.txt: $!";
- print "The following parameters are no longer used in Bugzilla,",
- " and so have been\nmoved from your parameters file into",
- " old-params.txt:\n";
- local $Data::Dumper::Terse = 1;
- local $Data::Dumper::Indent = 0;
- my $comma = "";
- foreach my $item (keys %oldparams) {
- print $op_file "\n\n$item:\n" . Data::Dumper->Dump([$oldparams{$item}]) . "\n";
- print "${comma}$item";
- $comma = ", ";
- }
- print "\n";
- $op_file->close;
- }
- if (ON_WINDOWS && !-e SENDMAIL_EXE
- && $param->{'mail_delivery_method'} eq 'Sendmail')
- {
- my $smtp = $answer->{'SMTP_SERVER'};
- if (!$smtp) {
- print "\nBugzilla requires an SMTP server to function on",
- " Windows.\nPlease enter your SMTP server's hostname: ";
- $smtp = <STDIN>;
- chomp $smtp;
- if ($smtp) {
- $param->{'smtpserver'} = $smtp;
- }
- else {
- print "\nWarning: No SMTP Server provided, defaulting to",
- " localhost\n";
- }
- }
- $param->{'mail_delivery_method'} = 'SMTP';
- }
- write_params($param);
- # 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 $datadir = bz_locations()->{'datadir'};
- my $param_file = "$datadir/params";
- local $Data::Dumper::Sortkeys = 1;
- my ($fh, $tmpname) = File::Temp::tempfile('params.XXXXX',
- DIR => $datadir );
- print $fh (Data::Dumper->Dump([$param_data], ['*param']))
- || die "Can't write param file: $!";
- close $fh;
- rename $tmpname, $param_file
- or die "Can't rename $tmpname to $param_file: $!";
- ChmodDataFile($param_file, 0666);
- # And now we have to reset the params cache so that Bugzilla will re-read
- # them.
- delete Bugzilla->request_cache->{params};
- }
- # Some files in the data directory must be world readable if and only if
- # we don't have a webserver group. Call this function to do this.
- # This will become a private function once all the datafile handling stuff
- # moves into this package
- # This sub is not perldoc'd for that reason - noone should know about it
- sub ChmodDataFile {
- my ($file, $mask) = @_;
- my $perm = 0770;
- if ((stat(bz_locations()->{'datadir'}))[2] & 0002) {
- $perm = 0777;
- }
- $perm = $perm & $mask;
- chmod $perm,$file;
- }
- sub read_param_file {
- my %params;
- my $datadir = bz_locations()->{'datadir'};
- if (-e "$datadir/params") {
- # Note that checksetup.pl sets file permissions on '$datadir/params'
- # Using Safe mode is _not_ a guarantee of safety if someone does
- # manage to write to the file. However, it won't hurt...
- # See bug 165144 for not needing to eval this at all
- my $s = new Safe;
- $s->rdo("$datadir/params");
- die "Error reading $datadir/params: $!" if $!;
- die "Error evaluating $datadir/params: $@" if $@;
- # Now read the param back out from the sandbox
- %params = %{$s->varglob('param')};
- }
- 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 $datadir/params file does not exist."
- . ' You probably need to run checksetup.pl.',
- }
- return \%params;
- }
- 1;
- __END__
- =head1 NAME
- Bugzilla::Config - Configuration parameters for Bugzilla
- =head1 SYNOPSIS
- # Administration functions
- use Bugzilla::Config qw(:admin);
- update_params();
- SetParam($param, $value);
- write_params();
- =head1 DESCRIPTION
- This package contains ways to access Bugzilla configuration parameters.
- =head1 FUNCTIONS
- =head2 Parameters
- Parameters can be set, retrieved, and updated.
- =over 4
- =item C<SetParam($name, $value)>
- Sets the param named $name to $value. Values are checked using the checker
- function for the given param if one exists.
- =item C<update_params()>
- Updates the parameters, by transitioning old params to new formats, setting
- defaults for new params, and removing obsolete ones. Used by F<checksetup.pl>
- in the process of an installation or upgrade.
- Prints out information about what it's doing, if it makes any changes.
- May prompt the user for input, if certain required parameters are not
- specified.
- =item C<write_params($params)>
- Description: Writes the parameters to disk.
- Params: C<$params> (optional) - A hashref to write to the disk
- instead of C<Bugzilla->params>. Used only by
- C<update_params>.
- Returns: nothing
- =item C<read_param_file()>
- Description: Most callers should never need this. This is used
- by C<Bugzilla->params> to directly read C<$datadir/params>
- and load it into memory. Use C<Bugzilla->params> instead.
- Params: none
- Returns: A hashref containing the current params in C<$datadir/params>.
- =back
|