Example #1
0
 /**
  *
  *
  * @param int $UserID
  * @param array $RoleIDs
  * @param bool $RecordEvent
  */
 public function saveRoles($UserID, $RoleIDs, $RecordEvent)
 {
     if (is_string($RoleIDs) && !is_numeric($RoleIDs)) {
         // The $RoleIDs are a comma delimited list of role names.
         $RoleNames = array_map('trim', explode(',', $RoleIDs));
         $RoleIDs = $this->SQL->select('r.RoleID')->from('Role r')->whereIn('r.Name', $RoleNames)->get()->resultArray();
         $RoleIDs = array_column($RoleIDs, 'RoleID');
     }
     if (!is_array($RoleIDs)) {
         $RoleIDs = [$RoleIDs];
     }
     // Get the current roles.
     $OldRoleIDs = [];
     $OldRoleData = $this->SQL->select('ur.RoleID, r.Name')->from('UserRole ur')->join('Role r', 'r.RoleID = ur.RoleID', 'left')->where('ur.UserID', $UserID)->get()->resultArray();
     if ($OldRoleData !== false) {
         $OldRoleIDs = array_column($OldRoleData, 'RoleID');
     }
     // 1a) Figure out which roles to delete.
     $DeleteRoleIDs = [];
     foreach ($OldRoleData as $row) {
         // The role should be deleted if it is an orphan or the user has not been assigned the role.
         if ($row['Name'] === null || !in_array($row['RoleID'], $RoleIDs)) {
             $DeleteRoleIDs[] = $row['RoleID'];
         }
     }
     // 1b) Remove old role associations for this user.
     if (!empty($DeleteRoleIDs)) {
         $this->SQL->whereIn('RoleID', $DeleteRoleIDs)->delete('UserRole', ['UserID' => $UserID]);
     }
     // 2a) Figure out which roles to insert.
     $InsertRoleIDs = array_diff($RoleIDs, $OldRoleIDs);
     // 2b) Insert the new role associations for this user.
     foreach ($InsertRoleIDs as $InsertRoleID) {
         if (is_numeric($InsertRoleID)) {
             $this->SQL->insert('UserRole', ['UserID' => $UserID, 'RoleID' => $InsertRoleID]);
         }
     }
     $this->clearCache($UserID, ['roles', 'permissions']);
     if ($RecordEvent) {
         $User = $this->getID($UserID);
         $OldRoles = [];
         foreach ($DeleteRoleIDs as $deleteRoleID) {
             $role = RoleModel::roles($deleteRoleID);
             $OldRoles[] = val('Name', $role, t('Unknown') . ' (' . $deleteRoleID . ')');
         }
         $NewRoles = [];
         foreach ($InsertRoleIDs as $insertRoleID) {
             $role = RoleModel::roles($insertRoleID);
             $NewRoles[] = val('Name', $role, t('Unknown') . ' (' . $insertRoleID . ')');
         }
         $RemovedRoles = array_diff($OldRoles, $NewRoles);
         $NewRoles = array_diff($NewRoles, $OldRoles);
         foreach ($RemovedRoles as $RoleName) {
             Logger::event('role_remove', Logger::INFO, "{username} removed {toUsername} from the {role} role.", ['touserid' => $User->UserID, 'toUsername' => $User->Name, 'role' => $RoleName]);
         }
         foreach ($NewRoles as $RoleName) {
             Logger::event('role_add', Logger::INFO, "{username} added {toUsername} to the {role} role.", ['touserid' => $User->UserID, 'toUsername' => $User->Name, 'role' => $RoleName]);
         }
     }
 }
 /**
  *
  *
  * @param $PluginName
  * @return bool
  * @throws Exception
  */
 public function disablePlugin($PluginName)
 {
     // Get the plugin and make sure its name is the correct case.
     $Plugin = $this->getPluginInfo($PluginName);
     if ($Plugin) {
         $PluginName = $Plugin['Index'];
     }
     Gdn_Autoloader::smartFree(Gdn_Autoloader::CONTEXT_PLUGIN, $Plugin);
     $enabled = $this->isEnabled($PluginName);
     // 1. Check to make sure that no other enabled plugins rely on this one
     // Get all available plugins and compile their requirements
     foreach ($this->enabledPlugins() as $CheckingName => $Trash) {
         $CheckingInfo = $this->getPluginInfo($CheckingName);
         $RequiredPlugins = ArrayValue('RequiredPlugins', $CheckingInfo, false);
         if (is_array($RequiredPlugins) && array_key_exists($PluginName, $RequiredPlugins) === true) {
             throw new Exception(sprintf(T('You cannot disable the %1$s plugin because the %2$s plugin requires it in order to function.'), $PluginName, $CheckingName));
         }
     }
     // 2. Perform necessary hook action
     $this->pluginHook($PluginName, self::ACTION_DISABLE, true);
     // 3. Disable it.
     SaveToConfig("EnabledPlugins.{$PluginName}", false);
     unset($this->EnabledPlugins[$PluginName]);
     if ($enabled) {
         Logger::event('addon_disabled', LogLevel::NOTICE, 'The {addonName} plugin was disabled.', array('addonName' => $PluginName));
     }
     // Redefine the locale manager's settings $Locale->Set($CurrentLocale, $EnabledApps, $EnabledPlugins, TRUE);
     Gdn::locale()->refresh();
     $this->EventArguments['AddonName'] = $PluginName;
     $this->fireEvent('AddonDisabled');
     return true;
 }
Example #3
0
 /**
  *
  *
  * @param $UserID
  * @param $RoleIDs
  * @param $RecordEvent
  */
 public function saveRoles($UserID, $RoleIDs, $RecordEvent)
 {
     if (is_string($RoleIDs) && !is_numeric($RoleIDs)) {
         // The $RoleIDs are a comma delimited list of role names.
         $RoleNames = array_map('trim', explode(',', $RoleIDs));
         $RoleIDs = $this->SQL->select('r.RoleID')->from('Role r')->whereIn('r.Name', $RoleNames)->get()->resultArray();
         $RoleIDs = array_column($RoleIDs, 'RoleID');
     }
     if (!is_array($RoleIDs)) {
         $RoleIDs = array($RoleIDs);
     }
     // Get the current roles.
     $OldRoleIDs = array();
     $OldRoleData = $this->SQL->select('ur.RoleID, r.Name')->from('Role r')->join('UserRole ur', 'r.RoleID = ur.RoleID')->where('ur.UserID', $UserID)->get()->resultArray();
     if ($OldRoleData !== false) {
         $OldRoleIDs = array_column($OldRoleData, 'RoleID');
     }
     // 1a) Figure out which roles to delete.
     $DeleteRoleIDs = array_diff($OldRoleIDs, $RoleIDs);
     // 1b) Remove old role associations for this user.
     if (count($DeleteRoleIDs) > 0) {
         $this->SQL->whereIn('RoleID', $DeleteRoleIDs)->delete('UserRole', array('UserID' => $UserID));
     }
     // 2a) Figure out which roles to insert.
     $InsertRoleIDs = array_diff($RoleIDs, $OldRoleIDs);
     // 2b) Insert the new role associations for this user.
     foreach ($InsertRoleIDs as $InsertRoleID) {
         if (is_numeric($InsertRoleID)) {
             $this->SQL->insert('UserRole', array('UserID' => $UserID, 'RoleID' => $InsertRoleID));
         }
     }
     $this->clearCache($UserID, array('roles', 'permissions'));
     if ($RecordEvent && (count($DeleteRoleIDs) > 0 || count($InsertRoleIDs) > 0)) {
         $User = $this->getID($UserID);
         $Session = Gdn::session();
         $OldRoles = false;
         if ($OldRoleData !== false) {
             $OldRoles = array_column($OldRoleData, 'Name');
         }
         $NewRoles = false;
         $NewRoleData = $this->SQL->select('r.RoleID, r.Name')->from('Role r')->join('UserRole ur', 'r.RoleID = ur.RoleID')->where('ur.UserID', $UserID)->get()->resultArray();
         if ($NewRoleData !== false) {
             $NewRoles = array_column($NewRoleData, 'Name');
         }
         $RemovedRoles = array_diff($OldRoles, $NewRoles);
         $NewRoles = array_diff($NewRoles, $OldRoles);
         foreach ($RemovedRoles as $RoleName) {
             Logger::event('role_remove', Logger::INFO, "{username} removed {toUsername} from the {role} role.", array('toUsername' => $User->Name, 'role' => $RoleName));
         }
         foreach ($NewRoles as $RoleName) {
             Logger::event('role_add', Logger::INFO, "{username} added {toUsername} to the {role} role.", array('toUsername' => $User->Name, 'role' => $RoleName));
         }
         $RemovedCount = count($RemovedRoles);
         $NewCount = count($NewRoles);
         $Story = '';
         if ($RemovedCount > 0 && $NewCount > 0) {
             $Story = sprintf(t('%1$s was removed from the %2$s %3$s and added to the %4$s %5$s.'), $User->Name, implode(', ', $RemovedRoles), plural($RemovedCount, 'role', 'roles'), implode(', ', $NewRoles), plural($NewCount, 'role', 'roles'));
         } elseif ($RemovedCount > 0) {
             $Story = sprintf(t('%1$s was removed from the %2$s %3$s.'), $User->Name, implode(', ', $RemovedRoles), plural($RemovedCount, 'role', 'roles'));
         } elseif ($NewCount > 0) {
             $Story = sprintf(t('%1$s was added to the %2$s %3$s.'), $User->Name, implode(', ', $NewRoles), plural($NewCount, 'role', 'roles'));
         }
     }
 }
Example #4
0
 public function EnableTheme($ThemeName, $IsMobile = FALSE)
 {
     // Make sure to run the setup
     $this->TestTheme($ThemeName);
     // Set the theme.
     $ThemeInfo = $this->GetThemeInfo($ThemeName);
     $ThemeFolder = GetValue('Folder', $ThemeInfo, '');
     $oldTheme = $IsMobile ? C('Garden.MobileTheme', 'mobile') : C('Garden.Theme', 'default');
     if ($ThemeFolder == '') {
         throw new Exception(T('The theme folder was not properly defined.'));
     } else {
         $Options = GetValueR("{$ThemeName}.Options", $this->AvailableThemes());
         if ($Options) {
             if ($IsMobile) {
                 SaveToConfig(array('Garden.MobileTheme' => $ThemeName, 'Garden.MobileThemeOptions.Name' => GetValueR("{$ThemeName}.Name", $this->AvailableThemes(), $ThemeFolder)));
             } else {
                 SaveToConfig(array('Garden.Theme' => $ThemeName, 'Garden.ThemeOptions.Name' => GetValueR("{$ThemeName}.Name", $this->AvailableThemes(), $ThemeFolder)));
             }
         } else {
             if ($IsMobile) {
                 SaveToConfig('Garden.MobileTheme', $ThemeName);
                 RemoveFromConfig('Garden.MobileThemeOptions');
             } else {
                 SaveToConfig('Garden.Theme', $ThemeName);
                 RemoveFromConfig('Garden.ThemeOptions');
             }
         }
     }
     Logger::event('theme_changed', LogLevel::NOTICE, 'The {themeType} theme changed from {oldTheme} to {newTheme}.', array('themeType' => $IsMobile ? 'mobile' : 'desktop', 'oldTheme' => $oldTheme, 'newTheme' => $ThemeName));
     // Tell the locale cache to refresh itself.
     Gdn::Locale()->Refresh();
     return TRUE;
 }
 /**
  * Do password reset.
  *
  * @access public
  * @since 2.0.0
  *
  * @param int $UserID Unique.
  * @param string $PasswordResetKey Authenticate with unique, 1-time code sent via email.
  */
 public function passwordReset($UserID = '', $PasswordResetKey = '')
 {
     $PasswordResetKey = trim($PasswordResetKey);
     if (!is_numeric($UserID) || $PasswordResetKey == '' || $this->UserModel->getAttribute($UserID, 'PasswordResetKey', '') != $PasswordResetKey) {
         $this->Form->addError('Failed to authenticate your password reset request. Try using the reset request form again.');
         Logger::event('password_reset_failure', Logger::NOTICE, '{username} failed to authenticate password reset request.');
     }
     $Expires = $this->UserModel->getAttribute($UserID, 'PasswordResetExpires');
     if ($this->Form->errorCount() === 0 && $Expires < time()) {
         $this->Form->addError('@' . t('Your password reset token has expired.', 'Your password reset token has expired. Try using the reset request form again.'));
         Logger::event('password_reset_failure', Logger::NOTICE, '{username} has an expired reset token.');
     }
     if ($this->Form->errorCount() == 0) {
         $User = $this->UserModel->getID($UserID, DATASET_TYPE_ARRAY);
         if ($User) {
             $User = arrayTranslate($User, array('UserID', 'Name', 'Email'));
             $this->setData('User', $User);
         }
     } else {
         $this->setData('Fatal', true);
     }
     if ($this->Form->errorCount() == 0 && $this->Form->isPostBack() === true) {
         $Password = $this->Form->getFormValue('Password', '');
         $Confirm = $this->Form->getFormValue('Confirm', '');
         if ($Password == '') {
             $this->Form->addError('Your new password is invalid');
             Logger::event('password_reset_failure', Logger::NOTICE, 'Failed to reset the password for {username}. Password is invalid.');
         } elseif ($Password != $Confirm) {
             $this->Form->addError('Your passwords did not match.');
         }
         Logger::event('password_reset_failure', Logger::NOTICE, 'Failed to reset the password for {username}. Passwords did not match.');
         if ($this->Form->errorCount() == 0) {
             $User = $this->UserModel->passwordReset($UserID, $Password);
             Logger::event('password_reset', Logger::NOTICE, '{username} has reset their password.');
             Gdn::session()->start($User->UserID, true);
             //            $Authenticator = Gdn::authenticator()->AuthenticateWith('password');
             //            $Authenticator->FetchData($Authenticator, array('Email' => $User->Email, 'Password' => $Password, 'RememberMe' => FALSE));
             //            $AuthUserID = $Authenticator->Authenticate();
             redirect('/');
         }
     }
     $this->render();
 }
Example #6
0
 /**
  * Validates that $ForeignKey was generated by the current user.
  *
  * @param string $ForeignKey The key to validate.
  * @return bool
  */
 public function validateTransientKey($ForeignKey, $ValidateUser = true)
 {
     static $ForceValid = false;
     if ($ForeignKey === true) {
         $ForceValid = true;
     }
     if (!$ForceValid && $ValidateUser && $this->UserID <= 0) {
         $Return = false;
     }
     if (!isset($Return)) {
         // Checking the postback here is a kludge, but is absolutely necessary until we can test the ValidatePostBack more.
         $Return = $ForceValid && Gdn::request()->isPostBack() || $ForeignKey === $this->_TransientKey && $this->_TransientKey !== false;
     }
     if (!$Return) {
         if (Gdn::session()->User) {
             Logger::event('csrf_failure', Logger::ERROR, 'Invalid transient key for {username}.');
         } else {
             Logger::event('csrf_failure', Logger::ERROR, 'Invalid transient key.');
         }
     }
     return $Return;
 }
Example #7
0
 /**
  * Send a request and receive the response
  * 
  * Options:
  *     'URL'                  => NULL,
  *     'Host'                 => NULL,       // Override the Host: header
  *     'Method'               => 'GET',      // HTTP Method
  *     'ConnectTimeout'       => 5,          // Connection timeout
  *     'Timeout'              => 5,          // Request timeout
  *     'TransferMode'         => 'normal',   // or 'binary'
  *     'SaveAs'               => NULL,       // Download the response to this file
  *     'Redirects'            => TRUE,       // Allow 302 and 302 redirects
  *     'SSLNoVerify'          => FALSE,      // Verify the remote SSL cert
  *     'PreEncodePost'        => TRUE,       // 
  *     'Cookies'              => TRUE,       // Send user's browser cookies?
  *     'CookieJar'            => FALSE,      // Create a cURL CookieJar?
  *     'CookieSession'        => FALSE,      // Should old cookies be trashed starting now?
  *     'CloseSession'         => TRUE,       // Whether to close the session. Should always do this.
  *     'Redirected'           => FALSE,      // Is this a redirected request?
  *     'Debug'                => FALSE,      // Debug output
  *     'Simulate'             => FALSE       // Don't actually request, just set up
  * 
  * @param array/string $Options URL, or array options
  * @param array $QueryParams GET/POST parameters
  * @param array $Files List of files to upload
  * @param array $ExtraHeaders Any additional headers to tack on
  * @return type 
  */
 public function Request($Options = NULL, $QueryParams = NULL, $Files = NULL, $ExtraHeaders = NULL)
 {
     /*
      * Allow requests that just want to use defaults to provide a string instead
      * of an optionlist.
      */
     if (is_string($Options)) {
         $Options = array('URL' => $Options);
     }
     if (is_null($Options)) {
         $Options = array();
     }
     $this->Options = $Options = array_merge($this->RequestDefaults, $Options);
     $this->ResponseHeaders = array();
     $this->ResponseStatus = "";
     $this->ResponseBody = "";
     $this->RequestBody = "";
     $this->ResponseTime = 0;
     $this->ContentLength = 0;
     $this->ContentType = '';
     $this->ConnectionMode = '';
     $this->ActionLog = array();
     if (is_string($Files)) {
         $Files = array($Files);
     }
     if (!is_array($Files)) {
         $Files = array();
     }
     if (!is_array($ExtraHeaders)) {
         $ExtraHeaders = array();
     }
     // Get the URL
     $RelativeURL = GetValue('URL', $Options, NULL);
     if (is_null($RelativeURL)) {
         $RelativeURL = GetValue('Url', $Options, NULL);
     }
     if (is_null($RelativeURL)) {
         throw new Exception("No URL provided");
     }
     $RequestMethod = GetValue('Method', $Options);
     $ForceHost = GetValue('Host', $Options);
     $FollowRedirects = GetValue('Redirects', $Options);
     $ConnectTimeout = GetValue('ConnectTimeout', $Options);
     $Timeout = GetValue('Timeout', $Options);
     $SaveAs = GetValue('SaveAs', $Options);
     $TransferMode = GetValue('TransferMode', $Options);
     $SSLNoVerify = GetValue('SSLNoVerify', $Options);
     $PreEncodePost = GetValue('PreEncodePost', $Options);
     $SendCookies = GetValue('Cookies', $Options);
     $CookieJar = GetValue('CookieJar', $Options);
     $CookieSession = GetValue('CookieSession', $Options);
     $CloseSesssion = GetValue('CloseSession', $Options);
     $Redirected = GetValue('Redirected', $Options);
     $Debug = GetValue('Debug', $Options, FALSE);
     $Simulate = GetValue('Simulate', $Options);
     $OldVolume = $this->Loud;
     if ($Debug) {
         $this->Loud = TRUE;
     }
     $Url = $RelativeURL;
     $PostData = $QueryParams;
     /*
      * If files were provided, preprocess the list and exclude files that don't
      * exist. Also, change the method to POST if it is currently GET and there 
      * are valid files to send.
      */
     $SendFiles = array();
     foreach ($Files as $File => $FilePath) {
         if (file_exists($FilePath)) {
             $SendFiles[$File] = $FilePath;
         }
     }
     $this->FileTransfer = (bool) sizeof($SendFiles);
     if ($this->FileTransfer && $RequestMethod != "PUT") {
         $this->Options['Method'] = 'POST';
         $RequestMethod = GetValue('Method', $Options);
     }
     /*
      * If extra headers were provided, preprocess the list into the correct 
      * format for inclusion into both cURL and fsockopen header queues.
      */
     // Tack on Host header if forced
     if (!is_null($ForceHost)) {
         $ExtraHeaders['Host'] = $ForceHost;
     }
     $SendExtraHeaders = array();
     foreach ($ExtraHeaders as $ExtraHeader => $ExtraHeaderValue) {
         $SendExtraHeaders[] = "{$ExtraHeader}: {$ExtraHeaderValue}";
     }
     /*
      * If the request is being saved to a file, prepare to save to the 
      * filesystem.
      */
     $this->SaveFile = FALSE;
     if ($SaveAs) {
         $SavePath = dirname($SaveAs);
         $CanSave = @mkdir($SavePath, 0775, TRUE);
         if (!is_writable($SavePath)) {
             throw new Exception("Cannot write to save path: {$SavePath}");
         }
         $this->SaveFile = $SaveAs;
     }
     /*
      * Parse Query Parameters and collapse into a querystring in the case of
      * GETs.
      */
     $RequestMethod = strtoupper($RequestMethod);
     switch ($RequestMethod) {
         case 'PUT':
         case 'POST':
             break;
         case 'GET':
         default:
             $PostData = is_array($PostData) ? http_build_query($PostData) : $PostData;
             if (strlen($PostData)) {
                 if (stristr($RelativeURL, '?')) {
                     $Url .= '&';
                 } else {
                     $Url .= '?';
                 }
                 $Url .= $PostData;
             }
             break;
     }
     $this->Action("Requesting {$Url}");
     $UrlParts = parse_url($Url);
     // Extract scheme
     $Scheme = strtolower(GetValue('scheme', $UrlParts, 'http'));
     $this->Action(" scheme: {$Scheme}");
     // Extract hostname
     $Host = GetValue('host', $UrlParts, '');
     $this->Action(" host: {$Host}");
     // Extract / deduce port
     $Port = GetValue('port', $UrlParts, NULL);
     if (empty($Port)) {
         $Port = $Scheme == 'https' ? 443 : 80;
     }
     $this->Action(" port: {$Port}");
     // Extract Path&Query
     $Path = GetValue('path', $UrlParts, '');
     $Query = GetValue('query', $UrlParts, '');
     $this->UseSSL = $Scheme == 'https' ? TRUE : FALSE;
     $this->Action(" transfer mode: {$TransferMode}");
     $logContext = array('url' => $Url, 'method' => $RequestMethod);
     /*
      * ProxyRequest can masquerade as the current user, so collect and encode
      * their current cookies as the default case is to send them.
      */
     $Cookie = '';
     $EncodeCookies = TRUE;
     foreach ($_COOKIE as $Key => $Value) {
         if (strncasecmp($Key, 'XDEBUG', 6) == 0) {
             continue;
         }
         if (strlen($Cookie) > 0) {
             $Cookie .= '; ';
         }
         $EncodedValue = $EncodeCookies ? urlencode($Value) : $Value;
         $Cookie .= "{$Key}={$EncodedValue}";
     }
     // This prevents problems for sites that use sessions.
     if ($CloseSesssion) {
         @session_write_close();
     }
     $Response = '';
     $this->Action("Parameters: " . print_r($PostData, true));
     // We need cURL
     if (!function_exists('curl_init')) {
         throw new Exception('Encountered an error while making a request to the remote server: Your PHP configuration does not allow cURL requests.');
     }
     $Handler = curl_init();
     curl_setopt($Handler, CURLOPT_HEADER, FALSE);
     curl_setopt($Handler, CURLINFO_HEADER_OUT, TRUE);
     curl_setopt($Handler, CURLOPT_RETURNTRANSFER, TRUE);
     curl_setopt($Handler, CURLOPT_USERAGENT, GetValue('HTTP_USER_AGENT', $_SERVER, 'Vanilla/2.0'));
     curl_setopt($Handler, CURLOPT_CONNECTTIMEOUT, $ConnectTimeout);
     curl_setopt($Handler, CURLOPT_HEADERFUNCTION, array($this, 'CurlHeader'));
     if ($TransferMode == 'binary') {
         curl_setopt($Handler, CURLOPT_BINARYTRANSFER, TRUE);
     }
     if ($RequestMethod != 'GET' && $RequestMethod != 'POST') {
         curl_setopt($Handler, CURLOPT_CUSTOMREQUEST, $RequestMethod);
     }
     if ($CookieJar) {
         curl_setopt($Handler, CURLOPT_COOKIEJAR, $this->CookieJar);
         curl_setopt($Handler, CURLOPT_COOKIEFILE, $this->CookieJar);
     }
     if ($CookieSession) {
         curl_setopt($Handler, CURLOPT_COOKIESESSION, TRUE);
     }
     if ($FollowRedirects) {
         curl_setopt($Handler, CURLOPT_FOLLOWLOCATION, TRUE);
         curl_setopt($Handler, CURLOPT_AUTOREFERER, TRUE);
         curl_setopt($Handler, CURLOPT_MAXREDIRS, 10);
     }
     if ($this->UseSSL) {
         $this->Action(" Using SSL");
         curl_setopt($Handler, CURLOPT_SSL_VERIFYPEER, !$SSLNoVerify);
         curl_setopt($Handler, CURLOPT_SSL_VERIFYHOST, $SSLNoVerify ? 0 : 2);
     }
     if ($Timeout > 0) {
         curl_setopt($Handler, CURLOPT_TIMEOUT, $Timeout);
     }
     if ($Cookie != '' && $SendCookies) {
         $this->Action(" Sending client cookies");
         curl_setopt($Handler, CURLOPT_COOKIE, $Cookie);
     }
     if ($this->SaveFile) {
         $this->Action(" Saving to file: {$this->SaveFile}");
         $FileHandle = fopen($this->SaveFile, 'w+');
         curl_setopt($Handler, CURLOPT_FILE, $FileHandle);
     }
     // Allow POST
     if ($RequestMethod == 'POST') {
         if ($this->FileTransfer) {
             $this->Action(" POSTing files");
             foreach ($SendFiles as $File => $FilePath) {
                 $PostData[$File] = "@{$FilePath}";
             }
         } else {
             if ($PreEncodePost && is_array($PostData)) {
                 $PostData = http_build_query($PostData);
             }
         }
         curl_setopt($Handler, CURLOPT_POST, TRUE);
         curl_setopt($Handler, CURLOPT_POSTFIELDS, $PostData);
         if (!is_array($PostData) && !is_object($PostData)) {
             $SendExtraHeaders['Content-Length'] = strlen($PostData);
         }
         $this->RequestBody = $PostData;
     }
     // Allow PUT
     if ($RequestMethod == 'PUT') {
         if ($this->FileTransfer) {
             $SendFile = GetValue('0', $SendFiles);
             $SendFileSize = filesize($SendFile);
             $this->Action(" PUTing file: {$SendFile}");
             $SendFileObject = fopen($SendFile, 'r');
             curl_setopt($Handler, CURLOPT_PUT, TRUE);
             curl_setopt($Handler, CURLOPT_INFILE, $SendFileObject);
             curl_setopt($Handler, CURLOPT_INFILESIZE, $SendFileSize);
             $SendExtraHeaders[] = "Content-Length: {$SendFileSize}";
         } else {
             curl_setopt($Handler, CURLOPT_CUSTOMREQUEST, 'PUT');
             curl_setopt($Handler, CURLOPT_POSTFIELDS, $PostData);
             if (!is_array($PostData) && !is_object($PostData)) {
                 $SendExtraHeaders['Content-Length'] = strlen($PostData);
             } else {
                 $TempPostData = http_build_str($PostData);
                 $SendExtraHeaders['Content-Length'] = strlen($TempPostData);
             }
             $this->RequestBody = $PostData;
         }
     }
     // Any extra needed headers
     if (sizeof($SendExtraHeaders)) {
         curl_setopt($Handler, CURLOPT_HTTPHEADER, $SendExtraHeaders);
     }
     // Set URL
     curl_setopt($Handler, CURLOPT_URL, $Url);
     curl_setopt($Handler, CURLOPT_PORT, $Port);
     if (val('Log', $Options, TRUE)) {
         Logger::event('http_request', Logger::DEBUG, '{method} {url}', $logContext);
     }
     $this->CurlReceive($Handler);
     if ($Simulate) {
         return NULL;
     }
     curl_close($Handler);
     $logContext['responseCode'] = $this->ResponseStatus;
     $logContext['responseTime'] = $this->ResponseTime;
     if (Debug()) {
         if ($this->ContentType == 'application/json') {
             $body = @json_decode($this->ResponseBody, true);
             if (!$body) {
                 $body = $this->ResponseBody;
             }
             $logContext['responseBody'] = $body;
         } else {
             $logContext['responseBody'] = $this->ResponseBody;
         }
     }
     if (val('Log', $Options, TRUE)) {
         if ($this->ResponseClass('2xx')) {
             Logger::event('http_response', Logger::DEBUG, '{responseCode} {method} {url} in {responseTime}s', $logContext);
         } else {
             Logger::event('http_response_error', Logger::DEBUG, '{responseCode} {method} {url} in {responseTime}s', $logContext);
         }
     }
     $this->Loud = $OldVolume;
     return $this->ResponseBody;
 }
Example #8
0
 /**
  *
  *
  * @param $ThemeName
  * @param bool $IsMobile
  * @return bool
  * @throws Exception
  */
 public function enableTheme($ThemeName, $IsMobile = false)
 {
     // Make sure to run the setup
     $this->testTheme($ThemeName);
     // Set the theme.
     $ThemeInfo = $this->getThemeInfo($ThemeName);
     $ThemeFolder = val('Folder', $ThemeInfo, '');
     $oldTheme = $IsMobile ? c('Garden.MobileTheme', 'mobile') : c('Garden.Theme', 'default');
     if ($ThemeFolder == '') {
         throw new Exception(t('The theme folder was not properly defined.'));
     } else {
         $Options = valr("{$ThemeName}.Options", $this->AvailableThemes());
         if ($Options) {
             if ($IsMobile) {
                 saveToConfig(array('Garden.MobileTheme' => $ThemeName, 'Garden.MobileThemeOptions.Name' => valr("{$ThemeName}.Name", $this->availableThemes(), $ThemeFolder)));
             } else {
                 saveToConfig(array('Garden.Theme' => $ThemeName, 'Garden.ThemeOptions.Name' => valr("{$ThemeName}.Name", $this->availableThemes(), $ThemeFolder)));
             }
         } else {
             if ($IsMobile) {
                 saveToConfig('Garden.MobileTheme', $ThemeName);
                 removeFromConfig('Garden.MobileThemeOptions');
             } else {
                 saveToConfig('Garden.Theme', $ThemeName);
                 removeFromConfig('Garden.ThemeOptions');
             }
         }
     }
     if ($oldTheme !== $ThemeName) {
         $this->themeHook($ThemeName, self::ACTION_ENABLE, true);
         Logger::event('theme_changed', Logger::NOTICE, 'The {themeType} theme changed from {oldTheme} to {newTheme}.', array('themeType' => $IsMobile ? 'mobile' : 'desktop', 'oldTheme' => $oldTheme, 'newTheme' => $ThemeName));
     }
     // Tell the locale cache to refresh itself.
     Gdn::locale()->refresh();
     return true;
 }
Example #9
0
 /**
  * Run the structure for all addons.
  *
  * The structure runs the addons in priority order so that higher priority addons override lower priority ones.
  *
  * @param bool $captureOnly Run the structure or just capture the SQL changes.
  * @throws Exception Throws an exception if in debug mode and something goes wrong.
  */
 public function runStructure($captureOnly = false)
 {
     $addons = array_reverse(Gdn::addonManager()->getEnabled());
     // These variables are required for included structure files.
     $Database = Gdn::database();
     $SQL = $this->SQL;
     $SQL->CaptureModifications = $captureOnly;
     $Structure = Gdn::structure();
     $Structure->CaptureOnly = $captureOnly;
     /* @var Addon $addon */
     foreach ($addons as $addon) {
         // Look for a structure file.
         if ($structure = $addon->getSpecial('structure')) {
             Logger::event('addon_structure', Logger::INFO, "Executing structure for {addonKey}.", ['addonKey' => $addon->getKey(), 'structureType' => 'file']);
             try {
                 include $addon->path($structure);
             } catch (\Exception $ex) {
                 if (debug()) {
                     throw $ex;
                 }
             }
         }
         // Look for a structure method on the plugin.
         if ($addon->getPluginClass()) {
             $plugin = Gdn::pluginManager()->getPluginInstance($addon->getPluginClass(), Gdn_PluginManager::ACCESS_CLASSNAME);
             if (is_object($plugin) && method_exists($plugin, 'structure')) {
                 Logger::event('addon_structure', Logger::INFO, "Executing structure for {addonKey}.", ['addonKey' => $addon->getKey(), 'structureType' => 'method']);
                 try {
                     call_user_func([$plugin, 'structure']);
                 } catch (\Exception $ex) {
                     if (debug()) {
                         throw $ex;
                     }
                 }
             }
         }
         // Register permissions.
         $permissions = $addon->getInfoValue('registerPermissions');
         if (!empty($permissions)) {
             Logger::event('addon_permissions', Logger::INFO, "Defining permissions for {addonKey}.", ['addonKey' => $addon->getKey(), 'permissions' => $permissions]);
             Gdn::permissionModel()->define($permissions);
         }
     }
     $this->fireEvent('AfterStructure');
     if ($captureOnly && property_exists($Structure->Database, 'CapturedSql')) {
         return $Structure->Database->CapturedSql;
     }
     return [];
 }
 /**
  * Disable an application.
  *
  * @param string $applicationName The name of the application to disable.
  * @throws \Exception Throws an exception if the application can't be disabled.
  */
 public function disableApplication($applicationName)
 {
     // 1. Check to make sure that this application is allowed to be disabled
     $ApplicationInfo = (array) arrayValueI($applicationName, $this->availableApplications(), array());
     $applicationName = $ApplicationInfo['Index'];
     if (!val('AllowDisable', $ApplicationInfo, true)) {
         throw new Exception(sprintf(t('You cannot disable the %s application.'), $applicationName));
     }
     // 2. Check to make sure that no other enabled applications rely on this one
     foreach ($this->enabledApplications() as $CheckingName => $CheckingInfo) {
         $RequiredApplications = val('RequiredApplications', $CheckingInfo, false);
         if (is_array($RequiredApplications) && array_key_exists($applicationName, $RequiredApplications) === true) {
             throw new Exception(sprintf(t('You cannot disable the %1$s application because the %2$s application requires it in order to function.'), $applicationName, $CheckingName));
         }
     }
     // 3. Check to make sure that no other enabled plugins rely on this one
     $DependendPlugins = array();
     foreach (Gdn::pluginManager()->enabledPlugins() as $CheckingName => $CheckingInfo) {
         $RequiredApplications = val('RequiredApplications', $CheckingInfo, false);
         if (is_array($RequiredApplications) && array_key_exists($applicationName, $RequiredApplications) === true) {
             $DependendPlugins[] = $CheckingName;
         }
     }
     if (!empty($DependendPlugins)) {
         throw new Exception(sprintf(t('You cannot disable the %1$s application because the following plugins require it in order to function: %2$s'), $applicationName, implode(', ', $DependendPlugins)));
     }
     // 2. Disable it
     removeFromConfig("EnabledApplications.{$applicationName}");
     Logger::event('addon_disabled', Logger::NOTICE, 'The {addonName} application was disabled.', array('addonName' => $applicationName));
     // Clear the object caches.
     Gdn_Autoloader::smartFree(Gdn_Autoloader::CONTEXT_APPLICATION, $ApplicationInfo);
     // Redefine the locale manager's settings $Locale->Set($CurrentLocale, $EnabledApps, $EnabledPlugins, true);
     $Locale = Gdn::locale();
     $Locale->set($Locale->current(), $this->enabledApplicationFolders(), Gdn::pluginManager()->enabledPluginFolders(), true);
     $this->EventArguments['AddonName'] = $applicationName;
     Gdn::pluginManager()->callEventHandlers($this, 'ApplicationManager', 'AddonDisabled');
 }
 /**
  * Set new password for current user.
  *
  * @since 2.0.0
  * @access public
  */
 public function password()
 {
     $this->permission('Garden.SignIn.Allow');
     // Don't allow password editing if using SSO Connect ONLY.
     // This is for security. We encountered the case where a customer charges
     // for membership using their external application and use SSO to let
     // their customers into Vanilla. If you allow those people to change their
     // password in Vanilla, they will then be able to log into Vanilla using
     // Vanilla's login form regardless of the state of their membership in the
     // external app.
     if (c('Garden.Registration.Method') == 'Connect') {
         Gdn::dispatcher()->dispatch('DefaultPermission');
         exit;
     }
     Gdn::userModel()->addPasswordStrength($this);
     // Get user data and set up form
     $this->getUserInfo();
     $this->Form->setModel($this->UserModel);
     $this->addDefinition('Username', $this->User->Name);
     if ($this->Form->authenticatedPostBack() === true) {
         $this->Form->setFormValue('UserID', $this->User->UserID);
         $this->UserModel->defineSchema();
         //         $this->UserModel->Validation->AddValidationField('OldPassword', $this->Form->formValues());
         // No password may have been set if they have only signed in with a connect plugin
         if (!$this->User->HashMethod || $this->User->HashMethod == "Vanilla") {
             $this->UserModel->Validation->applyRule('OldPassword', 'Required');
             $this->UserModel->Validation->applyRule('OldPassword', 'OldPassword', 'Your old password was incorrect.');
         }
         $this->UserModel->Validation->applyRule('Password', 'Required');
         $this->UserModel->Validation->applyRule('Password', 'Strength');
         $this->UserModel->Validation->applyRule('Password', 'Match');
         if ($this->Form->save()) {
             $this->informMessage(sprite('Check', 'InformSprite') . t('Your password has been changed.'), 'Dismissable AutoDismiss HasSprite');
             $this->Form->clearInputs();
             Logger::event('password_change', Logger::INFO, '{InsertName} changed password.');
         } else {
             Logger::event('password_change_failure', Logger::INFO, '{InsertName} failed to change password.', array('Error' => $this->Form->errorString()));
         }
     }
     $this->title(t('Change My Password'));
     $this->_setBreadcrumbs(t('Change My Password'), '/profile/password');
     $this->render();
 }
Example #12
0
 /**
  * Enable an addon and do all the stuff that's entailed there.
  *
  * @param Addon $addon The addon to enable.
  * @param bool $setup Whether or not to set the plugin up.
  * @throws Exception Throws an exception if something goes bonkers during the process.
  */
 private function enableAddon(Addon $addon, $setup)
 {
     if ($setup) {
         $this->addonManager->startAddon($addon);
         $this->pluginHook($addon->getRawKey(), self::ACTION_ENABLE, true);
         // If setup succeeded, register any specified permissions
         $permissions = $addon->getInfoValue('registerPermissions');
         if (!empty($permissions)) {
             $PermissionModel = Gdn::permissionModel();
             $PermissionModel->define($permissions);
         }
         // Write enabled state to config.
         saveToConfig("EnabledPlugins." . $addon->getRawKey(), true);
         Logger::event('addon_enabled', Logger::INFO, 'The {addonName} plugin was enabled.', array('addonName' => $addon->getRawKey()));
     }
     $pluginClassName = $addon->getPluginClass();
     $this->registerPlugin($pluginClassName);
 }
Example #13
0
 public function log($message, $data)
 {
     if (c('Vanilla.SSO.Debug')) {
         Logger::event('sso_logging', Logger::INFO, $message, $data);
     }
 }
Example #14
0
 /**
  * Send a query to the database and return the result.
  *
  * @param string $sql The sql to execute.
  * @param bool $checkThreshold Whether or not to check the alter table threshold before altering the table.
  * @return bool Whether or not the query succeeded.
  */
 public function query($sql, $checkThreshold = false)
 {
     if ($this->CaptureOnly) {
         if (!property_exists($this->Database, 'CapturedSql')) {
             $this->Database->CapturedSql = array();
         }
         $this->Database->CapturedSql[] = $sql;
         return true;
     } elseif ($checkThreshold && $this->getAlterTableThreshold() && $this->getRowCountEstimate($this->tableName()) >= $this->getAlterTableThreshold()) {
         $this->addIssue("The table was past its threshold. Run the alter manually.", $sql);
         // Log an event to be captured and analysed later.
         Logger::event('structure_threshold', Logger::ALERT, "Cannot alter table {tableName}. Its count of {rowCount,number} is past the {rowThreshold,number} threshold.", ['tableName' => $this->tableName(), 'rowCount' => $this->getRowCountEstimate($this->tableName()), 'rowThreshold' => $this->getAlterTableThreshold(), 'alterSql' => $sql]);
         return true;
     } else {
         $Result = $this->Database->query($sql);
         return $Result;
     }
 }
 /**
  * Undocumented method.
  *
  * @param string $ApplicationName Undocumented variable.
  * @todo Document DisableApplication() method.
  */
 public function DisableApplication($ApplicationName)
 {
     // 1. Check to make sure that this application is allowed to be disabled
     $ApplicationInfo = ArrayValueI($ApplicationName, $this->AvailableApplications(), array());
     $ApplicationName = $ApplicationInfo['Index'];
     if (!ArrayValue('AllowDisable', $ApplicationInfo, TRUE)) {
         throw new Exception(sprintf(T('You cannot disable the %s application.'), $ApplicationName));
     }
     // 2. Check to make sure that no other enabled applications rely on this one
     foreach ($this->EnabledApplications() as $CheckingName => $CheckingInfo) {
         $RequiredApplications = ArrayValue('RequiredApplications', $CheckingInfo, FALSE);
         if (is_array($RequiredApplications) && array_key_exists($ApplicationName, $RequiredApplications) === TRUE) {
             throw new Exception(sprintf(T('You cannot disable the %1$s application because the %2$s application requires it in order to function.'), $ApplicationName, $CheckingName));
         }
     }
     // 2. Disable it
     RemoveFromConfig("EnabledApplications.{$ApplicationName}");
     Logger::event('addon_disabled', LogLevel::NOTICE, 'The {addonName} application was disabled.', array('addonName' => $ApplicationName));
     // Clear the object caches.
     Gdn_Autoloader::SmartFree(Gdn_Autoloader::CONTEXT_APPLICATION, $ApplicationInfo);
     // Redefine the locale manager's settings $Locale->Set($CurrentLocale, $EnabledApps, $EnabledPlugins, TRUE);
     $Locale = Gdn::Locale();
     $Locale->Set($Locale->Current(), $this->EnabledApplicationFolders(), Gdn::PluginManager()->EnabledPluginFolders(), TRUE);
     $this->EventArguments['AddonName'] = $ApplicationName;
     Gdn::PluginManager()->CallEventHandlers($this, 'ApplicationManager', 'AddonDisabled');
 }
 /**
  * Disable an application.
  *
  * @param string $applicationName The name of the application to disable.
  * @throws \Exception Throws an exception if the application can't be disabled.
  */
 public function disableApplication($applicationName)
 {
     $addon = $this->addonManager->lookupAddon($applicationName);
     if (!$addon) {
         throw notFoundException('Application');
     }
     $applicationName = $addon->getRawKey();
     // 1. Check to make sure that this application is allowed to be disabled
     if (!$addon->getInfoValue('allowDisable', true)) {
         throw new Exception(sprintf(t('You cannot disable the %s application.'), $applicationName));
     }
     // 2. Check to make sure that no other enabled applications rely on this one.
     try {
         $this->addonManager->checkDependants($addon, true);
     } catch (Exception $ex) {
         throw new Gdn_UserException($ex->getMessage(), $ex->getCode());
     }
     // 2. Disable it
     removeFromConfig("EnabledApplications.{$applicationName}");
     Logger::event('addon_disabled', Logger::NOTICE, 'The {addonName} application was disabled.', array('addonName' => $applicationName));
     // Clear the object caches.
     $this->addonManager->stopAddonsByKey([$applicationName], \Vanilla\Addon::TYPE_ADDON);
 }