Bug 351983: Move admin creation out of checksetup.pl and into Bugzilla::Install
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> (module owner) a=justdave git-svn-id: svn://10.0.0.236/trunk@209603 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -26,8 +26,11 @@ package Bugzilla::Install;
|
||||
|
||||
use strict;
|
||||
|
||||
use Bugzilla::Constants;
|
||||
use Bugzilla::Error;
|
||||
use Bugzilla::Group;
|
||||
use Bugzilla::Product;
|
||||
use Bugzilla::User;
|
||||
use Bugzilla::User::Setting;
|
||||
use Bugzilla::Version;
|
||||
|
||||
@@ -136,6 +139,128 @@ sub create_default_product {
|
||||
|
||||
}
|
||||
|
||||
sub create_admin {
|
||||
my ($params) = @_;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $template = Bugzilla->template;
|
||||
|
||||
my $admin_group = new Bugzilla::Group({ name => 'admin' });
|
||||
my $admin_inheritors =
|
||||
Bugzilla::User->flatten_group_membership($admin_group->id);
|
||||
my $admin_group_ids = join(',', @$admin_inheritors);
|
||||
|
||||
my ($admin_count) = $dbh->selectrow_array(
|
||||
"SELECT COUNT(*) FROM user_group_map
|
||||
WHERE group_id IN ($admin_group_ids)");
|
||||
|
||||
return if $admin_count;
|
||||
|
||||
my %answer = %{$params->{answer} || {}};
|
||||
my $login = $answer{'ADMIN_EMAIL'};
|
||||
my $password = $answer{'ADMIN_PASSWORD'};
|
||||
my $full_name = $answer{'ADMIN_REALNAME'};
|
||||
|
||||
if (!$login || !$password || !$full_name) {
|
||||
print "\n" . get_text('install_admin_setup') . "\n\n";
|
||||
}
|
||||
|
||||
while (!$login) {
|
||||
print get_text('install_admin_get_email') . ' ';
|
||||
$login = <STDIN>;
|
||||
chomp $login;
|
||||
eval { Bugzilla::User->check_login_name_for_creation($login); };
|
||||
if ($@) {
|
||||
print $@ . "\n";
|
||||
undef $login;
|
||||
}
|
||||
}
|
||||
|
||||
while (!defined $full_name) {
|
||||
print get_text('install_admin_get_name') . ' ';
|
||||
$full_name = <STDIN>;
|
||||
chomp($full_name);
|
||||
}
|
||||
|
||||
while (!$password) {
|
||||
# trap a few interrupts so we can fix the echo if we get aborted.
|
||||
local $SIG{HUP} = \&_create_admin_exit;
|
||||
local $SIG{INT} = \&_create_admin_exit;
|
||||
local $SIG{QUIT} = \&_create_admin_exit;
|
||||
local $SIG{TERM} = \&_create_admin_exit;
|
||||
|
||||
system("stty","-echo") unless ON_WINDOWS; # disable input echoing
|
||||
|
||||
print get_text('install_admin_get_password') . ' ';
|
||||
$password = <STDIN>;
|
||||
print "\n", get_text('install_admin_get_password2') . ' ';
|
||||
my $pass2 = <STDIN>;
|
||||
eval { validate_password($password, $pass2); };
|
||||
if ($@) {
|
||||
print "\n$@\n";
|
||||
undef $password;
|
||||
}
|
||||
system("stty","echo") unless ON_WINDOWS;
|
||||
}
|
||||
|
||||
my $admin = Bugzilla::User->create({ login_name => $login,
|
||||
realname => $full_name,
|
||||
cryptpassword => $password });
|
||||
make_admin($admin);
|
||||
}
|
||||
|
||||
sub make_admin {
|
||||
my ($user) = @_;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
$user = ref($user) ? $user
|
||||
: new Bugzilla::User(login_to_id($user, THROW_ERROR));
|
||||
|
||||
my $admin_group = new Bugzilla::Group({ name => 'admin' });
|
||||
|
||||
# Admins get explicit membership and bless capability for the admin group
|
||||
$dbh->selectrow_array("SELECT id FROM groups WHERE name = 'admin'");
|
||||
|
||||
my $group_insert = $dbh->prepare(
|
||||
'INSERT INTO user_group_map (user_id, group_id, isbless, grant_type)
|
||||
VALUES (?, ?, ?, ?)');
|
||||
# These are run in an eval so that we can ignore the error of somebody
|
||||
# already being granted these things.
|
||||
eval {
|
||||
$group_insert->execute($user->id, $admin_group->id, 0, GRANT_DIRECT);
|
||||
};
|
||||
eval {
|
||||
$group_insert->execute($user->id, $admin_group->id, 1, GRANT_DIRECT);
|
||||
};
|
||||
|
||||
# Admins should also have editusers directly, even though they'll usually
|
||||
# inherit it. People could have changed their inheritance structure.
|
||||
my $editusers = new Bugzilla::Group({ name => 'editusers' });
|
||||
eval {
|
||||
$group_insert->execute($user->id, $editusers->id, 0, GRANT_DIRECT);
|
||||
};
|
||||
|
||||
print "\n", get_text('install_admin_created', { user => $user }), "\n";
|
||||
}
|
||||
|
||||
# This is just in case we get interrupted while getting the admin's password.
|
||||
sub _create_admin_exit {
|
||||
# re-enable input echoing
|
||||
system("stty","echo") unless ON_WINDOWS;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub get_text {
|
||||
my ($name, $vars) = @_;
|
||||
my $template = Bugzilla->template;
|
||||
$vars ||= {};
|
||||
$vars->{'message'} = $name;
|
||||
my $message;
|
||||
$template->process('global/message.txt.tmpl', $vars, \$message)
|
||||
|| ThrowTemplateError($template->error());
|
||||
$message =~ s/^\s+//gm;
|
||||
return $message;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
@@ -44,6 +44,7 @@ checksetup.pl - A do-it-all upgrade and installation script for Bugzilla.
|
||||
|
||||
./checksetup.pl [--help|--check-modules]
|
||||
./checksetup.pl [SCRIPT [--verbose]] [--no-templates|-t]
|
||||
./checksetup.pl --make-admin=user@domain.com
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
@@ -65,6 +66,12 @@ Display this help text
|
||||
|
||||
Only check for correct module dependencies and quit afterward.
|
||||
|
||||
=item B<--make-admin>=username@domain.com
|
||||
|
||||
Makes the specified user into a Bugzilla administrator. This is
|
||||
in case you accidentally lock yourself out of the Bugzilla administrative
|
||||
interface.
|
||||
|
||||
=item B<--no-templates> (B<-t>)
|
||||
|
||||
Don't compile the templates at all. Existing compiled templates will
|
||||
@@ -204,7 +211,6 @@ The format of that file is as follows:
|
||||
|
||||
(Any localconfig variable or parameter can be specified as above.)
|
||||
|
||||
$answer{'ADMIN_OK'} = 'Y';
|
||||
$answer{'ADMIN_EMAIL'} = 'myadmin@mydomain.net';
|
||||
$answer{'ADMIN_PASSWORD'} = 'fooey';
|
||||
$answer{'ADMIN_REALNAME'} = 'Joel Peshkin';
|
||||
@@ -270,7 +276,7 @@ sub read_answers_file {
|
||||
|
||||
my %switch;
|
||||
GetOptions(\%switch, 'help|h|?', 'check-modules', 'no-templates|t',
|
||||
'verbose|v|no-silent');
|
||||
'verbose|v|no-silent', 'make-admin=s');
|
||||
|
||||
# Print the help message if that switch was selected.
|
||||
pod2usage({-verbose => 1, -exitval => 1}) if $switch{'help'};
|
||||
@@ -343,6 +349,8 @@ require Bugzilla::Template;
|
||||
require Bugzilla::Field;
|
||||
require Bugzilla::Install;
|
||||
|
||||
Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
|
||||
|
||||
###########################################################################
|
||||
# Check and update --LOCAL-- configuration
|
||||
###########################################################################
|
||||
@@ -585,215 +593,8 @@ Bugzilla::Install::update_settings();
|
||||
# Create Administrator --ADMIN--
|
||||
###########################################################################
|
||||
|
||||
sub bailout { # this is just in case we get interrupted while getting passwd
|
||||
if ($^O !~ /MSWin32/i) {
|
||||
system("stty","echo"); # re-enable input echoing
|
||||
}
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my @groups = ();
|
||||
$sth = $dbh->prepare("SELECT id FROM groups");
|
||||
$sth->execute();
|
||||
while ( my @row = $sth->fetchrow_array() ) {
|
||||
push (@groups, $row[0]);
|
||||
}
|
||||
|
||||
# Prompt the user for the email address and name of an administrator. Create
|
||||
# that login, if it doesn't exist already, and make it a member of all groups.
|
||||
|
||||
$sth = $dbh->prepare("SELECT user_id FROM groups INNER JOIN user_group_map " .
|
||||
"ON id = group_id WHERE name = 'admin'");
|
||||
$sth->execute;
|
||||
# when we have no admin users, prompt for admin email address and password ...
|
||||
if ($sth->rows == 0) {
|
||||
my $login = "";
|
||||
my $realname = "";
|
||||
my $pass1 = "";
|
||||
my $pass2 = "*";
|
||||
my $admin_ok = 0;
|
||||
my $admin_create = 1;
|
||||
my $mailcheckexp = "";
|
||||
my $mailcheck = "";
|
||||
|
||||
# Here we look to see what the emailregexp is set to so we can
|
||||
# check the email address they enter. Bug 96675. If they have no
|
||||
# params (likely but not always the case), we use the default.
|
||||
if (-e "$datadir/params") {
|
||||
require "$datadir/params"; # if they have a params file, use that
|
||||
}
|
||||
if (Bugzilla->params->{'emailregexp'}) {
|
||||
$mailcheckexp = Bugzilla->params->{'emailregexp'};
|
||||
$mailcheck = Bugzilla->params->{'emailregexpdesc'};
|
||||
} else {
|
||||
$mailcheckexp = '^[\\w\\.\\+\\-=]+@[\\w\\.\\-]+\\.[\\w\\-]+$';
|
||||
$mailcheck = 'A legal address must contain exactly one \'@\',
|
||||
and at least one \'.\' after the @.';
|
||||
}
|
||||
|
||||
print "\nLooks like we don't have an administrator set up yet.\n";
|
||||
print "Either this is your first time using Bugzilla, or your\n ";
|
||||
print "administrator's privileges might have accidentally been deleted.\n";
|
||||
while(! $admin_ok ) {
|
||||
while( $login eq "" ) {
|
||||
print "Enter the e-mail address of the administrator: ";
|
||||
$login = $answer{'ADMIN_EMAIL'}
|
||||
|| ($silent && die("cant preload ADMIN_EMAIL"))
|
||||
|| <STDIN>;
|
||||
chomp $login;
|
||||
if(! $login ) {
|
||||
print "\nYou DO want an administrator, don't you?\n";
|
||||
}
|
||||
unless ($login =~ /$mailcheckexp/) {
|
||||
print "\nThe login address is invalid:\n";
|
||||
print "$mailcheck\n";
|
||||
print "You can change this test on the params page once checksetup has successfully\n";
|
||||
print "completed.\n\n";
|
||||
# Go round, and ask them again
|
||||
$login = "";
|
||||
}
|
||||
}
|
||||
$sth = $dbh->prepare("SELECT login_name FROM profiles " .
|
||||
"WHERE " . $dbh->sql_istrcmp('login_name', '?'));
|
||||
$sth->execute($login);
|
||||
if ($sth->rows > 0) {
|
||||
print "$login already has an account.\n";
|
||||
print "Make this user the administrator? [Y/n] ";
|
||||
my $ok = $answer{'ADMIN_OK'}
|
||||
|| ($silent && die("cant preload ADMIN_OK"))
|
||||
|| <STDIN>;
|
||||
chomp $ok;
|
||||
if ($ok !~ /^n/i) {
|
||||
$admin_ok = 1;
|
||||
$admin_create = 0;
|
||||
} else {
|
||||
print "OK, well, someone has to be the administrator.\n";
|
||||
print "Try someone else.\n";
|
||||
$login = "";
|
||||
}
|
||||
} else {
|
||||
print "You entered $login. Is this correct? [Y/n] ";
|
||||
my $ok = $answer{'ADMIN_OK'}
|
||||
|| ($silent && die("cant preload ADMIN_OK"))
|
||||
|| <STDIN>;
|
||||
chomp $ok;
|
||||
if ($ok !~ /^n/i) {
|
||||
$admin_ok = 1;
|
||||
} else {
|
||||
print "That's okay, typos happen. Give it another shot.\n";
|
||||
$login = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($admin_create) {
|
||||
while( $realname eq "" ) {
|
||||
print "Enter the real name of the administrator: ";
|
||||
$realname = $answer{'ADMIN_REALNAME'}
|
||||
|| ($silent && die("cant preload ADMIN_REALNAME"))
|
||||
|| <STDIN>;
|
||||
chomp $realname;
|
||||
if(! $realname ) {
|
||||
print "\nReally. We need a full name.\n";
|
||||
}
|
||||
if(! is_7bit_clean($realname)) {
|
||||
print "\nSorry, but at this stage the real name can only " .
|
||||
"contain standard English\ncharacters. Once Bugzilla " .
|
||||
"has been installed, you can use the 'Prefs' page\nto " .
|
||||
"update the real name.\n";
|
||||
$realname = '';
|
||||
}
|
||||
}
|
||||
|
||||
# trap a few interrupts so we can fix the echo if we get aborted.
|
||||
$SIG{HUP} = \&bailout;
|
||||
$SIG{INT} = \&bailout;
|
||||
$SIG{QUIT} = \&bailout;
|
||||
$SIG{TERM} = \&bailout;
|
||||
|
||||
if ($^O !~ /MSWin32/i) {
|
||||
system("stty","-echo"); # disable input echoing
|
||||
}
|
||||
|
||||
while( $pass1 ne $pass2 ) {
|
||||
while( $pass1 eq "" || $pass1 !~ /^[[:print:]]{3,16}$/ ) {
|
||||
print "Enter a password for the administrator account: ";
|
||||
$pass1 = $answer{'ADMIN_PASSWORD'}
|
||||
|| ($silent && die("cant preload ADMIN_PASSWORD"))
|
||||
|| <STDIN>;
|
||||
chomp $pass1;
|
||||
if(! $pass1 ) {
|
||||
print "\n\nAn empty password is a security risk. Try again!\n";
|
||||
} elsif ( $pass1 !~ /^.{3,16}$/ ) {
|
||||
print "\n\nThe password must be 3-16 characters in length.\n";
|
||||
} elsif ( $pass1 !~ /^[[:print:]]{3,16}$/ ) {
|
||||
print "\n\nThe password contains non-printable characters.\n";
|
||||
}
|
||||
}
|
||||
print "\nPlease retype the password to verify: ";
|
||||
$pass2 = $answer{'ADMIN_PASSWORD'}
|
||||
|| ($silent && die("cant preload ADMIN_PASSWORD"))
|
||||
|| <STDIN>;
|
||||
chomp $pass2;
|
||||
if ($pass1 ne $pass2) {
|
||||
print "\n\nPasswords don't match. Try again!\n";
|
||||
$pass1 = "";
|
||||
$pass2 = "*";
|
||||
}
|
||||
}
|
||||
|
||||
if ($^O !~ /MSWin32/i) {
|
||||
system("stty","echo"); # re-enable input echoing
|
||||
}
|
||||
|
||||
$SIG{HUP} = 'DEFAULT'; # and remove our interrupt hooks
|
||||
$SIG{INT} = 'DEFAULT';
|
||||
$SIG{QUIT} = 'DEFAULT';
|
||||
$SIG{TERM} = 'DEFAULT';
|
||||
|
||||
Bugzilla::User->create({
|
||||
login_name => $login,
|
||||
realname => $realname,
|
||||
cryptpassword => $pass1});
|
||||
}
|
||||
|
||||
# Put the admin in each group if not already
|
||||
my $userid = $dbh->selectrow_array("SELECT userid FROM profiles WHERE " .
|
||||
$dbh->sql_istrcmp('login_name', '?'),
|
||||
undef, $login);
|
||||
|
||||
# Admins get explicit membership and bless capability for the admin group
|
||||
my ($admingroupid) = $dbh->selectrow_array("SELECT id FROM groups
|
||||
WHERE name = 'admin'");
|
||||
$dbh->do("INSERT INTO user_group_map
|
||||
(user_id, group_id, isbless, grant_type)
|
||||
VALUES ($userid, $admingroupid, 0, " . GRANT_DIRECT . ")");
|
||||
$dbh->do("INSERT INTO user_group_map
|
||||
(user_id, group_id, isbless, grant_type)
|
||||
VALUES ($userid, $admingroupid, 1, " . GRANT_DIRECT . ")");
|
||||
|
||||
# Admins get inherited membership and bless capability for all groups
|
||||
foreach my $group ( @groups ) {
|
||||
my $sth_check = $dbh->prepare("SELECT member_id FROM group_group_map
|
||||
WHERE member_id = ?
|
||||
AND grantor_id = ?
|
||||
AND grant_type = ?");
|
||||
$sth_check->execute($admingroupid, $group, GROUP_MEMBERSHIP);
|
||||
unless ($sth_check->rows) {
|
||||
$dbh->do("INSERT INTO group_group_map
|
||||
(member_id, grantor_id, grant_type)
|
||||
VALUES ($admingroupid, $group, " . GROUP_MEMBERSHIP . ")");
|
||||
}
|
||||
$sth_check->execute($admingroupid, $group, GROUP_BLESS);
|
||||
unless ($sth_check->rows) {
|
||||
$dbh->do("INSERT INTO group_group_map
|
||||
(member_id, grantor_id, grant_type)
|
||||
VALUES ($admingroupid, $group, " . GROUP_BLESS . ")");
|
||||
}
|
||||
}
|
||||
|
||||
print "\n$login is now set up as an administrator account.\n";
|
||||
}
|
||||
Bugzilla::Install::make_admin($switch{'make-admin'}) if $switch{'make-admin'};
|
||||
Bugzilla::Install::create_admin({ answer => \%answer });
|
||||
|
||||
###########################################################################
|
||||
# Create default Product and Classification
|
||||
@@ -805,14 +606,6 @@ Bugzilla::Install::create_default_product();
|
||||
# Final checks
|
||||
###########################################################################
|
||||
|
||||
$sth = $dbh->prepare("SELECT user_id " .
|
||||
"FROM groups INNER JOIN user_group_map " .
|
||||
"ON groups.id = user_group_map.group_id " .
|
||||
"WHERE groups.name = 'admin'");
|
||||
$sth->execute;
|
||||
my ($adminuid) = $sth->fetchrow_array;
|
||||
if (!$adminuid) { die "No administrator!" } # should never get here
|
||||
|
||||
# Check if the default parameter for urlbase is still set, and if so, give
|
||||
# notification that they should go and visit editparams.cgi
|
||||
|
||||
|
||||
@@ -262,6 +262,26 @@
|
||||
<a href="editflagtypes.cgi">Back to flag types.</a>
|
||||
</p>
|
||||
|
||||
[% ELSIF message_tag == "install_admin_get_email" %]
|
||||
Enter the e-mail address of the administrator:
|
||||
|
||||
[% ELSIF message_tag == "install_admin_get_name" %]
|
||||
Enter the real name of the administrator:
|
||||
|
||||
[% ELSIF message_tag == "install_admin_get_password" %]
|
||||
Enter a password for the administrator account:
|
||||
|
||||
[% ELSIF message_tag == "install_admin_get_password2" %]
|
||||
Please retype the password to verify:
|
||||
|
||||
[% ELSIF message_tag == "install_admin_created" %]
|
||||
[% user.login FILTER html %] is now set up as an administrator.
|
||||
|
||||
[% ELSIF message_tag == "install_admin_setup" %]
|
||||
Looks like we don't have an administrator set up yet.
|
||||
Either this is your first time using Bugzilla, or your
|
||||
administrator's privileges might have accidentally been deleted.
|
||||
|
||||
[% ELSIF message_tag == "product_invalid" %]
|
||||
[% title = "$terms.Bugzilla Component Descriptions" %]
|
||||
The product <em>[% product FILTER html %]</em> does not exist
|
||||
|
||||
Reference in New Issue
Block a user