/** * 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 */ public function authenticate($obj) { $this->_driver->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); return new QuickBooks_Result_Authenticate('', 'nvu', null, null); } $override_dsn = $this->_config['authenticate_dsn']; $auth = null; if (strlen($override_dsn)) { $parse = QuickBooks_Utilities::parseDSN($override_dsn); $class = 'QuickBooks_Authenticate_' . $parse['scheme']; require_once 'QuickBooks/Authenticate/' . ucfirst(strtolower($parse['scheme'])) . '.php'; $auth = new $class($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 (strlen($override_dsn) and is_object($auth)) { if ($auth->authenticate($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); 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_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); $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_Result_Authenticate($ticket, $status, $wait_before_next_update, $min_run_every_n_seconds); } else { if ($ticket = $this->_driver->authLogin($obj->strUserName, $obj->strPassword, $company_file, $wait_before_next_update, $min_run_every_n_seconds)) { $this->_driver->log('Login: '******'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); $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_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 */ 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: '******')', 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)) { //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 { if ($ticket = $this->_driver->authLogin($obj->strUserName, $obj->strPassword, $company_file, $wait_before_next_update, $min_run_every_n_seconds)) { //$this->_driver->log('Login: '******'Login: '******'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); } }