public function run($request) { $algo = Security::get_password_encryption_algorithm(); if ($algo == 'none') { $this->debugMessage('Password encryption disabled'); return; } // Are there members with a clear text password? $members = DataObject::get("Member", "\"PasswordEncryption\" = 'none' AND \"Password\" IS NOT NULL"); if (!$members) { $this->debugMessage('No passwords to encrypt'); return; } // Encrypt the passwords... $this->debugMessage('Encrypting all passwords'); $this->debugMessage(sprintf('The passwords will be encrypted using the %s algorithm', $algo)); foreach ($members as $member) { // Force the update of the member record, as new passwords get // automatically encrypted according to the settings, this will do all // the work for us $member->PasswordEncryption = $algo; $member->forceChange(); $member->write(); $this->debugMessage(sprintf('Encrypted credentials for member #%d;', $member->ID)); } }
public function testCleartextPasswordsAreHashedWithDefaultAlgo() { $loader = new MemberCsvBulkLoader(); $results = $loader->load($this->getCurrentRelativePath() . '/MemberCsvBulkLoaderTest_cleartextpws.csv'); $member = $results->Created()->First(); $memberID = $member->ID; DataObject::flush_and_destroy_cache(); $member = DataObject::get_by_id('Member', $memberID); // TODO Direct getter doesn't work, wtf! $this->assertEquals(Security::get_password_encryption_algorithm(), $member->getField('PasswordEncryption')); $result = $member->checkPassword('mypassword'); $this->assertTrue($result->valid()); }
function testDefaultPasswordEncryptionDoesntChangeExistingMembers() { $member = new Member(); $member->Password = '******'; $member->PasswordEncryption = 'sha1_v2.4'; $member->write(); $origAlgo = Security::get_password_encryption_algorithm(); Security::set_password_encryption_algorithm('none'); $member->Password = '******'; $member->write(); $this->assertEquals($member->PasswordEncryption, 'sha1_v2.4'); $result = $member->checkPassword('mynewpassword'); $this->assertTrue($result->valid()); Security::set_password_encryption_algorithm($origAlgo); }
/** * Event handler called before writing to the database. */ function onBeforeWrite() { if($this->SetPassword) $this->Password = $this->SetPassword; // If a member with the same "unique identifier" already exists with a different ID, don't allow merging. // Note: This does not a full replacement for safeguards in the controller layer (e.g. in a registration form), // but rather a last line of defense against data inconsistencies. $identifierField = self::$unique_identifier_field; if($this->$identifierField) { // Note: Same logic as Member_Validator class $idClause = ($this->ID) ? sprintf(" AND \"Member\".\"ID\" <> %d", (int)$this->ID) : ''; $existingRecord = DataObject::get_one( 'Member', sprintf( "\"%s\" = '%s' %s", $identifierField, Convert::raw2sql($this->$identifierField), $idClause ) ); if($existingRecord) { throw new ValidationException(new ValidationResult(false, sprintf( _t( 'Member.ValidationIdentifierFailed', 'Can\'t overwrite existing member #%d with identical identifier (%s = %s))', 'The values in brackets show a fieldname mapped to a value, usually denoting an existing email address' ), $existingRecord->ID, $identifierField, $this->$identifierField ))); } } // We don't send emails out on dev/tests sites to prevent accidentally spamming users. // However, if TestMailer is in use this isn't a risk. if( (Director::isLive() || Email::mailer() instanceof TestMailer) && $this->isChanged('Password') && $this->record['Password'] && Member::$notify_password_change ) { $this->sendInfo('changePassword'); } // The test on $this->ID is used for when records are initially created. // Note that this only works with cleartext passwords, as we can't rehash // existing passwords. if((!$this->ID && $this->Password) || $this->isChanged('Password')) { // Password was changed: encrypt the password according the settings $encryption_details = Security::encrypt_password( $this->Password, // this is assumed to be cleartext $this->Salt, ($this->PasswordEncryption) ? $this->PasswordEncryption : Security::get_password_encryption_algorithm(), $this ); // Overwrite the Password property with the hashed value $this->Password = $encryption_details['password']; $this->Salt = $encryption_details['salt']; $this->PasswordEncryption = $encryption_details['algorithm']; // If we haven't manually set a password expiry if(!$this->isChanged('PasswordExpiry')) { // then set it for us if(self::$password_expiry_days) { $this->PasswordExpiry = date('Y-m-d', time() + 86400 * self::$password_expiry_days); } else { $this->PasswordExpiry = null; } } } // save locale if(!$this->Locale) { $this->Locale = i18n::get_locale(); } parent::onBeforeWrite(); }
function install($config) { ?> <html> <head> <title>Installing SilverStripe...</title> <link rel="stylesheet" type="text/css" href="<?php echo FRAMEWORK_NAME; ?>/dev/install/css/install.css" /> <script src="<?php echo FRAMEWORK_NAME; ?>/thirdparty/jquery/jquery.js"></script> </head> <body> <div class="install-header"> <div class="inner"> <div class="brand"> <span class="logo"></span> <h1>SilverStripe</h1> </div> </div> </div> <div id="Navigation"> </div> <div class="clear"><!-- --></div> <div class="main"> <div class="inner"> <h2>Installing SilverStripe...</h2> <p>I am now running through the installation steps (this should take about 30 seconds)</p> <p>If you receive a fatal error, refresh this page to continue the installation</p> <ul> <?php $webserver = $this->findWebserver(); $isIIS = $this->isIIS(); $isApache = $this->isApache(); flush(); if(isset($config['stats'])) { if(file_exists(FRAMEWORK_NAME . '/silverstripe_version')) { $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version'); } else { $silverstripe_version = "unknown"; } $phpVersion = urlencode(phpversion()); $encWebserver = urlencode($webserver); $dbType = $config['db']['type']; // Try to determine the database version from the helper $databaseVersion = $config['db']['type']; $helper = $this->getDatabaseConfigurationHelper($dbType); if($helper && method_exists($helper, 'getDatabaseVersion')) { $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($config['db'][$dbType])); } $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$encWebserver"; if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) { $url .= '&ID=' . $_SESSION['StatsID']; } @$_SESSION['StatsID'] = file_get_contents($url); } if(file_exists('mysite/_config.php')) { // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them $fh = fopen('mysite/_config.php', 'wb'); fclose($fh); } // Escape user input for safe insertion into PHP file $theme = isset($_POST['template']) ? addcslashes($_POST['template'], "\'") : 'simple'; $locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\'") : 'en_US'; $type = addcslashes($config['db']['type'], "\'"); $dbConfig = $config['db'][$type]; $dbConfig = array_map(create_function('$v', 'return addcslashes($v, "\\\'");'), $dbConfig); if(!isset($dbConfig['path'])) $dbConfig['path'] = ''; if(!$dbConfig) { echo "<p style=\"color: red\">Bad config submitted</p><pre>"; print_r($config); echo "</pre>"; die(); } // Write the config file global $usingEnv; if($usingEnv) { $this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php..."); $this->writeToFile("mysite/_config.php", <<<PHP <?php global \$project; \$project = 'mysite'; global \$database; \$database = '{$dbConfig['database']}'; require_once('conf/ConfigureFromEnv.php'); MySQLDatabase::set_connection_charset('utf8'); // Set the current theme. More themes can be downloaded from // http://www.silverstripe.org/themes/ SSViewer::set_theme('$theme'); // Set the site locale i18n::set_locale('$locale'); // Enable nested URLs for this site (e.g. page/sub-page/) if (class_exists('SiteTree')) SiteTree::enable_nested_urls(); PHP ); } else { $this->statusMessage("Setting up 'mysite/_config.php'..."); $escapedPassword = addslashes($dbConfig['password']); $this->writeToFile("mysite/_config.php", <<<PHP <?php global \$project; \$project = 'mysite'; global \$databaseConfig; \$databaseConfig = array( "type" => '{$type}', "server" => '{$dbConfig['server']}', "username" => '{$dbConfig['username']}', "password" => '{$escapedPassword}', "database" => '{$dbConfig['database']}', "path" => '{$dbConfig['path']}', ); MySQLDatabase::set_connection_charset('utf8'); // Set the current theme. More themes can be downloaded from // http://www.silverstripe.org/themes/ SSViewer::set_theme('$theme'); // Set the site locale i18n::set_locale('$locale'); // Enable nested URLs for this site (e.g. page/sub-page/) if (class_exists('SiteTree')) SiteTree::enable_nested_urls(); PHP ); } if (!$this->checkModuleExists('cms')) { $this->writeToFile("mysite/code/RootURLController.php", <<<PHP <?php class RootURLController extends Controller { function index() { echo "<html>Your site is now set up. Start adding controllers to mysite to get started.</html>"; } } PHP ); } // Write the appropriate web server configuration file for rewriting support if($this->hasRewritingCapability()) { if($isApache) { $this->statusMessage("Setting up '.htaccess' file..."); $this->createHtaccess(); } elseif($isIIS) { $this->statusMessage("Setting up 'web.config' file..."); $this->createWebConfig(); } } // Load the SilverStripe runtime $_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/' . FRAMEWORK_NAME . '/main.php'; chdir(FRAMEWORK_NAME); // Rebuild the manifest $_GET['flush'] = true; // Show errors as if you're in development mode $_SESSION['isDev'] = 1; $this->statusMessage("Building database schema..."); require_once 'core/Core.php'; // Build database $con = new Controller(); $con->pushCurrent(); global $databaseConfig; DB::connect($databaseConfig); $dbAdmin = new DatabaseAdmin(); $dbAdmin->init(); $dbAdmin->doBuild(true); // Create default administrator user and group in database // (not using Security::setDefaultAdmin()) $adminMember = Security::findAnAdministrator(); $adminMember->Email = $config['admin']['username']; $adminMember->Password = $config['admin']['password']; $adminMember->PasswordEncryption = Security::get_password_encryption_algorithm(); try { $this->statusMessage('Creating default CMS admin account...'); $adminMember->write(); } catch(Exception $e) { $this->statusMessage( sprintf('Warning: Default CMS admin account could not be created (error: %s)', $e->getMessage()) ); } // Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266) // show a warning if there was a problem doing so try { $this->statusMessage('Creating initial filesystem assets...'); Filesystem::sync(); } catch(Exception $e) { $this->statusMessage( sprintf('Warning: Creating initial filesystem assets failed (error: %s)', $e->getMessage()) ); } $_SESSION['username'] = $config['admin']['username']; $_SESSION['password'] = $config['admin']['password']; if(!$this->errors) { if(isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) { $this->statusMessage("Checking that friendly URLs work..."); $this->checkRewrite(); } else { $destinationURL = 'index.php/' . ($this->checkModuleExists('cms') ? 'home/successfullyinstalled?flush=1' : '?flush=1'); echo <<<HTML <li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li> <script> setTimeout(function() { window.location = "$destinationURL"; }, 2000); </script> <noscript> <li><a href="$destinationURL">Click here to access your site.</li> </noscript> HTML; } } return $this->errors; }
function install($config) { if (isset($_SERVER['HTTP_HOST'])) { ?> <html> <head> <title>Installing SilverStripe...</title> <link rel="stylesheet" type="text/css" href="themes/blackcandy/css/layout.css" /> <link rel="stylesheet" type="text/css" href="themes/blackcandy/css/typography.css" /> <link rel="stylesheet" type="text/css" href="themes/blackcandy/css/form.css" /> <link rel="stylesheet" type="text/css" href="sapphire/dev/install/install.css" /> <script src="sapphire/thirdparty/jquery/jquery.js"></script> </head> <body> <div id="BgContainer"> <div id="Container"> <div id="Header"> <h1>SilverStripe CMS Installation</h1> </div> <div id="Navigation"> </div> <div class="clear"><!-- --></div> <div id="Layout"> <div class="typography"> <h1>Installing SilverStripe...</h1> <p>I am now running through the installation steps (this should take about 30 seconds)</p> <p>If you receive a fatal error, refresh this page to continue the installation</p> <ul> <?php } else { echo "SILVERSTRIPE COMMAND-LINE INSTALLATION\n\n"; } $webserver = $this->findWebserver(); $isIIS = $this->isIIS(); $isApache = $this->isApache(); flush(); if (isset($config['stats'])) { if (file_exists('sapphire/silverstripe_version')) { $sapphireVersionFile = file_get_contents('sapphire/silverstripe_version'); if (strstr($sapphireVersionFile, "/sapphire/trunk")) { $silverstripe_version = "trunk"; } else { preg_match("/sapphire\\/(?:(?:branches)|(?:tags))(?:\\/rc)?\\/([A-Za-z0-9._-]+)\\/silverstripe_version/", $sapphireVersionFile, $matches); $silverstripe_version = $matches[1]; } } else { $silverstripe_version = "unknown"; } $phpVersion = urlencode(phpversion()); $encWebserver = urlencode($webserver); $dbType = $config['db']['type']; // Try to determine the database version from the helper $databaseVersion = $config['db']['type']; $helper = $this->getDatabaseConfigurationHelper($dbType); if ($helper && method_exists($helper, 'getDatabaseVersion')) { $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($config['db'][$dbType])); } $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe={$silverstripe_version}&PHP={$phpVersion}&Database={$databaseVersion}&WebServer={$encWebserver}"; if (isset($_SESSION['StatsID']) && $_SESSION['StatsID']) { $url .= '&ID=' . $_SESSION['StatsID']; } @($_SESSION['StatsID'] = file_get_contents($url)); } if (file_exists('mysite/_config.php')) { // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them $fh = fopen('mysite/_config.php', 'wb'); fclose($fh); } $theme = isset($_POST['template']) ? $_POST['template'] : 'blackcandy'; $locale = isset($_POST['locale']) ? $_POST['locale'] : 'en_US'; $type = $config['db']['type']; $dbConfig = $config['db'][$type]; if (!$dbConfig) { echo "<p style=\"color: red\">Bad config submitted</p><pre>"; print_r($config); echo "</pre>"; die; } // Write the config file global $usingEnv; if ($usingEnv) { $this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php..."); $this->writeToFile("mysite/_config.php", <<<PHP <?php global \$project; \$project = 'mysite'; global \$database; \$database = '{$dbConfig['database']}'; require_once('conf/ConfigureFromEnv.php'); MySQLDatabase::set_connection_charset('utf8'); // This line set's the current theme. More themes can be // downloaded from http://www.silverstripe.org/themes/ SSViewer::set_theme('{$theme}'); // Set the site locale i18n::set_locale('{$locale}'); // enable nested URLs for this site (e.g. page/sub-page/) SiteTree::enable_nested_urls(); PHP ); } else { $this->statusMessage("Setting up 'mysite/_config.php'..."); $escapedPassword = addslashes($dbConfig['password']); $this->writeToFile("mysite/_config.php", <<<PHP <?php global \$project; \$project = 'mysite'; global \$databaseConfig; \$databaseConfig = array( \t"type" => '{$type}', \t"server" => '{$dbConfig['server']}', \t"username" => '{$dbConfig['username']}', \t"password" => '{$escapedPassword}', \t"database" => '{$dbConfig['database']}', \t"path" => '{$dbConfig['path']}', ); // Sites running on the following servers will be // run in development mode. See // http://doc.silverstripe.org/doku.php?id=configuration // for a description of what dev mode does. Director::set_dev_servers(array( \t'localhost', \t'127.0.0.1' )); MySQLDatabase::set_connection_charset('utf8'); // This line set's the current theme. More themes can be // downloaded from http://www.silverstripe.org/themes/ SSViewer::set_theme('{$theme}'); // Set the site locale i18n::set_locale('{$locale}'); // enable nested URLs for this site (e.g. page/sub-page/) SiteTree::enable_nested_urls(); PHP ); } // Write the appropriate web server configuration file for rewriting support if ($this->hasRewritingCapability()) { if ($isApache) { $this->statusMessage("Setting up '.htaccess' file..."); $this->createHtaccess(); } elseif ($isIIS) { $this->statusMessage("Setting up 'web.config' file..."); $this->createWebConfig(); } } // Load the sapphire runtime $_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/sapphire/main.php'; chdir('sapphire'); // Rebuild the manifest $_GET['flush'] = true; // Show errors as if you're in development mode $_SESSION['isDev'] = 1; require_once 'core/Core.php'; $this->statusMessage("Building database schema..."); // Build database $con = new Controller(); $con->pushCurrent(); global $databaseConfig; DB::connect($databaseConfig); $dbAdmin = new DatabaseAdmin(); $dbAdmin->init(); $dbAdmin->doBuild(true); // Create default administrator user and group in database // (not using Security::setDefaultAdmin()) $adminMember = Security::findAnAdministrator(); $adminMember->Email = $config['admin']['username']; $adminMember->Password = $config['admin']['password']; $adminMember->PasswordEncryption = Security::get_password_encryption_algorithm(); // @todo Exception thrown if database with admin already exists with same Email try { $adminMember->write(); } catch (Exception $e) { } // Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266) Filesystem::sync(); $_SESSION['username'] = $config['admin']['username']; $_SESSION['password'] = $config['admin']['password']; if (!$this->errors) { if (isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) { $this->statusMessage("Checking that friendly URLs work..."); $this->checkRewrite(); } else { echo <<<HTML \t\t\t\t<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li> \t\t\t\t<script> \t\t\t\t\tsetTimeout(function() { \t\t\t\t\t\twindow.location = "index.php/home/successfullyinstalled?flush=1"; \t\t\t\t\t}, 2000); \t\t\t\t</script> \t\t\t\t<noscript> \t\t\t\t<li><a href="index.php/home/successfullyinstalled?flush=1">Click here to access your site.</li> \t\t\t\t</noscript> HTML; } } return $this->errors; }