function WriteJsConnect($User, $Request, $ClientID, $Secret, $Secure = TRUE) { $User = array_change_key_case($User); // Error checking. if ($Secure) { // Check the client. if (!isset($Request['client_id'])) { $Error = array('error' => 'invalid_request', 'message' => 'The client_id parameter is missing.'); } elseif ($Request['client_id'] != $ClientID) { $Error = array('error' => 'invalid_client', 'message' => "Unknown client {$Request['client_id']}."); } elseif (!isset($Request['timestamp']) && !isset($Request['signature'])) { if (is_array($User) && count($User) > 0) { // This isn't really an error, but we are just going to return public information when no signature is sent. $Error = array('name' => $User['name'], 'photourl' => @$User['photourl']); } else { $Error = array('name' => '', 'photourl' => ''); } } elseif (!isset($Request['timestamp']) || !is_numeric($Request['timestamp'])) { $Error = array('error' => 'invalid_request', 'message' => 'The timestamp parameter is missing or invalid.'); } elseif (!isset($Request['signature'])) { $Error = array('error' => 'invalid_request', 'message' => 'Missing signature parameter.'); } elseif (($Diff = abs($Request['timestamp'] - JsTimestamp())) > JS_TIMEOUT) { $Error = array('error' => 'invalid_request', 'message' => 'The timestamp is invalid.'); } else { // Make sure the timestamp hasn't timed out. $Signature = md5($Request['timestamp'] . $Secret); if ($Signature != $Request['signature']) { $Error = array('error' => 'access_denied', 'message' => 'Signature invalid.'); } } } if (isset($Error)) { $Result = $Error; } elseif (is_array($User) && count($User) > 0) { if ($Secure === NULL) { $Result = $User; } else { $Result = SignJsConnect($User, $ClientID, $Secret, TRUE); } } else { $Result = array('name' => '', 'photourl' => ''); } $Json = json_encode($Result); if (isset($Request['callback'])) { header("Content-Type: application/javascript"); echo "{$Request['callback']}({$Json});"; } else { header("Content-Type: application/json"); echo $Json; } }
/** * * @param EntryController $Sender * @param array $Args */ public function Base_ConnectData_Handler($Sender, $Args) { if (GetValue(0, $Args) != 'jsconnect') { return; } include_once dirname(__FILE__) . '/functions.jsconnect.php'; $Form = $Sender->Form; $JsConnect = $Form->GetFormValue('JsConnect', $Form->GetFormValue('Form/JsConnect')); parse_str($JsConnect, $JsData); // Make sure the data is valid. $client_id = GetValue('client_id', $JsData, GetValue('clientid', $JsData, $Sender->Request->Get('client_id'), TRUE), TRUE); $Signature = GetValue('signature', $JsData, FALSE, TRUE); $String = GetValue('sigStr', $JsData, FALSE, TRUE); // debugging unset($JsData['string']); if (!$client_id) { throw new Gdn_UserException(sprintf(T('ValidateRequired'), 'client_id'), 400); } $Provider = self::GetProvider($client_id); if (!$Provider) { throw new Gdn_UserException(sprintf(T('Unknown client: %s.'), $client_id), 400); } if (!GetValue('TestMode', $Provider)) { if (!$Signature) { throw new Gdn_UserException(sprintf(T('ValidateRequired'), 'signature'), 400); } // Validate the signature. $CalculatedSignature = SignJsConnect($JsData, $client_id, GetValue('AssociationSecret', $Provider), GetValue('HashType', $Provider, 'md5')); if ($CalculatedSignature != $Signature) { throw new Gdn_UserException(T("Signature invalid."), 400); } } // Map all of the standard jsConnect data. $Map = array('uniqueid' => 'UniqueID', 'name' => 'Name', 'email' => 'Email', 'photourl' => 'Photo'); foreach ($Map as $Key => $Value) { $Form->SetFormValue($Value, GetValue($Key, $JsData, '')); } if (isset($JsData['roles'])) { $Form->SetFormValue('Roles', $JsData['roles']); } // Now add any extended information that jsConnect might have sent. $ExtData = array_diff_key($JsData, $Map); if (class_exists('SimpleAPIPlugin')) { SimpleAPIPlugin::TranslatePost($ExtData, FALSE); } Gdn::UserModel()->DefineSchema(); $Keys = array_keys(Gdn::UserModel()->Schema->Fields()); $UserFields = array_change_key_case(array_combine($Keys, $Keys)); foreach ($ExtData as $Key => $Value) { $lkey = strtolower($Key); if (array_key_exists($lkey, $UserFields)) { $Form->SetFormValue($UserFields[$lkey], $Value); } else { $Form->SetFormValue($Key, $Value); } } $Form->SetFormValue('Provider', $client_id); $Form->SetFormValue('ProviderName', GetValue('Name', $Provider, '')); $Form->AddHidden('JsConnect', $JsData); $Sender->SetData('ClientID', $client_id); $Sender->SetData('Verified', TRUE); $Sender->SetData('Trusted', GetValue('Trusted', $Provider, TRUE)); // this is a trusted connection. $Sender->SetData('SSOUser', $JsData); }