mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #7136 from open-sausages/pulls/4.0/fix-installer-create-admin
BUG Ensure that installer can create an initial admin account
This commit is contained in:
commit
0b09a510f4
@ -4,11 +4,10 @@ namespace SilverStripe\Dev\Install;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use SilverStripe\Control\Cookie;
|
use SilverStripe\Control\Cookie;
|
||||||
|
use SilverStripe\Control\HTTPApplication;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Control\HTTPRequestBuilder;
|
use SilverStripe\Control\HTTPRequestBuilder;
|
||||||
use SilverStripe\Control\Session;
|
|
||||||
use SilverStripe\Core\CoreKernel;
|
use SilverStripe\Core\CoreKernel;
|
||||||
use SilverStripe\Control\HTTPApplication;
|
|
||||||
use SilverStripe\Core\Kernel;
|
use SilverStripe\Core\Kernel;
|
||||||
use SilverStripe\Core\Startup\ParameterConfirmationToken;
|
use SilverStripe\Core\Startup\ParameterConfirmationToken;
|
||||||
use SilverStripe\ORM\DatabaseAdmin;
|
use SilverStripe\ORM\DatabaseAdmin;
|
||||||
@ -229,9 +228,15 @@ PHP
|
|||||||
|
|
||||||
// Create default administrator user and group in database
|
// Create default administrator user and group in database
|
||||||
// (not using Security::setDefaultAdmin())
|
// (not using Security::setDefaultAdmin())
|
||||||
$adminMember = DefaultAdminService::singleton()->findOrCreateDefaultAdmin();
|
$username = $config['admin']['username'];
|
||||||
$adminMember->Email = $config['admin']['username'];
|
$password = $config['admin']['password'];
|
||||||
$adminMember->Password = $config['admin']['password'];
|
$adminMember = DefaultAdminService::singleton()
|
||||||
|
->findOrCreateAdmin(
|
||||||
|
$username,
|
||||||
|
_t(DefaultAdminService::class . '.DefaultAdminFirstname', 'Default Admin')
|
||||||
|
);
|
||||||
|
$adminMember->Email = $username;
|
||||||
|
$adminMember->Password = $password;
|
||||||
$adminMember->PasswordEncryption = Security::config()->get('encryption_algorithm');
|
$adminMember->PasswordEncryption = Security::config()->get('encryption_algorithm');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -243,8 +248,8 @@ PHP
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->getSession()->set('username', $config['admin']['username']);
|
$request->getSession()->set('username', $username);
|
||||||
$request->getSession()->set('password', $config['admin']['password']);
|
$request->getSession()->set('password', $password);
|
||||||
$request->getSession()->save($request);
|
$request->getSession()->save($request);
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
@ -129,33 +129,53 @@ class DefaultAdminService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find or create ADMIN group
|
// Create admin with default admin username
|
||||||
Group::singleton()->requireDefaultRecords();
|
$admin = $this->findOrCreateAdmin(
|
||||||
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
static::getDefaultAdminUsername(),
|
||||||
|
_t(__CLASS__ . '.DefaultAdminFirstname', 'Default Admin')
|
||||||
|
);
|
||||||
|
|
||||||
if (!$adminGroup) {
|
$this->extend('afterFindOrCreateDefaultAdmin', $admin);
|
||||||
Group::singleton()->requireDefaultRecords();
|
|
||||||
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
return $admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find or create a Member with admin permissions
|
||||||
|
*
|
||||||
|
* @skipUpgrade
|
||||||
|
* @param string $email
|
||||||
|
* @param string $name
|
||||||
|
* @return Member
|
||||||
|
*/
|
||||||
|
public function findOrCreateAdmin($email, $name = null)
|
||||||
|
{
|
||||||
|
$this->extend('beforeFindOrCreateAdmin', $email, $name);
|
||||||
|
|
||||||
// Find member
|
// Find member
|
||||||
/** @skipUpgrade */
|
/** @var Member $admin */
|
||||||
$admin = Member::get()
|
$admin = Member::get()
|
||||||
->filter('Email', static::getDefaultAdminUsername())
|
->filter('Email', $email)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
// Find or create admin group
|
||||||
|
$adminGroup = $this->findOrCreateAdminGroup();
|
||||||
|
|
||||||
// If no admin is found, create one
|
// If no admin is found, create one
|
||||||
if (!$admin) {
|
if ($admin) {
|
||||||
// 'Password' is not set to avoid creating
|
$inGroup = $admin->inGroup($adminGroup);
|
||||||
// persistent logins in the database. See Security::setDefaultAdmin().
|
} else {
|
||||||
|
// Note: This user won't be able to login until a password is set
|
||||||
// Set 'Email' to identify this as the default admin
|
// Set 'Email' to identify this as the default admin
|
||||||
|
$inGroup = false;
|
||||||
$admin = Member::create();
|
$admin = Member::create();
|
||||||
$admin->FirstName = _t(__CLASS__ . '.DefaultAdminFirstname', 'Default Admin');
|
$admin->FirstName = $name ?: $email;
|
||||||
$admin->Email = static::getDefaultAdminUsername();
|
$admin->Email = $email;
|
||||||
$admin->write();
|
$admin->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure this user is in the admin group
|
// Ensure this user is in an admin group
|
||||||
if (!$admin->inGroup($adminGroup)) {
|
if (!$inGroup) {
|
||||||
// Add member to group instead of adding group to member
|
// Add member to group instead of adding group to member
|
||||||
// This bypasses the privilege escallation code in Member_GroupSet
|
// This bypasses the privilege escallation code in Member_GroupSet
|
||||||
$adminGroup
|
$adminGroup
|
||||||
@ -163,11 +183,41 @@ class DefaultAdminService
|
|||||||
->add($admin);
|
->add($admin);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->extend('afterFindOrCreateDefaultAdmin', $admin);
|
$this->extend('afterFindOrCreateAdmin', $admin);
|
||||||
|
|
||||||
return $admin;
|
return $admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure a Group exists with admin permission
|
||||||
|
*
|
||||||
|
* @return Group
|
||||||
|
*/
|
||||||
|
protected function findOrCreateAdminGroup()
|
||||||
|
{
|
||||||
|
// Check pre-existing group
|
||||||
|
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
||||||
|
if ($adminGroup) {
|
||||||
|
return $adminGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if default records create the group
|
||||||
|
Group::singleton()->requireDefaultRecords();
|
||||||
|
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
||||||
|
if ($adminGroup) {
|
||||||
|
return $adminGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new admin group directly
|
||||||
|
$adminGroup = Group::create();
|
||||||
|
$adminGroup->Code = 'administrators';
|
||||||
|
$adminGroup->Title = _t('SilverStripe\\Security\\Group.DefaultGroupTitleAdministrators', 'Administrators');
|
||||||
|
$adminGroup->Sort = 0;
|
||||||
|
$adminGroup->write();
|
||||||
|
Permission::grant($adminGroup->ID, 'ADMIN');
|
||||||
|
return $adminGroup;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the user is a default admin.
|
* Check if the user is a default admin.
|
||||||
* Returns false if there is no default admin.
|
* Returns false if there is no default admin.
|
||||||
|
@ -79,6 +79,20 @@ class SecurityDefaultAdminTest extends SapphireTest
|
|||||||
$this->assertNull($admin->Password);
|
$this->assertNull($admin->Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFindOrCreateAdmin()
|
||||||
|
{
|
||||||
|
$adminMembers = Permission::get_members_by_permission('ADMIN');
|
||||||
|
$this->assertEquals(0, $adminMembers->count());
|
||||||
|
|
||||||
|
$admin = DefaultAdminService::singleton()->findOrCreateAdmin('newadmin@example.com', 'Admin Name');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Member::class, $admin);
|
||||||
|
$this->assertTrue(Permission::checkMember($admin, 'ADMIN'));
|
||||||
|
$this->assertEquals('newadmin@example.com', $admin->Email);
|
||||||
|
$this->assertEquals('Admin Name', $admin->FirstName);
|
||||||
|
$this->assertNull($admin->Password);
|
||||||
|
}
|
||||||
|
|
||||||
public function testFindAnAdministratorWithoutDefaultAdmin()
|
public function testFindAnAdministratorWithoutDefaultAdmin()
|
||||||
{
|
{
|
||||||
// Clear default admin
|
// Clear default admin
|
||||||
|
Loading…
Reference in New Issue
Block a user