Exemplo n.º 1
0
/**
 * Write the jsConnect string for single sign on.
 *
 * @param array $User An array containing information about the currently signed on user. If no user is signed in then this should be an empty array.
 * @param array $Request An array of the $_GET request.
 * @param string $ClientID The string client ID that you set up in the jsConnect settings page.
 * @param string $Secret The string secred that you set up in the jsConnect settings page.
 * @param string|bool $Secure Whether or not to check for security. This is one of these values.
 *  - true: Check for security and sign the response with an md5 hash.
 *  - false: Don't check for security, but sign the response with an md5 hash.
 *  - string: Check for security and sign the response with the given hash algorithm. See hash_algos() for what your server can support.
 *  - null: Don't check for security and don't sign the response.
 * @since 1.1b Added the ability to provide a hash algorithm to $Secure.
 */
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 = ['error' => 'invalid_request', 'message' => 'The client_id parameter is missing.'];
        } elseif ($Request['client_id'] != $ClientID) {
            $Error = ['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 = ['name' => $User['name'], 'photourl' => @$User['photourl']];
            } else {
                $Error = ['name' => '', 'photourl' => ''];
            }
        } elseif (!isset($Request['timestamp']) || !is_numeric($Request['timestamp'])) {
            $Error = ['error' => 'invalid_request', 'message' => 'The timestamp parameter is missing or invalid.'];
        } elseif (!isset($Request['signature'])) {
            $Error = ['error' => 'invalid_request', 'message' => 'Missing  signature parameter.'];
        } elseif (($Diff = abs($Request['timestamp'] - jsTimestamp())) > JS_TIMEOUT) {
            $Error = ['error' => 'invalid_request', 'message' => 'The timestamp is invalid.'];
        } else {
            // Make sure the timestamp hasn't timed out.
            $Signature = jsHash($Request['timestamp'] . $Secret, $Secure);
            if ($Signature != $Request['signature']) {
                $Error = ['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, $Secure, true);
        }
    } else {
        $Result = ['name' => '', 'photourl' => ''];
    }
    $Json = json_encode($Result);
    if (isset($Request['callback'])) {
        safeHeader('Content-Type: application/javascript');
        echo "{$Request['callback']}({$Json})";
    } else {
        safeHeader('Content-Type: application/json');
        echo $Json;
    }
}
Exemplo n.º 2
0
 /**
  *
  * @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', 'fullname' => 'FullName', 'roles' => 'Roles');
     foreach ($Map as $Key => $Value) {
         if (array_key_exists($Key, $JsData)) {
             $Form->SetFormValue($Value, $JsData[$Key]);
         }
     }
     // 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);
 }