Example #1
0
 /**
  * Generate a random string of characters.
  *
  * @param int $length The length of the string to generate.
  * @param string $characters The allowed characters in the string. See {@link betterRandomString()} for character options.
  * @return string Returns a random string of characters.
  */
 function randomString($length, $characters = 'A0')
 {
     return betterRandomString($length, $characters);
 }
Example #2
0
 /**
  * Send forgot password email.
  *
  * @param string $Email
  * @return bool
  */
 public function passwordRequest($Email)
 {
     if (!$Email) {
         return false;
     }
     $Users = $this->getWhere(['Email' => $Email])->resultObject();
     if (count($Users) == 0) {
         // Check for the username.
         $Users = $this->getWhere(['Name' => $Email])->resultObject();
     }
     $this->EventArguments['Users'] =& $Users;
     $this->EventArguments['Email'] = $Email;
     $this->fireEvent('BeforePasswordRequest');
     if (count($Users) == 0) {
         $this->Validation->addValidationResult('Name', "Couldn't find an account associated with that email/username.");
         return false;
     }
     $NoEmail = true;
     foreach ($Users as $User) {
         if (!$User->Email) {
             continue;
         }
         $Email = new Gdn_Email();
         // Instantiate in loop to clear previous settings
         $PasswordResetKey = betterRandomString(20, 'Aa0');
         $PasswordResetExpires = strtotime('+1 hour');
         $this->saveAttribute($User->UserID, 'PasswordResetKey', $PasswordResetKey);
         $this->saveAttribute($User->UserID, 'PasswordResetExpires', $PasswordResetExpires);
         $AppTitle = c('Garden.Title');
         $Email->subject('[' . $AppTitle . '] ' . t('Reset Your Password'));
         $Email->to($User->Email);
         $emailTemplate = $Email->getEmailTemplate()->setTitle(t('Reset Your Password'))->setMessage(sprintf(t('We\'ve received a request to change your password.'), $AppTitle))->setButton(externalUrl('/entry/passwordreset/' . $User->UserID . '/' . $PasswordResetKey), t('Change My Password'));
         $Email->setEmailTemplate($emailTemplate);
         try {
             $Email->send();
         } catch (Exception $e) {
             if (debug()) {
                 throw $e;
             }
         }
         $NoEmail = false;
     }
     if ($NoEmail) {
         $this->Validation->addValidationResult('Name', 'There is no email address associated with that account.');
         return false;
     }
     return true;
 }
 /**
  * Allows the configuration of basic setup information in Garden. This
  * should not be functional after the application has been set up.
  *
  * @since 2.0.0
  * @access public
  * @param string $RedirectUrl Where to send user afterward.
  */
 private function configure($RedirectUrl = '')
 {
     // Create a model to save configuration settings
     $Validation = new Gdn_Validation();
     $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
     $ConfigurationModel->setField(array('Garden.Locale', 'Garden.Title', 'Garden.WebRoot', 'Garden.Cookie.Salt', 'Garden.Cookie.Domain', 'Database.Name', 'Database.Host', 'Database.User', 'Database.Password', 'Garden.Registration.ConfirmEmail', 'Garden.Email.SupportName'));
     // Set the models on the forms.
     $this->Form->setModel($ConfigurationModel);
     // If seeing the form for the first time...
     if (!$this->Form->isPostback()) {
         // Force the webroot using our best guesstimates
         $ConfigurationModel->Data['Database.Host'] = 'localhost';
         $this->Form->setData($ConfigurationModel->Data);
     } else {
         // Define some validation rules for the fields being saved
         $ConfigurationModel->Validation->applyRule('Database.Name', 'Required', 'You must specify the name of the database in which you want to set up Vanilla.');
         // Let's make some user-friendly custom errors for database problems
         $DatabaseHost = $this->Form->getFormValue('Database.Host', '~~Invalid~~');
         $DatabaseName = $this->Form->getFormValue('Database.Name', '~~Invalid~~');
         $DatabaseUser = $this->Form->getFormValue('Database.User', '~~Invalid~~');
         $DatabasePassword = $this->Form->getFormValue('Database.Password', '~~Invalid~~');
         $ConnectionString = GetConnectionString($DatabaseName, $DatabaseHost);
         try {
             $Connection = new PDO($ConnectionString, $DatabaseUser, $DatabasePassword);
         } catch (PDOException $Exception) {
             switch ($Exception->getCode()) {
                 case 1044:
                     $this->Form->addError(t('The database user you specified does not have permission to access the database. Have you created the database yet? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage()));
                     break;
                 case 1045:
                     $this->Form->addError(t('Failed to connect to the database with the username and password you entered. Did you mistype them? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage()));
                     break;
                 case 1049:
                     $this->Form->addError(t('It appears as though the database you specified does not exist yet. Have you created it yet? Did you mistype the name? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage()));
                     break;
                 case 2005:
                     $this->Form->addError(t("Are you sure you've entered the correct database host name? Maybe you mistyped it? The database reported: <code>%s</code>"), strip_tags($Exception->getMessage()));
                     break;
                 default:
                     $this->Form->addError(sprintf(t('ValidateConnection'), strip_tags($Exception->getMessage())));
                     break;
             }
         }
         $ConfigurationModel->Validation->applyRule('Garden.Title', 'Required');
         $ConfigurationFormValues = $this->Form->formValues();
         if ($ConfigurationModel->validate($ConfigurationFormValues) !== true || $this->Form->errorCount() > 0) {
             // Apply the validation results to the form(s)
             $this->Form->setValidationResults($ConfigurationModel->validationResults());
         } else {
             $Host = array_shift(explode(':', Gdn::request()->requestHost()));
             $Domain = Gdn::request()->domain();
             // Set up cookies now so that the user can be signed in.
             $ExistingSalt = c('Garden.Cookie.Salt', false);
             $ConfigurationFormValues['Garden.Cookie.Salt'] = $ExistingSalt ? $ExistingSalt : betterRandomString(16, 'Aa0');
             $ConfigurationFormValues['Garden.Cookie.Domain'] = '';
             // Don't set this to anything by default. # Tim - 2010-06-23
             // Additional default setup values.
             $ConfigurationFormValues['Garden.Registration.ConfirmEmail'] = true;
             $ConfigurationFormValues['Garden.Email.SupportName'] = $ConfigurationFormValues['Garden.Title'];
             $ConfigurationModel->save($ConfigurationFormValues, true);
             // If changing locale, redefine locale sources:
             $NewLocale = 'en-CA';
             // $this->Form->getFormValue('Garden.Locale', false);
             if ($NewLocale !== false && Gdn::config('Garden.Locale') != $NewLocale) {
                 $Locale = Gdn::locale();
                 $Locale->set($NewLocale);
             }
             // Install db structure & basic data.
             $Database = Gdn::database();
             $Database->init();
             $Drop = false;
             $Explicit = false;
             try {
                 include PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'structure.php';
             } catch (Exception $ex) {
                 $this->Form->addError($ex);
             }
             if ($this->Form->errorCount() > 0) {
                 return false;
             }
             // Create the administrative user
             $UserModel = Gdn::userModel();
             $UserModel->defineSchema();
             $UsernameError = t('UsernameError', 'Username can only contain letters, numbers, underscores, and must be between 3 and 20 characters long.');
             $UserModel->Validation->applyRule('Name', 'Username', $UsernameError);
             $UserModel->Validation->applyRule('Name', 'Required', t('You must specify an admin username.'));
             $UserModel->Validation->applyRule('Password', 'Required', t('You must specify an admin password.'));
             $UserModel->Validation->applyRule('Password', 'Match');
             $UserModel->Validation->applyRule('Email', 'Email');
             if (!($AdminUserID = $UserModel->SaveAdminUser($ConfigurationFormValues))) {
                 $this->Form->setValidationResults($UserModel->validationResults());
             } else {
                 // The user has been created successfully, so sign in now.
                 saveToConfig('Garden.Installed', true, array('Save' => false));
                 Gdn::session()->start($AdminUserID, true);
                 saveToConfig('Garden.Installed', false, array('Save' => false));
             }
             if ($this->Form->errorCount() > 0) {
                 return false;
             }
             // Assign some extra settings to the configuration file if everything succeeded.
             $ApplicationInfo = array();
             include CombinePaths(array(PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'about.php'));
             // Detect Internet connection for CDNs
             $Disconnected = !(bool) @fsockopen('ajax.googleapis.com', 80);
             saveToConfig(array('Garden.Version' => val('Version', val('Dashboard', $ApplicationInfo, array()), 'Undefined'), 'Garden.Cdns.Disable' => $Disconnected, 'Garden.CanProcessImages' => function_exists('gd_info'), 'EnabledPlugins.GettingStarted' => 'GettingStarted', 'EnabledPlugins.HtmLawed' => 'HtmLawed'));
         }
     }
     return $this->Form->errorCount() == 0 ? true : false;
 }
Example #4
0
 /**
  * Set the TransientKey attribute on a user.
  *
  * @param $UserID
  * @param string $ExplicitKey
  * @return string
  */
 public function setTransientKey($UserID, $ExplicitKey = '')
 {
     $Key = $ExplicitKey == '' ? betterRandomString(16, 'Aa0') : $ExplicitKey;
     $this->saveAttribute($UserID, 'TransientKey', $Key);
     return $Key;
 }
Example #5
0
 /**
  * Create a user.
  *
  * @since 2.0.0
  * @access public
  */
 public function add()
 {
     $this->permission('Garden.Users.Add');
     // Page setup
     $this->addJsFile('user.js');
     $this->title(t('Add User'));
     $this->setHighlightRoute('dashboard/user');
     $RoleModel = new RoleModel();
     $AllRoles = $RoleModel->getArray();
     $RoleData = $RoleModel->GetAssignable();
     // By default, people with access here can freely assign all roles
     $this->RoleData = $RoleData;
     $UserModel = new UserModel();
     $this->User = false;
     // Set the model on the form.
     $this->Form->setModel($UserModel);
     try {
         // These are all the 'effective' roles for this add action. This list can
         // be trimmed down from the real list to allow subsets of roles to be edited.
         $this->EventArguments['RoleData'] =& $this->RoleData;
         $this->fireEvent("BeforeUserAdd");
         if ($this->Form->authenticatedPostBack(true)) {
             // These are the new roles the creating user wishes to apply to the target
             // user, adjusted for his ability to affect those roles
             $RequestedRoles = $this->Form->getFormValue('RoleID');
             if (!is_array($RequestedRoles)) {
                 $RequestedRoles = array();
             }
             $RequestedRoles = array_flip($RequestedRoles);
             $UserNewRoles = array_intersect_key($this->RoleData, $RequestedRoles);
             // Put the data back into the forum object as if the user had submitted
             // this themselves
             $this->Form->setFormValue('RoleID', array_keys($UserNewRoles));
             $noPassword = (bool) $this->Form->getFormValue('NoPassword');
             if ($noPassword) {
                 $this->Form->setFormValue('Password', betterRandomString(15, 'Aa0'));
                 $this->Form->setFormValue('HashMethod', 'Random');
             }
             $NewUserID = $this->Form->save(array('SaveRoles' => true, 'NoConfirmEmail' => true));
             if ($NewUserID !== false) {
                 $this->setData('UserID', $NewUserID);
                 if ($noPassword) {
                     $password = T('No password');
                 } else {
                     $password = $this->Form->getValue('Password', '');
                 }
                 $UserModel->sendWelcomeEmail($NewUserID, $password, 'Add');
                 $this->informMessage(t('The user has been created successfully'));
                 $this->RedirectUrl = url('dashboard/user');
             } elseif ($noPassword) {
                 $this->Form->setFormValue('Password', '');
                 $this->Form->setFormValue('HashMethod', '');
             }
             $this->UserRoleData = $UserNewRoles;
         } else {
             // Set the default roles.
             $this->UserRoleData = RoleModel::getDefaultRoles(RoleModel::TYPE_MEMBER);
         }
     } catch (Exception $Ex) {
         $this->Form->addError($Ex);
     }
     $this->render();
 }
Example #6
0
 /**
  * Used by $this->Stash() to create & manage sessions for users & guests.
  *
  * This is a stop-gap solution until full session management for users &
  * guests can be imlemented.
  */
 private function _getStashSession($ValueToStash)
 {
     $CookieName = c('Garden.Cookie.Name', 'Vanilla');
     $Name = $CookieName . '-sid';
     // Grab the entire session record
     $SessionID = val($Name, $_COOKIE, '');
     // If there is no session, and no value for saving, return;
     if ($SessionID == '' && $ValueToStash == '') {
         return false;
     }
     $Session = Gdn::SQL()->select()->from('Session')->where('SessionID', $SessionID)->get()->firstRow();
     if (!$Session) {
         $SessionID = betterRandomString(32);
         $TransientKey = substr(md5(mt_rand()), 0, 11) . '!';
         // Save the session information to the database.
         Gdn::SQL()->insert('Session', array('SessionID' => $SessionID, 'UserID' => Gdn::session()->UserID, 'TransientKey' => $TransientKey, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime()));
         Trace("Inserting session stash {$SessionID}");
         $Session = Gdn::SQL()->select()->from('Session')->where('SessionID', $SessionID)->get()->firstRow();
         // Save a session cookie
         $Path = c('Garden.Cookie.Path', '/');
         $Domain = c('Garden.Cookie.Domain', '');
         $Expire = 0;
         // If the domain being set is completely incompatible with the current domain then make the domain work.
         $CurrentHost = Gdn::request()->host();
         if (!stringEndsWith($CurrentHost, trim($Domain, '.'))) {
             $Domain = '';
         }
         safeCookie($Name, $SessionID, $Expire, $Path, $Domain);
         $_COOKIE[$Name] = $SessionID;
     }
     $Session->Attributes = @unserialize($Session->Attributes);
     if (!$Session->Attributes) {
         $Session->Attributes = array();
     }
     return $Session;
 }
 /**
  * Get server list with mapping keys.
  */
 public function shardMap()
 {
     static $servers = null;
     if (is_null($servers)) {
         $serverList = $this->servers();
         $numShards = count($serverList);
         $servers = array();
         if ($this->canAutoShard()) {
             // Use getServerByKey to determine server keys
             // Here we loop until we have found keys for all the servers
             $i = $numShards * 10;
             do {
                 $i--;
                 // limited iterations
                 $shardKey = betterRandomString(6, 'a0');
                 $shardServer = $this->memcache->getServerByKey($shardKey);
                 $shardServerName = $shardServer['host'];
                 if ($shardServerName) {
                     $servers[$shardServerName] = $shardKey;
                 }
             } while ($i > 0 && count($servers) < $numShards);
         }
         if (!count($servers)) {
             // Use random server keys and hope for the best
             foreach ($serverList as $server) {
                 $serverName = $server['host'];
                 $servers[$serverName] = betterRandomString(6, 'a0');
             }
         }
     }
     return $servers;
 }
 /**
  *
  *
  * @throws Exception
  */
 public function ping()
 {
     $start = microtime(true);
     $this->setData('pong', true);
     $this->MasterView = 'empty';
     $this->CssClass = 'Home';
     $valid = true;
     // Test the cache.
     if (Gdn::cache()->activeEnabled()) {
         $k = betterRandomString(20);
         Gdn::cache()->store($k, 1);
         Gdn::cache()->increment($k, 1);
         $v = Gdn::cache()->get($k);
         if ($v !== 2) {
             $valid = false;
             $this->setData('cache', false);
         } else {
             $this->setData('cache', true);
         }
     } else {
         $this->setData('cache', 'disabled');
     }
     // Test the db.
     try {
         $users = Gdn::sql()->get('User', 'UserID', 'asc', 1);
         $this->setData('database', true);
     } catch (Exception $ex) {
         $this->setData('database', false);
         $valid = false;
     }
     $this->EventArguments['Valid'] =& $valid;
     $this->fireEvent('Ping');
     if (!$valid) {
         $this->statusCode(500);
     }
     $time = microtime(true) - $start;
     $this->setData('time', Gdn_Format::timespan($time));
     $this->setData('time_s', $time);
     $this->setData('valid', $valid);
     $this->title('Ping');
     $this->render();
 }
Example #9
0
 /**
  * Used by $this->stash() to create & manage sessions for users & guests.
  *
  * This is a stop-gap solution until full session management for users &
  * guests can be implemented.
  *
  * @param Gdn_SQLDriver $sql          Local clone of the sql driver.
  * @param string        $valueToStash The value of the stash to set.
  *
  * @return bool|Gdn_DataSet Current session.
  */
 private function getStashSession($sql, $valueToStash)
 {
     $cookieName = c('Garden.Cookie.Name', 'Vanilla');
     $name = $cookieName . '-sid';
     // Grab the entire session record.
     $sessionID = val($name, $_COOKIE, '');
     // If there is no session, and no value for saving, return.
     if ($sessionID == '' && $valueToStash == '') {
         return false;
     }
     $session = $sql->select()->from('Session')->where('SessionID', $sessionID)->get()->firstRow();
     if (!$session) {
         $sessionID = betterRandomString(32);
         $transientKey = substr(md5(mt_rand()), 0, 11) . '!';
         // Save the session information to the database.
         $sql->insert('Session', ['SessionID' => $sessionID, 'UserID' => Gdn::session()->UserID, 'TransientKey' => $transientKey, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime()]);
         trace("Inserting session stash {$sessionID}");
         $session = $sql->select()->from('Session')->where('SessionID', $sessionID)->get()->firstRow();
         // Save a session cookie.
         $path = c('Garden.Cookie.Path', '/');
         $domain = c('Garden.Cookie.Domain', '');
         $expire = 0;
         // If the domain being set is completely incompatible with the
         // current domain then make the domain work.
         $currentHost = Gdn::request()->host();
         if (!stringEndsWith($currentHost, trim($domain, '.'))) {
             $domain = '';
         }
         safeCookie($name, $sessionID, $expire, $path, $domain);
         $_COOKIE[$name] = $sessionID;
     }
     $session->Attributes = dbdecode($session->Attributes);
     if (!$session->Attributes) {
         $session->Attributes = [];
     }
     return $session;
 }