public static getProviderByKey ( $AuthenticationProviderKey ) : array | boolean | stdClass | ||
$AuthenticationProviderKey | ||
return | array | boolean | stdClass |
/** * * * @param bool $UserID * @throws Exception * @throws Gdn_UserException */ public function sso($UserID = false) { $this->permission('Garden.Users.Edit'); $ProviderModel = new Gdn_AuthenticationProviderModel(); $Form = new Gdn_Form(); if ($this->Request->isAuthenticatedPostBack()) { // 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, val('Password', $User), val('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'); }
/** * Connect a user with a foreign authentication system. * * @param string $UniqueID The user's unique key in the other authentication system. * @param string $ProviderKey The key of the system providing the authentication. * @param array $UserData Data to go in the user table. * @param array $Options Additional connect options. * @return int The new/existing user ID. */ public function connect($UniqueID, $ProviderKey, $UserData, $Options = []) { trace('UserModel->Connect()'); $provider = Gdn_AuthenticationProviderModel::getProviderByKey($ProviderKey); // Trusted providers can sync roles. if (val('Trusted', $provider) && (!empty($UserData['Roles']) || !empty($UserData['Roles']))) { saveToConfig('Garden.SSO.SyncRoles', true, false); } $UserID = false; if (!isset($UserData['UserID'])) { // Check to see if the user already exists. $Auth = $this->getAuthentication($UniqueID, $ProviderKey); $UserID = val('UserID', $Auth); if ($UserID) { $UserData['UserID'] = $UserID; } } if ($UserID) { // Save the user. $this->syncUser($UserID, $UserData); return $UserID; } else { // The user hasn't already been connected. We want to see if we can't find the user based on some critera. // Check to auto-connect based on email address. if (c('Garden.SSO.AutoConnect', c('Garden.Registration.AutoConnect')) && isset($UserData['Email'])) { $User = $this->getByEmail($UserData['Email']); trace($User, "Autoconnect User"); if ($User) { $User = (array) $User; // Save the user. $this->syncUser($User, $UserData); $UserID = $User['UserID']; } } if (!$UserID) { // Create a new user. $UserData['Password'] = md5(microtime()); $UserData['HashMethod'] = 'Random'; touchValue('CheckCaptcha', $Options, false); touchValue('NoConfirmEmail', $Options, true); touchValue('NoActivity', $Options, true); // Translate SSO style roles to an array of role IDs suitable for registration. if (!empty($UserData['Roles']) && !isset($UserData['RoleID'])) { $UserData['RoleID'] = $this->lookupRoleIDs($UserData['Roles']); } touchValue('SaveRoles', $Options, !empty($UserData['RoleID']) && c('Garden.SSO.SyncRoles', false)); trace($UserData, 'Registering User'); $UserID = $this->register($UserData, $Options); } if ($UserID) { // Save the authentication. $this->saveAuthentication(['UniqueID' => $UniqueID, 'Provider' => $ProviderKey, 'UserID' => $UserID]); } else { trace($this->Validation->resultsText(), TRACE_ERROR); } } return $UserID; }
/** * * * @param $String * @param bool $ThrowError * @return int|void */ public function sso($String, $ThrowError = false) { if (!$String) { return; } $Parts = explode(' ', $String); $String = $Parts[0]; trace($String, "SSO String"); $Data = json_decode(base64_decode($String), true); trace($Data, 'RAW SSO Data'); $Errors = array(); if (!isset($Parts[1])) { $Errors[] = 'Missing SSO signature'; } if (!isset($Parts[2])) { $Errors[] = 'Missing SSO timestamp'; } if (!empty($Errors)) { return; } $Signature = $Parts[1]; $Timestamp = $Parts[2]; $HashMethod = val(3, $Parts, 'hmacsha1'); $ClientID = val('client_id', $Data); if (!$ClientID) { trace('Missing SSO client_id', TRACE_ERROR); return; } $Provider = Gdn_AuthenticationProviderModel::getProviderByKey($ClientID); if (!$Provider) { trace("Unknown SSO Provider: {$ClientID}", TRACE_ERROR); return; } $Secret = $Provider['AssociationSecret']; // Check the signature. switch ($HashMethod) { case 'hmacsha1': $CalcSignature = hash_hmac('sha1', "{$String} {$Timestamp}", $Secret); break; default: trace("Invalid SSO hash method {$HashMethod}.", TRACE_ERROR); return; } if ($CalcSignature != $Signature) { trace("Invalid SSO signature: {$Signature}", TRACE_ERROR); return; } $UniqueID = $Data['uniqueid']; $User = arrayTranslate($Data, array('name' => 'Name', 'email' => 'Email', 'photourl' => 'Photo', 'roles' => 'Roles', 'uniqueid' => null, 'client_id' => null), true); trace($User, 'SSO User'); $UserID = Gdn::userModel()->connect($UniqueID, $ClientID, $User); return $UserID; }
/** * * * @param null $ProviderKey * @param bool $Force * @return array|bool|stdClass */ public function getProvider($ProviderKey = null, $Force = false) { static $AuthModel = null; static $Provider = null; if (is_null($AuthModel)) { $AuthModel = new Gdn_AuthenticationProviderModel(); } $AuthenticationSchemeAlias = $this->getAuthenticationSchemeAlias(); if (is_null($Provider) || $Force === true) { if (!is_null($ProviderKey)) { $ProviderData = $AuthModel->getProviderByKey($ProviderKey); } else { $ProviderData = $AuthModel->getProviderByScheme($AuthenticationSchemeAlias, Gdn::session()->UserID); if (!$ProviderData && Gdn::session()->UserID > 0) { $ProviderData = $AuthModel->getProviderByScheme($AuthenticationSchemeAlias, null); } } if ($ProviderData) { $Provider = $ProviderData; } else { return false; } } return $Provider; }
/** * Return all the information saved in provider table. * * @return array Stored provider data (secret, client_id, etc.). */ public function provider() { if (!$this->provider) { $this->provider = Gdn_AuthenticationProviderModel::getProviderByKey($this->providerKey); } return $this->provider; }