public function sso($String, $ThrowError = false)
{
if (!$String) {
return null;
}
$Parts = explode(' ', $String);
$String = $Parts[0];
trace($String, "SSO String");
$Data = json_decode(base64_decode($String), true);
trace($Data, 'RAW SSO Data');
if (!isset($Parts[1])) {
$this->Validation->addValidationResult('sso', 'Missing SSO signature.');
}
if (!isset($Parts[2])) {
$this->Validation->addValidationResult('sso', 'Missing SSO timestamp.');
}
if (count($this->Validation->results()) > 0) {
$msg = $this->Validation->resultsText();
if ($ThrowError) {
throw new Gdn_UserException($msg, 400);
}
return false;
}
$Signature = $Parts[1];
$Timestamp = $Parts[2];
$HashMethod = val(3, $Parts, 'hmacsha1');
$ClientID = val('client_id', $Data);
if (!$ClientID) {
$this->Validation->addValidationResult('sso', 'Missing SSO client_id');
return false;
}
$Provider = Gdn_AuthenticationProviderModel::getProviderByKey($ClientID);
if (!$Provider) {
$this->Validation->addValidationResult('sso', "Unknown SSO Provider: {$ClientID}");
return false;
}
$Secret = $Provider['AssociationSecret'];
if (!trim($Secret, '.')) {
$this->Validation->addValidationResult('sso', 'Missing client secret');
return false;
}
// Check the signature.
switch ($HashMethod) {
case 'hmacsha1':
$CalcSignature = hash_hmac('sha1', "{$String} {$Timestamp}", $Secret);
break;
default:
$this->Validation->addValidationResult('sso', "Invalid SSO hash method {$HashMethod}.");
return false;
}
if ($CalcSignature != $Signature) {
$this->Validation->addValidationResult('sso', "Invalid SSO signature: {$Signature}");
return false;
}
$UniqueID = $Data['uniqueid'];
$User = arrayTranslate($Data, ['name' => 'Name', 'email' => 'Email', 'photourl' => 'Photo', 'roles' => 'Roles', 'uniqueid' => null, 'client_id' => null], true);
// Remove important missing keys.
if (!array_key_exists('photourl', $Data)) {
unset($User['Photo']);
}
if (!array_key_exists('roles', $Data)) {
unset($User['Roles']);
}
trace($User, 'SSO User');
$UserID = Gdn::userModel()->connect($UniqueID, $ClientID, $User);
return $UserID;
}