/** * * * @return array|bool|null|stdClass */ public function provider() { if ($this->_Provider === null) { $this->_Provider = Gdn_AuthenticationProviderModel::getProviderByScheme('disqus'); } return $this->_Provider; }
/** * Return the default provider. * * @return array */ public static function getDefault() { if (self::$default === null) { $Rows = self::getWhereStatic(array('IsDefault' => 1)); if (empty($Rows)) { self::$default = false; } else { self::$default = array_pop($Rows); } } return self::$default; }
/** * * * @param $Sender * @param $Args */ public function socialController_googlePlus_create($Sender, $Args) { $Sender->permission('Garden.Settings.Manage'); $Conf = new ConfigurationModule($Sender); $Conf->initialize(array('Plugins.GooglePlus.ClientID' => array('LabelCode' => 'Client ID'), 'Plugins.GooglePlus.Secret' => array('LabelCode' => 'Client secret'), 'Plugins.GooglePlus.SocialReactions' => array('Control' => 'checkbox', 'Default' => true), 'Plugins.GooglePlus.SocialSharing' => array('Control' => 'checkbox', 'Default' => true), 'Plugins.GooglePlus.UseAvatars' => array('Control' => 'checkbox', 'Default' => true), 'Plugins.GooglePlus.Default' => array('Control' => 'checkbox', 'LabelCode' => 'Make this connection your default signin method.'))); if (Gdn::request()->isAuthenticatedPostBack()) { $Model = new Gdn_AuthenticationProviderModel(); $Model->save(array('AuthenticationKey' => self::ProviderKey, 'IsDefault' => c('Plugins.GooglePlus.Default'))); } $Sender->addSideMenu('dashboard/social'); $Sender->setData('Title', sprintf(t('%s Settings'), 'Google+')); $Sender->ConfigurationModule = $Conf; $Sender->render('Settings', '', 'plugins/GooglePlus'); }
public function SSO($String) { if (!$String) { return; } $Parts = explode(' ', $String); $String = $Parts[0]; $Data = json_decode(base64_decode($String), TRUE); Trace($Data, 'RAW SSO Data'); $Errors = 0; if (!isset($Parts[1])) { Trace('Missing SSO signature', TRACE_ERROR); $Errors++; } if (!isset($Parts[2])) { Trace('Missing SSO timestamp', TRACE_ERROR); $Errors++; } if ($Errors) { return; } $Signature = $Parts[1]; $Timestamp = $Parts[2]; $HashMethod = GetValue(3, $Parts, 'hmacsha1'); $ClientID = GetValue('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.", TRACE_ERROR); return; } $UniqueID = $Data['uniqueid']; $User = ArrayTranslate($Data, array('name' => 'Name', 'email' => 'Email', 'photourl' => 'Photo', 'uniqueid' => NULL, 'client_id' => NULL), TRUE); Trace($User, 'SSO User'); $UserID = Gdn::UserModel()->Connect($UniqueID, $ClientID, $User); return $UserID; }
public function settings_delete($Sender, $Args) { $client_id = $Sender->Request->Get('client_id'); $Provider = self::getProvider($client_id); $Sender->Form->InputPrefix = FALSE; if ($Sender->Form->AuthenticatedPostBack()) { if ($Sender->Form->GetFormValue('Yes')) { $Model = new Gdn_AuthenticationProviderModel(); $Model->Delete(array('AuthenticationKey' => $client_id)); } $Sender->RedirectUrl = url('/settings/jsconnect'); $Sender->Render('Blank', 'Utility', 'Dashboard'); } else { $Sender->Render('ConfirmDelete', '', 'plugins/jsconnect'); } }
/** * * * @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; }
/** * * * @param $Sender * @param $Args */ public function settings_delete($Sender, $Args) { $client_id = $Sender->Request->get('client_id'); if ($Sender->Form->authenticatedPostBack()) { $Model = new Gdn_AuthenticationProviderModel(); $Model->delete(['AuthenticationKey' => $client_id]); $Sender->RedirectUrl = url('/settings/jsconnect'); $Sender->render('Blank', 'Utility', 'Dashboard'); } }
/** * * * @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; }
/** * Method for plugins that want a friendly /sso method to hook into. * * @param RootController $Sender * @param string $Target The url to redirect to after sso. */ public function RootController_SSO_Create($Sender, $Target = '') { if (!$Target) { $Target = $Sender->Request->Get('redirect'); if (!$Target) { $Target = '/'; } } // TODO: Make sure the target is a safe redirect. // Get the default authentication provider. $DefaultProvider = Gdn_AuthenticationProviderModel::GetDefault(); $Sender->EventArguments['Target'] = $Target; $Sender->EventArguments['DefaultProvider'] = $DefaultProvider; $Handled = FALSE; $Sender->EventArguments['Handled'] =& $Handled; $Sender->FireEvent('SSO'); // If an event handler didn't handle the signin then just redirect to the target. if (!$Handled) { Redirect($Target, 302); } }
public function CreateProviderModel() { $Key = 'k'.sha1(implode('.',array( 'proxyconnect', 'key', microtime(true), RandomString(16), Gdn::Session()->User->Name ))); $Secret = 's'.sha1(implode('.',array( 'proxyconnect', 'secret', md5(microtime(true)), RandomString(16), Gdn::Session()->User->Name ))); $ProviderModel = new Gdn_AuthenticationProviderModel(); $Inserted = $ProviderModel->Insert($Provider = array( 'AuthenticationKey' => $Key, 'AuthenticationSchemeAlias' => 'proxy', 'AssociationSecret' => $Secret, 'AssociationHashMethod' => 'HMAC-SHA1' )); return ($Inserted !== FALSE) ? $Provider : FALSE; }
/** * 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; }
public function Controller_Index($Sender) { $this->AddSliceAsset($this->GetResource('css/wordpress.css', FALSE, FALSE)); $ProviderModel = new Gdn_AuthenticationProviderModel(); $LastState = NULL; $State = NULL; do { $LastState = $State; $State = $this->State($this->ProxyConnect->Provider); $Sender->SetData('IntegrationState', $State); switch ($State) { case 'Address': // Gather remote address from user. // User has submitted the form and provided a URL if ($Sender->Form->AuthenticatedPostBack()) { // Address supplied. Query the remote blog. $Address = $Sender->Form->GetValue('WordpressUrl', NULL); if (empty($Address)) { $Sender->Form->AddError("Please enter the URL for your blog."); return $this->GetView('wordpress.php'); } $this->ProxyConnect->Provider['URL'] = $Address; $Response = $this->QueryRemote($this->ProxyConnect->Provider, 'Check', NULL, FALSE); if (GetValue('X-ProxyConnect-Enabled', $Response) == 'yes') { // Proxyconnect is enabled at the provided URL. $ProviderModel->Save($this->ProxyConnect->Provider); } else { unset($this->ProxyConnect->Provider['URL']); $Sender->Form->AddError("Unable to contact remote plugin. Perhaps your blog URL was incorrect?"); return $this->GetView('wordpress.php'); } } else { // break out of the loop and let the form render break 2; } break; case 'Exchange': if ($LastState == $State) { // exchanging again. $Sender->Form->AddError("Unable to poll remote plugin for all required information. Switch to manual integration."); return $this->GetView('wordpress.php'); } // 1: push challenge key to remote. // 2: gather urls // 3: set cookie domain // 1 - push challenge key $Response = $this->QueryRemote($this->ProxyConnect->Provider, 'Secure', array('Challenge' => GetValue('AssociationSecret', $this->ProxyConnect->Provider, 'flam'))); $ChallengeSet = GetValue('X-Autoconfigure-Challenge', $Response); if ($ChallengeSet != 'set') { $Sender->Form->AddError("Could not set Challenge key on remote. Reason was: challenge {$ChallengeSet}"); return $this->GetView('wordpress.php'); } // 2 - gather URLs $Response = $this->QueryRemote($this->ProxyConnect->Provider, 'Exchange', NULL, TRUE, TRUE); $Result = json_decode($Response); $CheckURLs = array('AuthenticateUrl', 'RegisterUrl', 'SignInUrl', 'SignOutUrl', 'PasswordUrl', 'ProfileUrl'); foreach ($CheckURLs as $CheckURL) { $Value = GetValue($CheckURL, $Result, NULL); if (!is_null($Value)) { $this->ProxyConnect->Provider[$CheckURL] = $Value; } } // save the provider data $ProviderModel->Save($this->ProxyConnect->Provider); // 3 - set cookie domain $ExplodedDomain = explode('.', Gdn::Request()->RequestHost()); if (sizeof($ExplodedDomain) == 1) { $GuessedCookieDomain = ''; } else { $GuessedCookieDomain = '.' . implode('.', array_slice($ExplodedDomain, -2, 2)); } $Response = $this->QueryRemote($this->ProxyConnect->Provider, 'Cookie', array('CookieDomain' => $GuessedCookieDomain), TRUE, TRUE); if (GetValue('X-Autoconfigure-Cookie', $Response, NULL) == 'set') { // Set local cookie domain too SaveToConfig('Garden.Cookie.Domain', $GuessedCookieDomain); } break; case NULL: // provider is fully configured. $Sender->SetData('BlogURL', GetValue('URL', $this->ProxyConnect->Provider)); break; case 'Error': return $this->GetView('providerfailed.php'); break; } } while (!is_null($State)); return $this->GetView('wordpress.php'); }
public function Disconnect($UserReference = '', $Username = '', $Provider) { if (!$this->Request->IsPostBack()) { throw PermissionException('Javascript'); } $this->Permission('Garden.SignIn.Allow'); $this->GetUserInfo($UserReference, $Username, '', TRUE); // First try and delete the authentication the fast way. Gdn::SQL()->Delete('UserAuthentication', array('UserID' => $this->User->UserID, 'ProviderKey' => $Provider)); // Delete the profile information. Gdn::UserModel()->SaveAttribute($this->User->UserID, $Provider, NULL); if ($this->DeliveryType() == DELIVERY_TYPE_ALL) { Redirect(UserUrl($this->User), '', 'connections'); } else { // Grab all of the providers again. $PModel = new Gdn_AuthenticationProviderModel(); $Providers = $PModel->GetProviders(); $this->SetData('_Providers', $Providers); $this->SetData('Connections', array()); $this->FireEvent('GetConnections'); // Send back the connection button. $Connection = $this->Data("Connections.{$Provider}"); require_once $this->FetchViewLocation('connection_functions'); $this->JsonTarget("#Provider_{$Provider} .ActivateSlider", ConnectButton($Connection), 'ReplaceWith'); $this->Render('Blank', 'Utility', 'Dashboard'); } }
/** * * * @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; }
/** * Check the default provider to see if it overrides one of the entry methods and then redirect. * * @param string $Type One of the following. * - SignIn * - Register * - SignOut (not complete) * @param string $Target * @param string $TransientKey */ protected function checkOverride($Type, $Target, $TransientKey = null) { if (!$this->Request->get('override', true)) { return; } $Provider = Gdn_AuthenticationProviderModel::getDefault(); if (!$Provider) { return; } $this->EventArguments['Target'] = $Target; $this->EventArguments['DefaultProvider'] =& $Provider; $this->EventArguments['TransientKey'] = $TransientKey; $this->fireEvent("Override{$Type}"); $Url = $Provider[$Type . 'Url']; if ($Url) { switch ($Type) { case 'Register': case 'SignIn': // When the other page comes back it needs to go through /sso to force a sso check. $Target = '/sso?target=' . urlencode($Target); break; case 'SignOut': $Cookie = c('Garden.Cookie.Name'); if (strpos($Url, '?') === false) { $Url .= '?vfcookie=' . urlencode($Cookie); } else { $Url .= '&vfcookie=' . urlencode($Cookie); } // Check to sign out here. $SignedOut = !Gdn::session()->isValid(); if (!$SignedOut && (Gdn::session()->validateTransientKey($TransientKey) || $this->Form->isPostBack())) { Gdn::session()->end(); $SignedOut = true; } // Sign out is a bit of a tricky thing so we configure the way it works. $SignoutType = c('Garden.SSO.Signout'); switch ($SignoutType) { case 'redirect-only': // Just redirect to the url. break; case 'post-only': $this->setData('Method', 'POST'); break; case 'post': // Post to the url after signing out here. if (!$SignedOut) { return; } $this->setData('Method', 'POST'); break; case 'none': return; case 'redirect': default: if (!$SignedOut) { return; } break; } break; default: throw new Exception("Unknown entry type {$Type}."); } $Url = str_ireplace('{target}', rawurlencode(url($Target, true)), $Url); if ($this->deliveryType() == DELIVERY_TYPE_ALL && strcasecmp($this->data('Method'), 'POST') != 0) { redirectUrl($Url, 302); } else { $this->setData('Url', $Url); $Script = <<<EOT <script type="text/javascript"> window.location = "{$Url}"; </script> EOT; $this->render('Redirect', 'Utility'); die; } } }
/** * * * @param string $UserReference * @param string $Username * @param $Provider * @throws Exception */ public function disconnect($UserReference = '', $Username = '', $Provider) { if (!Gdn::request()->isAuthenticatedPostBack(true)) { throw new Exception('Requires POST', 405); } $this->permission('Garden.SignIn.Allow'); $this->getUserInfo($UserReference, $Username, '', true); // First try and delete the authentication the fast way. Gdn::sql()->delete('UserAuthentication', array('UserID' => $this->User->UserID, 'ProviderKey' => $Provider)); // Delete the profile information. Gdn::userModel()->saveAttribute($this->User->UserID, $Provider, null); if ($this->deliveryType() == DELIVERY_TYPE_ALL) { redirect(userUrl($this->User), '', 'connections'); } else { // Grab all of the providers again. $PModel = new Gdn_AuthenticationProviderModel(); $Providers = $PModel->getProviders(); $this->setData('_Providers', $Providers); $this->setData('Connections', array()); $this->fireEvent('GetConnections'); // Send back the connection button. $Connection = $this->data("Connections.{$Provider}"); require_once $this->fetchViewLocation('connection_functions'); $this->jsonTarget("#Provider_{$Provider} .ActivateSlider", connectButton($Connection), 'ReplaceWith'); $this->render('Blank', 'Utility', 'Dashboard'); } }
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, $UserID); } if ($ProviderData) { $Provider = $ProviderData; } else { return FALSE; } } return $Provider; }
/** * Method for plugins that want a friendly /sso method to hook into. * * @param RootController $Sender * @param string $Target The url to redirect to after sso. */ public function rootController_sso_create($Sender, $Target = '') { if (!$Target) { $Target = $Sender->Request->get('redirect'); if (!$Target) { $Target = '/'; } } // Get the default authentication provider. $DefaultProvider = Gdn_AuthenticationProviderModel::getDefault(); $Sender->EventArguments['Target'] = $Target; $Sender->EventArguments['DefaultProvider'] = $DefaultProvider; $Handled = false; $Sender->EventArguments['Handled'] =& $Handled; $Sender->fireEvent('SSO'); // If an event handler didn't handle the signin then just redirect to the target. if (!$Handled) { safeRedirect($Target, 302); } }
function signInUrl($target = '', $force = false) { // Check to see if there is even a sign in button. if (!$force && strcasecmp(C('Garden.Registration.Method'), 'Connect') !== 0) { $defaultProvider = Gdn_AuthenticationProviderModel::getDefault(); if ($defaultProvider && !val('SignInUrl', $defaultProvider)) { return ''; } } return '/entry/signin' . ($target ? '?Target=' . urlencode($target) : ''); }
/** * Get an array of all of the trusted domains in the application. * * @return array */ function trustedDomains() { // This domain is safe. $trustedDomains = [Gdn::request()->host()]; $configuredDomains = c('Garden.TrustedDomains', []); if (!is_array($configuredDomains)) { $configuredDomains = is_string($configuredDomains) ? explode("\n", $configuredDomains) : []; } $configuredDomains = array_filter($configuredDomains); $trustedDomains = array_merge($trustedDomains, $configuredDomains); // Build a collection of authentication provider URLs. $authProviderModel = new Gdn_AuthenticationProviderModel(); $providers = $authProviderModel->getProviders(); $providerUrls = ['PasswordUrl', 'ProfileUrl', 'RegisterUrl', 'SignInUrl', 'SignOutUrl', 'URL']; // Iterate through the providers, only grabbing URLs if they're not empty and not already present. if (is_array($providers) && count($providers) > 0) { foreach ($providers as $key => $record) { foreach ($providerUrls as $urlKey) { $providerUrl = $record[$urlKey]; if ($providerUrl && ($providerDomain = parse_url($providerUrl, PHP_URL_HOST))) { if (!in_array($providerDomain, $trustedDomains)) { $trustedDomains[] = $providerDomain; } } } } } Gdn::pluginManager()->EventArguments['TrustedDomains'] =& $trustedDomains; Gdn::pluginManager()->fireAs('EntryController')->fireEvent('BeforeTargetReturn'); return array_unique($trustedDomains); }