/**
  * Grant access tokens for basic user credentials.
  *
  * Check the supplied username and password for validity.
  *
  * You can also use the $client_id param to do any checks required based
  * on a client, if you need that.
  *
  * Required for OAuth2::GRANT_TYPE_USER_CREDENTIALS.
  *
  * @param $client_id
  * Client identifier to be check with.
  * @param $username
  * Username to be check with.
  * @param $password
  * Password to be check with.
  *
  * @return
  * TRUE if the username and password are valid, and FALSE if it isn't.
  * Moreover, if the username and password are valid, and you want to
  * verify the scope of a user's access, return an associative array
  * with the scope values as below. We'll check the scope you provide
  * against the requested scope before providing an access token:
  * @code
  * return array(
  * 'scope' => <stored scope values (space-separated string)>,
  * );
  * @endcode
  *
  * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.3
  *
  * @ingroup oauth2_section_4
  */
 public function checkUserCredentials(IOAuth2GrantUser $storage, $client_id, $username, $password)
 {
     $clientInfo = $storage->getClientDetails($client_id);
     if ($clientInfo === false) {
         return false;
     }
     // Is just a regular Sugar User
     $auth = AuthenticationController::getInstance();
     // noHooks since we'll take care of the hooks on API level, to make it more generalized
     $loginSuccess = $auth->login($username, $password, array('passwordEncrypted' => false, 'noRedirect' => true, 'noHooks' => true));
     if ($loginSuccess && !empty($auth->nextStep)) {
         // Set it here, and then load it in to the session on the next pass
         // TODO: How do we pass the next required step to the client via the REST API?
         $GLOBALS['nextStep'] = $auth->nextStep;
     }
     if ($loginSuccess) {
         $this->userBean = $this->loadUserFromName($username);
         return array('user_id' => $this->userBean->id);
     } else {
         if (!empty($_SESSION['login_error'])) {
             $message = $_SESSION['login_error'];
         } else {
             $message = null;
         }
         throw new SugarApiExceptionNeedLogin($message);
     }
 }
 /**
  * Grant access tokens for basic user credentials.
  *
  * Check the supplied username and password for validity.
  *
  * You can also use the $client_id param to do any checks required based
  * on a client, if you need that.
  *
  * Required for OAuth2::GRANT_TYPE_USER_CREDENTIALS.
  *
  * @param $client_id
  * Client identifier to be check with.
  * @param $username
  * Username to be check with.
  * @param $password
  * Password to be check with.
  *
  * @return
  * TRUE if the username and password are valid, and FALSE if it isn't.
  * Moreover, if the username and password are valid, and you want to
  * verify the scope of a user's access, return an associative array
  * with the scope values as below. We'll check the scope you provide
  * against the requested scope before providing an access token:
  * @code
  * return array(
  * 'scope' => <stored scope values (space-separated string)>,
  * );
  * @endcode
  *
  * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-4.3
  *
  * @ingroup oauth2_section_4
  */
 public function checkUserCredentials(IOAuth2GrantUser $storage, $client_id, $username, $password)
 {
     if (empty($username)) {
         return false;
     }
     $clientInfo = $storage->getClientDetails($client_id);
     if ($clientInfo === false) {
         return false;
     }
     $portalApiUser = $this->findPortalApiUser($client_id);
     if ($portalApiUser == null) {
         // Can't login as a portal user if there is no API user
         throw new SugarApiExceptionPortalNotConfigured();
     }
     $contact = $this->loadUserFromName($username);
     if (!empty($contact) && !User::checkPassword($password, $contact->portal_password)) {
         $contact = null;
     }
     if (!empty($contact)) {
         $sessionManager = new SessionManager();
         if (!$sessionManager->canAddSession()) {
             //not able to add another session right now
             $GLOBALS['log']->error("Unable to add new session");
             throw new SugarApiExceptionNeedLogin('too_many_concurrent_connections', array('Too many concurrent sessions'));
         }
         $this->contactBean = $contact;
         if (empty($this->userBean)) {
             $this->userBean = $portalApiUser;
         }
         return array('user_id' => $contact->id);
     } else {
         throw new SugarApiExceptionNeedLogin(translate('ERR_INVALID_PASSWORD', 'Users'));
     }
 }