/** * Synchronize the object with the UF Match entry. Can be called stand-alone from * the drupalUsers script * * @param Object $user the drupal user object * @param string $userKey the id of the user from the uf object * @param string $uniqId the OpenID of the user * @param string $uf the name of the user framework * @param integer $status returns the status if user created or already exits (used for CMS sync) * * @return the ufmatch object that was found or created * @access public * @static */ static function &synchronizeUFMatch(&$user, $userKey, $uniqId, $uf, $status = null, $ctype = null, $isLogin = false) { // validate that uniqId is a valid url. it will either be // an OpenID (which should always be a valid url) or a // http://uf_username/ construction (so that it can // be used as an OpenID in the future) require_once 'CRM/Utils/Rule.php'; if ($uf == 'Standalone') { if (!CRM_Utils_Rule::url($uniqId)) { return $status ? null : false; } } else { if (!CRM_Utils_Rule::email($uniqId)) { return $status ? null : false; } } $newContact = false; // make sure that a contact id exists for this user id $ufmatch =& new CRM_Core_DAO_UFMatch(); if (CRM_Core_DAO::checkFieldExists('civicrm_uf_match', 'domain_id')) { // FIXME: if() condition check was required especially for upgrade cases (2.2.x -> 3.0.x), // where folks if happen to logout, would encounter a column not found fatal error $ufmatch->domain_id = CRM_Core_Config::domainID(); } $ufmatch->uf_id = $userKey; if (!$ufmatch->find(true)) { require_once 'CRM/Core/Transaction.php'; $transaction = new CRM_Core_Transaction(); if (!empty($_POST) && !$isLogin) { $params = $_POST; $params['email'] = $uniqId; require_once 'CRM/Dedupe/Finder.php'; $dedupeParams = CRM_Dedupe_Finder::formatParams($params, 'Individual'); $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual'); if (!empty($ids) && defined('CIVICRM_UNIQ_EMAIL_PER_SITE') && CIVICRM_UNIQ_EMAIL_PER_SITE) { // restrict dupeIds to ones that belong to current domain/site. require_once 'CRM/Core/BAO/Domain.php'; $siteContacts = CRM_Core_BAO_Domain::getContactList(); foreach ($ids as $index => $dupeId) { if (!in_array($dupeId, $siteContacts)) { unset($ids[$index]); } } $ids = array_values($ids); //re-index the array } if (!empty($ids)) { $dao = new CRM_Core_DAO(); $dao->contact_id = $ids[0]; } } else { require_once 'CRM/Contact/BAO/Contact.php'; if ($uf == 'Standalone') { $dao =& CRM_Contact_BAO_Contact::matchContactOnOpenId($uniqId, $ctype); } else { $dao =& CRM_Contact_BAO_Contact::matchContactOnEmail($uniqId, $ctype); } } if ($dao) { //print "Found contact with uniqId $uniqId<br/>"; $ufmatch->contact_id = $dao->contact_id; $ufmatch->uf_name = $uniqId; } else { if ($uf == 'Drupal') { $mail = 'mail'; } else { $mail = 'email'; } if (is_Object($user)) { $params = array('email-Primary' => $user->{$mail}); } if ($ctype == 'Organization') { $params['organization_name'] = $uniqId; } else { if ($ctype == 'Household') { $params['household_name'] = $uniqId; } } if (!$ctype) { $ctype = "Individual"; } $params['contact_type'] = $ctype; // extract first / middle / last name // for joomla if ($uf == 'Joomla' && $user->name) { require_once 'CRM/Utils/String.php'; CRM_Utils_String::extractName($user->name, $params); } if ($uf == 'Standalone') { $params['openid-Primary'] = $uniqId; //need to delete below code once profile is //exposed on signup page if (!empty($user->first_name) || !empty($user->last_name)) { $params['first_name'] = $user->first_name; $params['last_name'] = $user->last_name; } elseif (!empty($user->name)) { require_once 'CRM/Utils/String.php'; CRM_Utils_String::extractName($user->name, $params); } } $contactId = CRM_Contact_BAO_Contact::createProfileContact($params, CRM_Core_DAO::$_nullArray); $ufmatch->contact_id = $contactId; $ufmatch->uf_name = $uniqId; } // check that there are not two CMS IDs matching the same CiviCRM contact - this happens when a civicrm // user has two e-mails and there is a cms match for each of them // the gets rid of the nasty fata error but still reports the error $sql = "\nSELECT uf_id\nFROM civicrm_uf_match\nWHERE ( contact_id = %1\nOR uf_name = %2\nOR uf_id = %3 )\nAND domain_id = %4\n"; $params = array(1 => array($ufmatch->contact_id, 'Integer'), 2 => array($ufmatch->uf_name, 'String'), 3 => array($ufmatch->uf_id, 'Integer'), 4 => array($ufmatch->domain_id, 'Integer')); require_once 'CRM/Core/DAO.php'; $conflict = CRM_Core_DAO::singleValueQuery($sql, $params); if (!$conflict) { $ufmatch->save(); $ufmatch->free(); $newContact = true; $transaction->commit(); } else { $msg = ts("Contact ID %1 is a match for %2 user %3 but has already been matched to %4", array(1 => $ufmatch->contact_id, 2 => $uf, 3 => $ufmatch->uf_id, 4 => $conflict)); unset($conflict); } } if ($status) { return $newContact; } else { return $ufmatch; } }
/** * Eventually we should use OAuth here, since this is mainly * for API authentication. * * For now let's just verify that they passed in a valid * OpenID. The API layer verifies a valid API key later anyway, * so we don't duplicate that effort here. * * @param string $name the user name * @param string $password the password for the above user name * * @return mixed false if no auth * array( contactID, ufID, unique string ) if success * @access public * @static */ static function authenticate($name, $password) { // check that we got a valid URL $options = array('domain_check' => false, 'allowed_schemes' => array('http', 'https')); require_once 'Validate.php'; $validUrl = Validate::uri($name, $options); if (!$validUrl) { return false; } // we got a valid URL, see if it's allowed to login require_once 'CRM/Core/BAO/OpenID.php'; $allowLogin = CRM_Core_BAO_OpenID::isAllowedToLogin($name); if (!$allowLogin) { return false; } // see if the password matches the API key require_once 'CRM/Contact/BAO/Contact.php'; $dao = CRM_Contact_BAO_Contact::matchContactOnOpenId($name); require_once 'CRM/Core/DAO.php'; $api_key = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $dao->contact_id, 'api_key'); if ($api_key != $password) { return false; } // everything looks good, setup the session and return require_once 'CRM/Standalone/User.php'; $user = new CRM_Standalone_User($name); require_once 'CRM/Core/BAO/UFMatch.php'; CRM_Core_BAO_UFMatch::synchronize($user, false, 'Standalone', 'Individual'); require_once 'CRM/Core/Session.php'; $session = CRM_Core_Session::singleton(); $returnArray = array($session->get('userID'), $session->get('ufID'), mt_rand()); return $returnArray; }
/** * Synchronize the object with the UF Match entry. Can be called stand-alone from * the drupalUsers script * * @param Object $user the drupal user object * @param string $userKey the id of the user from the uf object * @param string $uniqId the OpenID of the user * @param string $uf the name of the user framework * @param integer $status returns the status if user created or already exits (used for CMS sync) * * @return the ufmatch object that was found or created * @access public * @static */ static function &synchronizeUFMatch(&$user, $userKey, $uniqId, $uf, $status = null, $ctype = null) { // validate that uniqId is a valid url. it will either be // an OpenID (which should always be a valid url) or a // http://uf_username/ construction (so that it can // be used as an OpenID in the future) require_once 'CRM/Utils/Rule.php'; if ($uf == 'Standalone') { if (!CRM_Utils_Rule::url($uniqId)) { return $status ? null : false; } } else { if (!CRM_Utils_Rule::email($uniqId)) { return $status ? null : false; } } $newContact = false; // make sure that a contact id exists for this user id $ufmatch =& new CRM_Core_DAO_UFMatch(); if (CRM_Core_DAO::checkFieldExists('civicrm_uf_match', 'domain_id')) { // FIXME: if() condition check was required especially for upgrade cases (2.2.x -> 3.0.x), // where folks if happen to logout, would encounter a column not found fatal error $ufmatch->domain_id = CRM_Core_Config::domainID(); } $ufmatch->uf_id = $userKey; if (!$ufmatch->find(true)) { require_once 'CRM/Core/Transaction.php'; $transaction = new CRM_Core_Transaction(); if (!empty($_POST)) { $params = $_POST; $params['email'] = $uniqId; require_once 'CRM/Dedupe/Finder.php'; $dedupeParams = CRM_Dedupe_Finder::formatParams($params, 'Individual'); $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual'); if (!empty($ids)) { $dao = new CRM_Core_DAO(); $dao->contact_id = $ids[0]; } } else { require_once 'CRM/Contact/BAO/Contact.php'; if ($uf == 'Standalone') { $dao =& CRM_Contact_BAO_Contact::matchContactOnOpenId($uniqId, $ctype); } else { $dao =& CRM_Contact_BAO_Contact::matchContactOnEmail($uniqId, $ctype); } } if ($dao) { //print "Found contact with uniqId $uniqId<br/>"; $ufmatch->contact_id = $dao->contact_id; $ufmatch->uf_name = $uniqId; } else { if ($uf == 'Drupal') { $mail = 'mail'; } else { $mail = 'email'; } if (is_Object($user)) { $params = array('email-Primary' => $user->{$mail}); } if ($ctype == 'Organization') { $params['organization_name'] = $uniqId; } else { if ($ctype == 'Household') { $params['household_name'] = $uniqId; } } if (!$ctype) { $ctype = "Individual"; } $params['contact_type'] = $ctype; // extract first / middle / last name // for joomla if ($uf == 'Joomla' && $user->name) { require_once 'CRM/Utils/String.php'; CRM_Utils_String::extractName($user->name, $params); } if ($uf == 'Standalone') { $params['openid-Primary'] = $uniqId; //need to delete below code once profile is //exposed on signup page if (!empty($user->first_name) || !empty($user->last_name)) { $params['first_name'] = $user->first_name; $params['last_name'] = $user->last_name; } elseif (!empty($user->name)) { require_once 'CRM/Utils/String.php'; CRM_Utils_String::extractName($user->name, $params); } } $contactId = CRM_Contact_BAO_Contact::createProfileContact($params, CRM_Core_DAO::$_nullArray); $ufmatch->contact_id = $contactId; $ufmatch->uf_name = $uniqId; } $ufmatch->save(); $ufmatch->free(); $newContact = true; $transaction->commit(); } if ($status) { return $newContact; } else { return $ufmatch; } }