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 SilverStripe\Control\Cookie;
|
||||
use SilverStripe\Control\HTTPApplication;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\HTTPRequestBuilder;
|
||||
use SilverStripe\Control\Session;
|
||||
use SilverStripe\Core\CoreKernel;
|
||||
use SilverStripe\Control\HTTPApplication;
|
||||
use SilverStripe\Core\Kernel;
|
||||
use SilverStripe\Core\Startup\ParameterConfirmationToken;
|
||||
use SilverStripe\ORM\DatabaseAdmin;
|
||||
@ -229,9 +228,15 @@ PHP
|
||||
|
||||
// Create default administrator user and group in database
|
||||
// (not using Security::setDefaultAdmin())
|
||||
$adminMember = DefaultAdminService::singleton()->findOrCreateDefaultAdmin();
|
||||
$adminMember->Email = $config['admin']['username'];
|
||||
$adminMember->Password = $config['admin']['password'];
|
||||
$username = $config['admin']['username'];
|
||||
$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');
|
||||
|
||||
try {
|
||||
@ -243,8 +248,8 @@ PHP
|
||||
);
|
||||
}
|
||||
|
||||
$request->getSession()->set('username', $config['admin']['username']);
|
||||
$request->getSession()->set('password', $config['admin']['password']);
|
||||
$request->getSession()->set('username', $username);
|
||||
$request->getSession()->set('password', $password);
|
||||
$request->getSession()->save($request);
|
||||
}, true);
|
||||
|
||||
|
@ -129,33 +129,53 @@ class DefaultAdminService
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find or create ADMIN group
|
||||
Group::singleton()->requireDefaultRecords();
|
||||
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
||||
// Create admin with default admin username
|
||||
$admin = $this->findOrCreateAdmin(
|
||||
static::getDefaultAdminUsername(),
|
||||
_t(__CLASS__ . '.DefaultAdminFirstname', 'Default Admin')
|
||||
);
|
||||
|
||||
if (!$adminGroup) {
|
||||
Group::singleton()->requireDefaultRecords();
|
||||
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
||||
}
|
||||
$this->extend('afterFindOrCreateDefaultAdmin', $admin);
|
||||
|
||||
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
|
||||
/** @skipUpgrade */
|
||||
/** @var Member $admin */
|
||||
$admin = Member::get()
|
||||
->filter('Email', static::getDefaultAdminUsername())
|
||||
->filter('Email', $email)
|
||||
->first();
|
||||
|
||||
// Find or create admin group
|
||||
$adminGroup = $this->findOrCreateAdminGroup();
|
||||
|
||||
// If no admin is found, create one
|
||||
if (!$admin) {
|
||||
// 'Password' is not set to avoid creating
|
||||
// persistent logins in the database. See Security::setDefaultAdmin().
|
||||
if ($admin) {
|
||||
$inGroup = $admin->inGroup($adminGroup);
|
||||
} else {
|
||||
// Note: This user won't be able to login until a password is set
|
||||
// Set 'Email' to identify this as the default admin
|
||||
$inGroup = false;
|
||||
$admin = Member::create();
|
||||
$admin->FirstName = _t(__CLASS__ . '.DefaultAdminFirstname', 'Default Admin');
|
||||
$admin->Email = static::getDefaultAdminUsername();
|
||||
$admin->FirstName = $name ?: $email;
|
||||
$admin->Email = $email;
|
||||
$admin->write();
|
||||
}
|
||||
|
||||
// Ensure this user is in the admin group
|
||||
if (!$admin->inGroup($adminGroup)) {
|
||||
// Ensure this user is in an admin group
|
||||
if (!$inGroup) {
|
||||
// Add member to group instead of adding group to member
|
||||
// This bypasses the privilege escallation code in Member_GroupSet
|
||||
$adminGroup
|
||||
@ -163,11 +183,41 @@ class DefaultAdminService
|
||||
->add($admin);
|
||||
}
|
||||
|
||||
$this->extend('afterFindOrCreateDefaultAdmin', $admin);
|
||||
$this->extend('afterFindOrCreateAdmin', $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.
|
||||
* Returns false if there is no default admin.
|
||||
|
@ -79,6 +79,20 @@ class SecurityDefaultAdminTest extends SapphireTest
|
||||
$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()
|
||||
{
|
||||
// Clear default admin
|
||||
|
Loading…
Reference in New Issue
Block a user