QuickBooks/WebConnector/Handlers.php
public function authenticate($obj)
	{
		//$this->_driver->log('authenticate()', '', QUICKBOOKS_LOG_VERBOSE);
		$this->_log('authenticate()', '', QUICKBOOKS_LOG_VERBOSE);

		$ticket = '';
		$status = '';

		// Authenticate login hook
		$hookdata = array(
			'username' => $obj->strUserName,
			'password' => $obj->strPassword,
			);
		$hookerr = '';
		$this->_callHook($ticket, QUICKBOOKS_HANDLERS_HOOK_AUTHENTICATE, null, null, null, null, $hookerr, null, array(), $hookdata);

		// Remote address allow/deny
		if (false == $this->_checkRemote($_SERVER['REMOTE_ADDR'], $this->_config['allow_remote_addr'], $this->_config['deny_remote_addr']))
		{
			//$this->_driver->log('Connection from remote address rejected: ' . $_SERVER['REMOTE_ADDR'], null, QUICKBOOKS_LOG_VERBOSE);
			$this->_log('Connection from remote address rejected: ' . $_SERVER['REMOTE_ADDR'], null, QUICKBOOKS_LOG_VERBOSE);

			return new QuickBooks_WebConnector_Result_Authenticate('', 'nvu', null, null);
		}

		// If we do either concurrent login checks, or rate-limiting, we need to grab the date/time
		//	of the last connection.
		$authLast = null;
		if ($this->_config['deny_concurrent_logins'] or $this->_config['deny_reallyfast_logins'])
		{
			$authlast = $this->_driver->authLast($obj->strUserName);
		}

		// Check for concurrent logins
		if ($this->_config['deny_concurrent_logins'])
		{
			if ($authlast and
				time() - strtotime($authlast[1]) < $this->_config['deny_concurrent_timeout'])
			{
				$this->_log('Denied concurrent login from: ' . $obj->strUserName, null, QUICKBOOKS_LOG_VERBOSE);

				return new QuickBooks_WebConnector_Result_Authenticate('CONC1234', 'none', null, null);
			}
		}

		// Rate-limiting
		if ($this->_config['deny_reallyfast_logins'])
		{
			if ($authlast and
				time() - strtotime($authlast[1]) < $this->_config['deny_reallyfast_timeout'])
			{
				$this->_log('Denied really fast login from: ' . $obj->strUserName . ' (last login: ' . $authlast[1] . ')', null, QUICKBOOKS_LOG_VERBOSE);

				return new QuickBooks_WebConnector_Result_Authenticate('FAST1234', 'none', null, null);
			}
		}

		// Custom authentication backends
		$override_dsn = $this->_config['authenticate'];

		if (!empty($this->_config['authenticate_dsn']))
		{
			// Backwards compat.
			$override_dsn = $this->_config['authenticate_dsn'];
		}

		$auth = null;

		/*
		if (strlen($override_dsn))
		{
			$override_dsn = str_replace('function://', '', $override_dsn);
		}
		*/

		$company_file = null;
		$wait_before_next_update = null;
		$min_run_every_n_seconds = null;

		$customauth_company_file = null;
		$customauth_wait_before_next_update = null;
		$customauth_min_run_every_n_seconds = null;

		if (is_array($override_dsn) or strlen($override_dsn)) 	// Custom autj
		{
			//if ($auth->authenticate($obj->strUserName, $obj->strPassword, $customauth_company_file, $customauth_wait_before_next_update, $customauth_min_run_every_n_seconds) and

			//if ($override_dsn($obj->strUserName, $obj->strPassword, $customauth_company_file, $customauth_wait_before_next_update, $customauth_min_run_every_n_seconds) and

			if (QuickBooks_Callbacks::callAuthenticate($this->_driver, $override_dsn, $obj->strUserName, $obj->strPassword, $customauth_company_file, $customauth_wait_before_next_update, $customauth_min_run_every_n_seconds) and
				$ticket = $this->_driver->authLogin($obj->strUserName, $obj->strPassword, $company_file, $wait_before_next_update, $min_run_every_n_seconds, true))
			{
				//$this->_driver->log('Login (' . $parse['scheme'] . '): ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login via ' . print_r($override_dsn, true) . ': ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);

				if ($customauth_company_file)
				{
					$status = $customauth_company_file;
				}
				else if ($company_file)
				{
					$status = $company_file;
				}
				else if ($this->_config['qb_company_file'])
				{
					$status = $this->_config['qb_company_file'];
				}

				if ((int) $customauth_wait_before_next_update)
				{
					$wait_before_next_update = (int) $customauth_wait_before_next_update;
				}
				else if ((int) $wait_before_next_update)
				{
					;
				}
				else if ((int) $this->_config['qbwc_wait_before_next_update'])
				{
					$wait_before_next_update = (int) $this->_config['qbwc_wait_before_next_update'];
				}

				if ((int) $customauth_min_run_every_n_seconds)
				{
					$min_run_every_n_seconds = (int) $customauth_min_run_every_n_seconds;
				}
				else if ((int) $min_run_every_n_seconds)
				{
					;
				}
				else if ((int) $this->_config['qbwc_min_run_every_n_seconds'])
				{
					$min_run_every_n_seconds = (int) $this->_config['qbwc_min_run_every_n_seconds'];
				}

				// Call login hook
				$hookdata = array(
					'authenticate_dsn' => $override_dsn,
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					'ticket' => $ticket,
					'qb_company_file' => $status,
					'qbwc_wait_before_next_update' => $wait_before_next_update,
					'qbwc_min_run_every_n_seconds' => $min_run_every_n_seconds,
					);
				$hookerr = '';
				$this->_callHook($ticket, QuickBooks_WebConnector_Handlers::HOOK_LOGINSUCCESS, null, null, null, null, $hookerr, null, array(), $hookdata);

				// Move any recurring events that are due to the queue table
				$this->_handleRecurringEvents($ticket);

				if (!$this->_driver->queueDequeue($obj->strUserName))
				{
					$status = 'none';
				}

				// Login success (with a custom login handler)!
			}
			else
			{
				//$this->_driver->log('Login failed (' . $parse['scheme'] . '): ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login failed: ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);

				$hookdata = array(
					'authenticate_dsn' => $override_dsn,
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					);
				$hookerr = '';
				$this->_callHook(null, QUICKBOOKS_HANDLERS_HOOK_LOGINFAILURE, null, null, null, null, $hookerr, null, array(), $hookdata);

				$ticket = '';
				$status = 'nvu'; // Invalid username/password
			}

			return new QuickBooks_WebConnector_Result_Authenticate($ticket, $status, $wait_before_next_update, $min_run_every_n_seconds);
		}
		else	// Standard authentication
		{
			if ($ticket = $this->_driver->authLogin($obj->strUserName, $obj->strPassword, $company_file, $wait_before_next_update, $min_run_every_n_seconds))
			{
				//$this->_driver->log('Login: ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login: ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);

				if (!strlen($company_file) and $this->_config['qb_company_file'])
				{
					$status = $this->_config['qb_company_file'];
				}
				else if (strlen($company_file))
				{
					$status = $company_file;
				}

				if (! (int) $wait_before_next_update and (int) $this->_config['qbwc_wait_before_next_update'])
				{
					$wait_before_next_update = (int) $this->_config['qbwc_wait_before_next_update'];
				}

				if (! (int) $min_run_every_n_seconds and (int) $this->_config['qbwc_min_run_every_n_seconds'])
				{
					$min_run_every_n_seconds = (int) $this->_config['qbwc_min_run_every_n_seconds'];
				}

				$hookdata = array(
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					'ticket' => $ticket,
					'qb_company_file' => $status,
					'qbwc_wait_before_next_update' => $wait_before_next_update,
					'qbwc_min_run_every_n_seconds' => $min_run_every_n_seconds,
					);
				$hookerr = '';
				$this->_callHook($ticket, QUICKBOOKS_HANDLERS_HOOK_LOGINSUCCESS, null, null, null, null, $hookerr, null, array(), $hookdata);

				$this->_handleRecurringEvents($ticket);

				if (!$this->_driver->queueDequeue($obj->strUserName))
				{
					$status = 'none'; // Good login, but there isn't anything in the queue
				}

				// Login success!
			}
			else
			{
				//$this->_driver->log('Login failed: ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login failed: ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);

				$hookdata = array(
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					);
				$hookerr = '';
				$this->_callHook(null, QUICKBOOKS_HANDLERS_HOOK_LOGINFAILURE, null, null, null, null, $hookerr, null, array(), $hookdata);

				$ticket = '';
				$status = 'nvu'; // Invalid username/password
			}

			return new QuickBooks_WebConnector_Result_Authenticate($ticket, $status, $wait_before_next_update, $min_run_every_n_seconds);
		}
	}
public function authenticate($obj)
	{
		//$this->_driver->log('authenticate()', '', QUICKBOOKS_LOG_VERBOSE);
		$this->_log('authenticate()', '', QUICKBOOKS_LOG_VERBOSE);

		$ticket = '';
		$status = '';

		// Authenticate login hook
		$hookdata = array(
			'username' => $obj->strUserName,
			'password' => $obj->strPassword,
			);
		$hookerr = '';
		$this->_callHook($ticket, QUICKBOOKS_HANDLERS_HOOK_AUTHENTICATE, null, null, null, null, $hookerr, null, array(), $hookdata);

		// Remote address allow/deny
		if (false == $this->_checkRemote($_SERVER['REMOTE_ADDR'], $this->_config['allow_remote_addr'], $this->_config['deny_remote_addr']))
		{
			//$this->_driver->log('Connection from remote address rejected: ' . $_SERVER['REMOTE_ADDR'], null, QUICKBOOKS_LOG_VERBOSE);
			$this->_log('Connection from remote address rejected: ' . $_SERVER['REMOTE_ADDR'], null, QUICKBOOKS_LOG_VERBOSE);

			return new QuickBooks_WebConnector_Result_Authenticate('', 'nvu', null, null);
		}

		// If we do either concurrent login checks, or rate-limiting, we need to grab the date/time
		//	of the last connection.
		$authLast = null;
		if ($this->_config['deny_concurrent_logins'] or $this->_config['deny_reallyfast_logins'])
		{
			$authlast = $this->_driver->authLast($obj->strUserName);
		}

		// Check for concurrent logins
		if ($this->_config['deny_concurrent_logins'])
		{
			if ($authlast and
				time() - strtotime($authlast[1]) < $this->_config['deny_concurrent_timeout'])
			{
				$this->_log('Denied concurrent login from: ' . $obj->strUserName, null, QUICKBOOKS_LOG_VERBOSE);

				return new QuickBooks_WebConnector_Result_Authenticate('CONC1234', 'none', null, null);
			}
		}

		// Rate-limiting
		if ($this->_config['deny_reallyfast_logins'])
		{
			if ($authlast and
				time() - strtotime($authlast[1]) < $this->_config['deny_reallyfast_timeout'])
			{
				$this->_log('Denied really fast login from: ' . $obj->strUserName . ' (last login: ' . $authlast[1] . ')', null, QUICKBOOKS_LOG_VERBOSE);

				return new QuickBooks_WebConnector_Result_Authenticate('FAST1234', 'none', null, null);
			}
		}

		// Custom authentication backends
		$override_dsn = $this->_config['authenticate'];

		if (!empty($this->_config['authenticate_dsn']))
		{
			// Backwards compat.
			$override_dsn = $this->_config['authenticate_dsn'];
		}

		$auth = null;

		/*
		if (strlen($override_dsn))
		{
			$override_dsn = str_replace('function://', '', $override_dsn);
		}
		*/

		$company_file = null;
		$wait_before_next_update = null;
		$min_run_every_n_seconds = null;

		$customauth_company_file = null;
		$customauth_wait_before_next_update = null;
		$customauth_min_run_every_n_seconds = null;

		if (is_array($override_dsn) or strlen($override_dsn)) 	// Custom autj
		{
			//if ($auth->authenticate($obj->strUserName, $obj->strPassword, $customauth_company_file, $customauth_wait_before_next_update, $customauth_min_run_every_n_seconds) and

			//if ($override_dsn($obj->strUserName, $obj->strPassword, $customauth_company_file, $customauth_wait_before_next_update, $customauth_min_run_every_n_seconds) and

			if (QuickBooks_Callbacks::callAuthenticate($this->_driver, $override_dsn, $obj->strUserName, $obj->strPassword, $customauth_company_file, $customauth_wait_before_next_update, $customauth_min_run_every_n_seconds) and
				$ticket = $this->_driver->authLogin($obj->strUserName, $obj->strPassword, $company_file, $wait_before_next_update, $min_run_every_n_seconds, true))
			{
				//$this->_driver->log('Login (' . $parse['scheme'] . '): ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login via ' . print_r($override_dsn, true) . ': ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);

				if ($customauth_company_file)
				{
					$status = $customauth_company_file;
				}
				else if ($company_file)
				{
					$status = $company_file;
				}
				else if ($this->_config['qb_company_file'])
				{
					$status = $this->_config['qb_company_file'];
				}

				if ((int) $customauth_wait_before_next_update)
				{
					$wait_before_next_update = (int) $customauth_wait_before_next_update;
				}
				else if ((int) $wait_before_next_update)
				{
					;
				}
				else if ((int) $this->_config['qbwc_wait_before_next_update'])
				{
					$wait_before_next_update = (int) $this->_config['qbwc_wait_before_next_update'];
				}

				if ((int) $customauth_min_run_every_n_seconds)
				{
					$min_run_every_n_seconds = (int) $customauth_min_run_every_n_seconds;
				}
				else if ((int) $min_run_every_n_seconds)
				{
					;
				}
				else if ((int) $this->_config['qbwc_min_run_every_n_seconds'])
				{
					$min_run_every_n_seconds = (int) $this->_config['qbwc_min_run_every_n_seconds'];
				}

				// Call login hook
				$hookdata = array(
					'authenticate_dsn' => $override_dsn,
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					'ticket' => $ticket,
					'qb_company_file' => $status,
					'qbwc_wait_before_next_update' => $wait_before_next_update,
					'qbwc_min_run_every_n_seconds' => $min_run_every_n_seconds,
					);
				$hookerr = '';
				$this->_callHook($ticket, QuickBooks_WebConnector_Handlers::HOOK_LOGINSUCCESS, null, null, null, null, $hookerr, null, array(), $hookdata);

				// Move any recurring events that are due to the queue table
				$this->_handleRecurringEvents($ticket);

				if (!$this->_driver->queueDequeue($obj->strUserName))
				{
					$status = 'none';
				}

				// Login success (with a custom login handler)!
			}
			else
			{
				//$this->_driver->log('Login failed (' . $parse['scheme'] . '): ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login failed: ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);

				$hookdata = array(
					'authenticate_dsn' => $override_dsn,
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					);
				$hookerr = '';
				$this->_callHook(null, QUICKBOOKS_HANDLERS_HOOK_LOGINFAILURE, null, null, null, null, $hookerr, null, array(), $hookdata);

				$ticket = '';
				$status = 'nvu'; // Invalid username/password
			}

			return new QuickBooks_WebConnector_Result_Authenticate($ticket, $status, $wait_before_next_update, $min_run_every_n_seconds);
		}
		else	// Standard authentication
		{
			if ($ticket = $this->_driver->authLogin($obj->strUserName, $obj->strPassword, $company_file, $wait_before_next_update, $min_run_every_n_seconds))
			{
				//$this->_driver->log('Login: ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login: ' . $obj->strUserName, $ticket, QUICKBOOKS_LOG_DEBUG);

				if (!strlen($company_file) and $this->_config['qb_company_file'])
				{
					$status = $this->_config['qb_company_file'];
				}
				else if (strlen($company_file))
				{
					$status = $company_file;
				}

				if (! (int) $wait_before_next_update and (int) $this->_config['qbwc_wait_before_next_update'])
				{
					$wait_before_next_update = (int) $this->_config['qbwc_wait_before_next_update'];
				}

				if (! (int) $min_run_every_n_seconds and (int) $this->_config['qbwc_min_run_every_n_seconds'])
				{
					$min_run_every_n_seconds = (int) $this->_config['qbwc_min_run_every_n_seconds'];
				}

				$hookdata = array(
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					'ticket' => $ticket,
					'qb_company_file' => $status,
					'qbwc_wait_before_next_update' => $wait_before_next_update,
					'qbwc_min_run_every_n_seconds' => $min_run_every_n_seconds,
					);
				$hookerr = '';
				$this->_callHook($ticket, QUICKBOOKS_HANDLERS_HOOK_LOGINSUCCESS, null, null, null, null, $hookerr, null, array(), $hookdata);

				$this->_handleRecurringEvents($ticket);

				if (!$this->_driver->queueDequeue($obj->strUserName))
				{
					$status = 'none'; // Good login, but there isn't anything in the queue
				}

				// Login success!
			}
			else
			{
				//$this->_driver->log('Login failed: ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);
				$this->_log('Login failed: ' . $obj->strUserName, '', QUICKBOOKS_LOG_DEBUG);

				$hookdata = array(
					'username' => $obj->strUserName,
					'password' => $obj->strPassword,
					);
				$hookerr = '';
				$this->_callHook(null, QUICKBOOKS_HANDLERS_HOOK_LOGINFAILURE, null, null, null, null, $hookerr, null, array(), $hookdata);

				$ticket = '';
				$status = 'nvu'; // Invalid username/password
			}

			return new QuickBooks_WebConnector_Result_Authenticate($ticket, $status, $wait_before_next_update, $min_run_every_n_seconds);
		}
	}
Authenticate method for the QuickBooks Web Connector SOAP service

The authenticate method is called when the Web Connector establishes a
connection with the SOAP server in order to ensure that there is work to
do and that the Web Connector is allowed to connect/that it actually is
the Web Connector that is connecting and sending us messages.

The stdClass object that is received as a parameter will have two
members:
- strUserName	The username provided in the QWC file to the Web Connector
- strPassword 	The password the end-user enters into the QuickBooks Web Connector application

The return object should be an array with two elements. The first
element is a generated login ticket (or an empty string if the login
failed) and the second string is either "none" (for successful log-ins
with nothing to do in the queue) or "nvu" if the login failed.

The following user-defined hooks are invoked:
- QUICKBOOKS_HANDLERS_HOOK_AUTHENTICATE
- QUICKBOOKS_HANDLERS_HOOK_LOGINSUCCESS
- QUICKBOOKS_HANDLERS_HOOK_LOGINFAILURE

@param stdClass $obj						The SOAP object that gets sent by the Web Connector
@return QuickBooks_Result_Authenticate	A container object to send back to the Web Connector