2017-06-13 11:04:43 +02:00
|
|
|
<?php
|
|
|
|
|
2017-06-15 04:20:12 +02:00
|
|
|
namespace SilverStripe\Security;
|
2017-06-13 11:04:43 +02:00
|
|
|
|
2017-06-15 04:20:12 +02:00
|
|
|
use BadMethodCallException;
|
|
|
|
use InvalidArgumentException;
|
2017-06-13 11:04:43 +02:00
|
|
|
use SilverStripe\Core\Config\Configurable;
|
|
|
|
use SilverStripe\Core\Extensible;
|
2017-06-15 04:20:12 +02:00
|
|
|
use SilverStripe\Core\Injector\Injectable;
|
2017-06-13 11:04:43 +02:00
|
|
|
|
2017-06-15 04:20:12 +02:00
|
|
|
/**
|
|
|
|
* Provides access to the default admin
|
|
|
|
*/
|
2017-06-13 11:04:43 +02:00
|
|
|
class DefaultAdminService
|
|
|
|
{
|
|
|
|
use Extensible;
|
|
|
|
use Configurable;
|
2017-06-15 04:20:12 +02:00
|
|
|
use Injectable;
|
2017-06-13 11:04:43 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var bool
|
|
|
|
*/
|
2017-06-15 04:20:12 +02:00
|
|
|
protected static $has_default_admin = false;
|
2017-06-13 11:04:43 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
2017-06-15 04:20:12 +02:00
|
|
|
protected static $default_username = null;
|
2017-06-13 11:04:43 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
2017-06-15 04:20:12 +02:00
|
|
|
protected static $default_password = null;
|
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
$this->constructExtensions();
|
|
|
|
}
|
2017-06-13 11:04:43 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the default admin credentials
|
|
|
|
*
|
|
|
|
* @param string $username
|
|
|
|
* @param string $password
|
|
|
|
*/
|
|
|
|
public static function setDefaultAdmin($username, $password)
|
|
|
|
{
|
|
|
|
// don't overwrite if already set
|
2017-06-15 04:20:12 +02:00
|
|
|
if (static::hasDefaultAdmin()) {
|
|
|
|
throw new BadMethodCallException(
|
|
|
|
"Default admin already exists. Use clearDefaultAdmin() first."
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (empty($username) || empty($password)) {
|
|
|
|
throw new InvalidArgumentException("Default admin username / password cannot be empty");
|
2017-06-13 11:04:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static::$default_username = $username;
|
|
|
|
static::$default_password = $password;
|
2017-06-15 04:20:12 +02:00
|
|
|
static::$has_default_admin = true;
|
2017-06-13 11:04:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string The default admin username
|
2017-06-15 04:20:12 +02:00
|
|
|
* @throws BadMethodCallException Throws exception if there is no default admin
|
2017-06-13 11:04:43 +02:00
|
|
|
*/
|
|
|
|
public static function getDefaultAdminUsername()
|
|
|
|
{
|
2017-06-15 04:20:12 +02:00
|
|
|
if (!static::hasDefaultAdmin()) {
|
|
|
|
throw new BadMethodCallException(
|
|
|
|
"No default admin configured. Please call hasDefaultAdmin() before getting default admin username"
|
|
|
|
);
|
|
|
|
}
|
2017-06-13 11:04:43 +02:00
|
|
|
return static::$default_username;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string The default admin password
|
2017-06-15 04:20:12 +02:00
|
|
|
* @throws BadMethodCallException Throws exception if there is no default admin
|
2017-06-13 11:04:43 +02:00
|
|
|
*/
|
|
|
|
public static function getDefaultAdminPassword()
|
|
|
|
{
|
2017-06-15 04:20:12 +02:00
|
|
|
if (!static::hasDefaultAdmin()) {
|
|
|
|
throw new BadMethodCallException(
|
|
|
|
"No default admin configured. Please call hasDefaultAdmin() before getting default admin password"
|
|
|
|
);
|
|
|
|
}
|
2017-06-13 11:04:43 +02:00
|
|
|
return static::$default_password;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if there is a default admin
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function hasDefaultAdmin()
|
|
|
|
{
|
|
|
|
return static::$has_default_admin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flush the default admin credentials
|
|
|
|
*/
|
|
|
|
public static function clearDefaultAdmin()
|
|
|
|
{
|
2017-06-15 04:20:12 +02:00
|
|
|
static::$has_default_admin = false;
|
|
|
|
static::$default_username = null;
|
|
|
|
static::$default_password = null;
|
2017-06-13 11:04:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-06-15 04:20:12 +02:00
|
|
|
* @return Member|null
|
2017-06-13 11:04:43 +02:00
|
|
|
*/
|
|
|
|
public function findOrCreateDefaultAdmin()
|
|
|
|
{
|
2017-06-15 04:20:12 +02:00
|
|
|
$this->extend('beforeFindOrCreateDefaultAdmin');
|
2017-06-13 11:04:43 +02:00
|
|
|
|
|
|
|
// Check if we have default admins
|
2017-06-15 04:20:12 +02:00
|
|
|
if (!static::hasDefaultAdmin()) {
|
2017-06-13 11:04:43 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find or create ADMIN group
|
|
|
|
Group::singleton()->requireDefaultRecords();
|
|
|
|
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
|
|
|
|
|
|
|
if (!$adminGroup) {
|
|
|
|
Group::singleton()->requireDefaultRecords();
|
|
|
|
$adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find member
|
|
|
|
/** @skipUpgrade */
|
|
|
|
$admin = Member::get()
|
|
|
|
->filter('Email', static::getDefaultAdminUsername())
|
|
|
|
->first();
|
|
|
|
// If no admin is found, create one
|
|
|
|
if (!$admin) {
|
|
|
|
// 'Password' is not set to avoid creating
|
|
|
|
// persistent logins in the database. See Security::setDefaultAdmin().
|
|
|
|
// Set 'Email' to identify this as the default admin
|
|
|
|
$admin = Member::create();
|
|
|
|
$admin->FirstName = _t(__CLASS__ . '.DefaultAdminFirstname', 'Default Admin');
|
|
|
|
$admin->Email = static::getDefaultAdminUsername();
|
|
|
|
$admin->write();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure this user is in the admin group
|
|
|
|
if (!$admin->inGroup($adminGroup)) {
|
|
|
|
// Add member to group instead of adding group to member
|
|
|
|
// This bypasses the privilege escallation code in Member_GroupSet
|
|
|
|
$adminGroup
|
|
|
|
->DirectMembers()
|
|
|
|
->add($admin);
|
|
|
|
}
|
|
|
|
|
2017-06-15 04:20:12 +02:00
|
|
|
$this->extend('afterFindOrCreateDefaultAdmin', $admin);
|
2017-06-13 11:04:43 +02:00
|
|
|
|
|
|
|
return $admin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-06-15 04:20:12 +02:00
|
|
|
* Check if the user is a default admin.
|
|
|
|
* Returns false if there is no default admin.
|
|
|
|
*
|
|
|
|
* @param string $username
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function isDefaultAdmin($username)
|
|
|
|
{
|
|
|
|
return static::hasDefaultAdmin()
|
|
|
|
&& $username
|
|
|
|
&& $username === static::getDefaultAdminUsername();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the user credentials match the default admin.
|
|
|
|
* Returns false if there is no default admin.
|
|
|
|
*
|
2017-06-13 11:04:43 +02:00
|
|
|
* @param string $username
|
|
|
|
* @param string $password
|
2017-06-15 04:20:12 +02:00
|
|
|
* @return bool
|
2017-06-13 11:04:43 +02:00
|
|
|
*/
|
2017-06-15 04:20:12 +02:00
|
|
|
public static function isDefaultAdminCredentials($username, $password)
|
2017-06-13 11:04:43 +02:00
|
|
|
{
|
2017-06-15 04:20:12 +02:00
|
|
|
return static::isDefaultAdmin($username)
|
|
|
|
&& $password
|
|
|
|
&& $password === static::getDefaultAdminPassword();
|
2017-06-13 11:04:43 +02:00
|
|
|
}
|
2017-06-15 04:20:12 +02:00
|
|
|
}
|