/**
  * 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();
 }
 public function SSO($UserID = FALSE)
 {
     $this->Permission('Garden.Users.Edit');
     $ProviderModel = new Gdn_AuthenticationProviderModel();
     $Form = new Gdn_Form();
     if ($this->Request->IsPostBack()) {
         // Make sure everything has been posted.
         $Form->ValidateRule('ClientID', 'ValidateRequired');
         $Form->ValidateRule('UniqueID', 'ValidateRequired');
         if (!ValidateRequired($Form->GetFormValue('Username')) && !ValidateRequired($Form->GetFormValue('Email'))) {
             $Form->AddError('Username or Email is required.');
         }
         $Provider = $ProviderModel->GetProviderByKey($Form->GetFormValue('ClientID'));
         if (!$Provider) {
             $Form->AddError(sprintf('%1$s "%2$s" not found.', T('Provider'), $Form->GetFormValue('ClientID')));
         }
         if ($Form->ErrorCount() > 0) {
             throw new Gdn_UserException($Form->ErrorString());
         }
         // Grab the user.
         $User = FALSE;
         if ($Email = $Form->GetFormValue('Email')) {
             $User = Gdn::UserModel()->GetByEmail($Email);
         }
         if (!$User && ($Username = $Form->GetFormValue('Username'))) {
             $User = Gdn::UserModel()->GetByUsername($Username);
         }
         if (!$User) {
             throw new Gdn_UserException(sprintf(T('User not found.'), strtolower(T(UserModel::SigninLabelCode()))), 404);
         }
         // Validate the user's password.
         $PasswordHash = new Gdn_PasswordHash();
         $Password = $this->Form->GetFormValue('Password', NULL);
         if ($Password !== NULL && !$PasswordHash->CheckPassword($Password, GetValue('Password', $User), GetValue('HashMethod', $User))) {
             throw new Gdn_UserException(T('Invalid password.'), 401);
         }
         // Okay. We've gotten this far. Let's save the authentication.
         $User = (array) $User;
         Gdn::UserModel()->SaveAuthentication(array('UserID' => $User['UserID'], 'Provider' => $Form->GetFormValue('ClientID'), 'UniqueID' => $Form->GetFormValue('UniqueID')));
         $Row = Gdn::UserModel()->GetAuthentication($Form->GetFormValue('UniqueID'), $Form->GetFormValue('ClientID'));
         if ($Row) {
             $this->SetData('Result', $Row);
         } else {
             throw new Gdn_UserException(T('There was an error saving the data.'));
         }
     } else {
         $User = Gdn::UserModel()->GetID($UserID);
         if (!$User) {
             throw NotFoundException('User');
         }
         $Result = Gdn::SQL()->Select('ua.ProviderKey', '', 'ClientID')->Select('ua.ForeignUserKey', '', 'UniqueID')->Select('ua.UserID')->Select('p.Name')->Select('p.AuthenticationSchemeAlias', '', 'Type')->From('UserAuthentication ua')->Join('UserAuthenticationProvider p', 'ua.ProviderKey = p.AuthenticationKey')->Where('UserID', $UserID)->Get()->ResultArray();
         $this->SetData('Result', $Result);
     }
     $this->Render('Blank', 'Utility', 'Dashboard');
 }
 /**
  * Mobile Themes management screen.
  *
  * @since 2.2.10.3
  * @access public
  * @param string $ThemeName Unique ID.
  * @param string $TransientKey Security token.
  */
 public function MobileThemes($ThemeName = '', $TransientKey = '')
 {
     $IsMobile = TRUE;
     $this->AddJsFile('addons.js');
     $this->AddJsFile('addons.js');
     $this->SetData('Title', T('Mobile Themes'));
     $this->Permission('Garden.Settings.Manage');
     $this->AddSideMenu('dashboard/settings/mobilethemes');
     // Get currently enabled theme.
     $EnabledThemeName = Gdn::ThemeManager()->MobileTheme();
     $ThemeInfo = Gdn::ThemeManager()->GetThemeInfo($EnabledThemeName);
     $this->SetData('EnabledThemeInfo', $ThemeInfo);
     $this->SetData('EnabledThemeFolder', GetValue('Folder', $ThemeInfo));
     $this->SetData('EnabledTheme', $ThemeInfo);
     $this->SetData('EnabledThemeName', GetValue('Name', $ThemeInfo, GetValue('Index', $ThemeInfo)));
     // Get all themes.
     $Themes = Gdn::ThemeManager()->AvailableThemes();
     // Filter themes.
     foreach ($Themes as $ThemeKey => $ThemeData) {
         // Only show mobile themes.
         if (empty($ThemeData['IsMobile'])) {
             unset($Themes[$ThemeKey]);
         }
         // Remove themes that are archived
         if (!empty($ThemeData['Archived'])) {
             unset($Themes[$ThemeKey]);
         }
     }
     uasort($Themes, array('SettingsController', '_NameSort'));
     $this->SetData('AvailableThemes', $Themes);
     // Process self-post.
     if ($ThemeName != '' && Gdn::Session()->ValidateTransientKey($TransientKey)) {
         try {
             $ThemeInfo = Gdn::ThemeManager()->GetThemeInfo($ThemeName);
             if ($ThemeInfo === FALSE) {
                 throw new Exception(sprintf(T("Could not find a theme identified by '%s'"), $ThemeName));
             }
             Gdn::Session()->SetPreference(array('PreviewThemeName' => '', 'PreviewThemeFolder' => ''));
             // Clear out the preview
             Gdn::ThemeManager()->EnableTheme($ThemeName, $IsMobile);
             $this->EventArguments['ThemeName'] = $ThemeName;
             $this->EventArguments['ThemeInfo'] = $ThemeInfo;
             $this->FireEvent('AfterEnableTheme');
         } catch (Exception $Ex) {
             $this->Form->AddError($Ex);
         }
         $AsyncRequest = $this->DeliveryType() === DELIVERY_METHOD_JSON ? TRUE : FALSE;
         if ($this->Form->ErrorCount() == 0) {
             if ($AsyncRequest) {
                 echo 'Success';
                 $this->Render('Blank', 'Utility', 'Dashboard');
                 exit;
             } else {
                 Redirect('/settings/mobilethemes');
             }
         } else {
             if ($AsyncRequest) {
                 echo $this->Form->ErrorString();
                 $this->Render('Blank', 'Utility', 'Dashboard');
                 exit;
             }
         }
     }
     $this->Render();
 }