/**
  * @param $options
  * @param null $access
  * @param bool $bypassAuth
  */
 function processingRequest($options, $access = null, $bypassAuth = false)
 {
     $this->logger->setDebugMessage("[processingRequest]", 2);
     $this->outputOfProcessing = array();
     $currentDir = dirname(__FILE__) . DIRECTORY_SEPARATOR;
     // Message Class Detection
     $messageClass = null;
     if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
         $clientLangArray = explode(',', $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
         foreach ($clientLangArray as $oneLanguage) {
             $langCountry = explode(';', $oneLanguage);
             if (strlen($langCountry[0]) > 0) {
                 $clientLang = explode('-', $langCountry[0]);
                 $messageClass = "MessageStrings_{$clientLang['0']}";
                 if (file_exists("{$currentDir}{$messageClass}.php")) {
                     $messageClass = new $messageClass();
                     break;
                 }
             }
             $messageClass = null;
         }
     }
     if ($messageClass == null) {
         $messageClass = new MessageStrings();
     }
     /* Aggregation Judgement */
     $isSelect = $this->dbSettings->getAggregationSelect();
     $isFrom = $this->dbSettings->getAggregationFrom();
     $isGroupBy = $this->dbSettings->getAggregationGroupBy();
     $isDBSupport = $this->dbClass->isSupportAggregation();
     if (!$isDBSupport && ($isSelect || $isFrom || $isGroupBy)) {
         $this->logger->setErrorMessage($messageClass->getMessageAs(1042));
         $access = "do nothing";
     } else {
         if ($isDBSupport && ($isSelect && !$isFrom || !$isSelect && $isFrom)) {
             $this->logger->setErrorMessage($messageClass->getMessageAs(1043));
             $access = "do nothing";
         } else {
             if ($isDBSupport && $isSelect && $isFrom && in_array($access, array("update", "new", "create", "delete", "copy"))) {
                 $this->logger->setErrorMessage($messageClass->getMessageAs(1044));
                 $access = "do nothing";
             }
         }
     }
     // Authentication and Authorization
     $tableInfo = $this->dbSettings->getDataSourceTargetArray();
     $access = is_null($access) ? $_POST['access'] : $access;
     $access = $access == "select" || $access == "load" ? "read" : $access;
     $clientId = isset($_POST['clientid']) ? $_POST['clientid'] : (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "Non-browser-client");
     $this->paramAuthUser = isset($_POST['authuser']) ? $_POST['authuser'] : "";
     $paramResponse = isset($_POST['response']) ? $_POST['response'] : "";
     $paramCryptResponse = isset($_POST['cresponse']) ? $_POST['cresponse'] : "";
     $this->dbSettings->setRequireAuthentication(false);
     $this->dbSettings->setRequireAuthorization(false);
     $this->dbSettings->setDBNative(false);
     if (isset($options['authentication']) || $access == 'challenge' || $access == 'changepassword' || isset($tableInfo['authentication']) && (isset($tableInfo['authentication']['all']) || isset($tableInfo['authentication'][$access]))) {
         $this->dbSettings->setRequireAuthorization(true);
         $this->dbSettings->setDBNative(false);
         if (isset($options['authentication']['user']) && $options['authentication']['user'][0] == 'database_native') {
             $this->dbSettings->setDBNative(true);
         }
     }
     if (!$bypassAuth && $this->dbSettings->getRequireAuthorization()) {
         // Authentication required
         if (strlen($this->paramAuthUser) == 0 || strlen($paramResponse) == 0) {
             // No username or password
             $access = "do nothing";
             $this->dbSettings->setRequireAuthentication(true);
         }
         // User and Password are suppried but...
         if ($access != 'challenge') {
             // Not accessing getting a challenge.
             if ($this->dbSettings->isDBNative()) {
                 list($password, $challenge) = $this->decrypting($paramCryptResponse);
                 if ($password !== false) {
                     if (!$this->checkChallenge($challenge, $clientId)) {
                         $access = "do nothing";
                         $this->dbSettings->setRequireAuthentication(true);
                     } else {
                         $this->dbSettings->setUserAndPasswordForAccess($this->paramAuthUser, $password);
                         $this->logger->setDebugMessage("[checkChallenge] returns true.", 2);
                     }
                 } else {
                     $this->logger->setDebugMessage("Can't decrypt.");
                     $access = "do nothing";
                     $this->dbSettings->setRequireAuthentication(true);
                 }
             } else {
                 $noAuthorization = true;
                 $authorizedGroups = $this->dbClass->getAuthorizedGroups($access);
                 $authorizedUsers = $this->dbClass->getAuthorizedUsers($access);
                 $this->logger->setDebugMessage(str_replace("\n", "", "contextName={$access}/access={$this->dbSettings->getTargetName()}/" . "authorizedUsers=" . var_export($authorizedUsers, true) . "/authorizedGroups=" . var_export($authorizedGroups, true)), 2);
                 if (count($authorizedUsers) == 0 && count($authorizedGroups) == 0) {
                     $noAuthorization = false;
                 } else {
                     $signedUser = $this->dbClass->authSupportUnifyUsernameAndEmail($this->dbSettings->getCurrentUser());
                     if (in_array($signedUser, $authorizedUsers)) {
                         $noAuthorization = false;
                     } else {
                         if (count($authorizedGroups) > 0) {
                             $belongGroups = $this->dbClass->authSupportGetGroupsOfUser($signedUser);
                             $this->logger->setDebugMessage($signedUser . "=belongGroups=" . var_export($belongGroups, true), 2);
                             if (count(array_intersect($belongGroups, $authorizedGroups)) != 0) {
                                 $noAuthorization = false;
                             }
                         }
                     }
                 }
                 if ($noAuthorization) {
                     $this->logger->setDebugMessage("Authorization doesn't meet the settings.");
                     $access = "do nothing";
                     $this->dbSettings->setRequireAuthentication(true);
                 }
                 $signedUser = $this->dbClass->authSupportUnifyUsernameAndEmail($this->paramAuthUser);
                 $authSucceed = false;
                 if ($this->checkAuthorization($signedUser, $paramResponse, $clientId)) {
                     $this->logger->setDebugMessage("IM-built-in Authentication succeed.");
                     $authSucceed = true;
                 } else {
                     $ldap = new LDAPAuth();
                     $ldap->setLogger($this->logger);
                     if ($ldap->isActive) {
                         list($password, $challenge) = $this->decrypting($paramCryptResponse);
                         if ($ldap->bindCheck($signedUser, $password)) {
                             $this->logger->setDebugMessage("LDAP Authentication succeed.");
                             $authSucceed = true;
                             $this->addUser($signedUser, $password, true);
                         }
                     }
                 }
                 if (!$authSucceed) {
                     $this->logger->setDebugMessage("Authentication doesn't meet valid.{$signedUser}/{$paramResponse}/{$clientId}");
                     // Not Authenticated!
                     $access = "do nothing";
                     $this->dbSettings->setRequireAuthentication(true);
                 }
             }
         }
     }
     // Come here access=challenge or authenticated access
     switch ($access) {
         case 'describe':
             $result = $this->dbClass->getSchema($this->dbSettings->getTargetName());
             $this->outputOfProcessing['dbresult'] = $result;
             $this->outputOfProcessing['resultCount'] = 0;
             $this->outputOfProcessing['totalCount'] = 0;
             break;
         case 'read':
         case 'select':
             $result = $this->getFromDB($this->dbSettings->getTargetName());
             if (isset($tableInfo['protect-reading']) && is_array($tableInfo['protect-reading'])) {
                 $recordCount = count($result);
                 for ($index = 0; $index < $recordCount; $index++) {
                     foreach ($result[$index] as $field => $value) {
                         if (in_array($field, $tableInfo['protect-reading'])) {
                             $result[$index][$field] = "[protected]";
                         }
                     }
                 }
             }
             $this->outputOfProcessing['dbresult'] = $result;
             $this->outputOfProcessing['resultCount'] = $this->countQueryResult($this->dbSettings->getTargetName());
             $this->outputOfProcessing['totalCount'] = $this->getTotalCount($this->dbSettings->getTargetName());
             break;
         case 'update':
             if (isset($tableInfo['protect-writing']) && is_array($tableInfo['protect-writing'])) {
                 $fieldArray = array();
                 $valueArray = array();
                 $counter = 0;
                 $fieldValues = $this->dbSettings->getValue();
                 foreach ($this->dbSettings->getFieldsRequired() as $field) {
                     if (!in_array($field, $tableInfo['protect-writing'])) {
                         $fieldArray[] = $field;
                         $valueArray[] = $fieldValues[$counter];
                     }
                     $counter++;
                 }
                 $this->dbSettings->setTargetFields($fieldArray);
                 $this->dbSettings->setValue($valueArray);
             }
             $this->setToDB($this->dbSettings->getTargetName());
             break;
         case 'new':
         case 'create':
             $result = $this->newToDB($this->dbSettings->getTargetName(), $bypassAuth);
             $this->outputOfProcessing['newRecordKeyValue'] = $result;
             $this->outputOfProcessing['dbresult'] = $this->dbClass->updatedRecord();
             break;
         case 'delete':
             $this->deleteFromDB($this->dbSettings->getTargetName());
             break;
         case 'copy':
             $result = $this->copyInDB($this->dbSettings->getTargetName());
             $this->outputOfProcessing['newRecordKeyValue'] = $result;
             $this->outputOfProcessing['dbresult'] = $this->dbClass->updatedRecord();
             break;
         case 'challenge':
             break;
         case 'changepassword':
             if (isset($_POST['newpass'])) {
                 $changeResult = $this->changePassword($this->paramAuthUser, $_POST['newpass']);
                 $this->outputOfProcessing['changePasswordResult'] = $changeResult ? true : false;
             } else {
                 $this->outputOfProcessing['changePasswordResult'] = false;
             }
             break;
         case 'unregister':
             if (!is_null($this->dbSettings->notifyServer) && $this->clientPusherAvailable) {
                 $tableKeys = null;
                 if (isset($_POST['pks'])) {
                     $tableKeys = json_decode($_POST['pks'], true);
                 }
                 $this->dbSettings->notifyServer->unregister($_POST['notifyid'], $tableKeys);
             }
             break;
     }
     if ($this->logger->getDebugLevel() !== false) {
         $fInfo = $this->getFieldInfo($this->dbSettings->getTargetName());
         if ($fInfo != null) {
             foreach ($this->dbSettings->getFieldsRequired() as $fieldName) {
                 if (!$this->dbClass->isContainingFieldName($fieldName, $fInfo)) {
                     $this->logger->setErrorMessage($messageClass->getMessageAs(1033, array($fieldName)));
                 }
             }
         }
     }
 }
 /**
  * @param $options
  * @param null $access
  * @param bool $bypassAuth
  */
 function processingRequest($options, $access = null, $bypassAuth = false)
 {
     $this->logger->setDebugMessage("[processingRequest]", 2);
     $this->outputOfPrcessing = '';
     $generatedPrivateKey = '';
     $passPhrase = '';
     $currentDir = dirname(__FILE__) . DIRECTORY_SEPARATOR;
     $currentDirParam = $currentDir . 'params.php';
     $parentDirParam = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'params.php';
     if (file_exists($parentDirParam)) {
         include $parentDirParam;
     } else {
         if (file_exists($currentDirParam)) {
             include $currentDirParam;
         }
     }
     $messageClass = null;
     if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
         $clientLangArray = explode(',', $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
         foreach ($clientLangArray as $oneLanguage) {
             $langCountry = explode(';', $oneLanguage);
             if (strlen($langCountry[0]) > 0) {
                 $clientLang = explode('-', $langCountry[0]);
                 $messageClass = "MessageStrings_{$clientLang['0']}";
                 if (file_exists("{$currentDir}{$messageClass}.php")) {
                     $messageClass = new $messageClass();
                     break;
                 }
             }
             $messageClass = null;
         }
     }
     if ($messageClass == null) {
         $messageClass = new MessageStrings();
     }
     $tableInfo = $this->dbSettings->getDataSourceTargetArray();
     $access = is_null($access) ? $_POST['access'] : $access;
     $clientId = isset($_POST['clientid']) ? $_POST['clientid'] : (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "Non-browser-client");
     $this->paramAuthUser = isset($_POST['authuser']) ? $_POST['authuser'] : "";
     $paramResponse = isset($_POST['response']) ? $_POST['response'] : "";
     $this->dbSettings->setRequireAuthentication(false);
     $this->dbSettings->setRequireAuthorization(false);
     $this->dbSettings->setDBNative(false);
     $keywordAuth = $access == "select" ? "load" : $access;
     if (isset($options['authentication']) || $access == 'challenge' || $access == 'changepassword' || isset($tableInfo['authentication']) && (isset($tableInfo['authentication']['all']) || isset($tableInfo['authentication'][$keywordAuth]))) {
         $this->dbSettings->setRequireAuthorization(true);
         $this->dbSettings->setDBNative(false);
         if (isset($options['authentication']['user']) && $options['authentication']['user'][0] == 'database_native') {
             $this->dbSettings->setDBNative(true);
         }
     }
     //        $this->logger->setDebugMessage("dbNative={$this->dbSettings->isDBNative()}", 2);
     //        $this->logger->setDebugMessage("", 2);
     if (!$bypassAuth && $this->dbSettings->getRequireAuthorization()) {
         // Authentication required
         if (strlen($this->paramAuthUser) == 0 || strlen($paramResponse) == 0) {
             // No username or password
             $access = "do nothing";
             $this->dbSettings->setRequireAuthentication(true);
         }
         // User and Password are suppried but...
         if ($access != 'challenge') {
             // Not accessing getting a challenge.
             if ($this->dbSettings->isDBNative()) {
                 $rsa = new Crypt_RSA();
                 $rsa->setPassword($passPhrase);
                 $rsa->loadKey($generatedPrivateKey);
                 $rsa->setPassword();
                 $privatekey = $rsa->getPrivateKey();
                 $priv = $rsa->_parseKey($privatekey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
                 require_once 'bi2php/biRSA.php';
                 $keyDecrypt = new biRSAKeyPair('0', $priv['privateExponent']->toHex(), $priv['modulus']->toHex());
                 $decrypted = $keyDecrypt->biDecryptedString($paramResponse);
                 //                    $this->logger->setDebugMessage("decrypted={$decrypted}", 2);
                 if ($decrypted !== false) {
                     $nlPos = strpos($decrypted, "\n");
                     $nlPos = $nlPos === false ? strlen($decrypted) : $nlPos;
                     $password = $keyDecrypt->biDecryptedString(substr($decrypted, 0, $nlPos));
                     $password = strlen($password) == 0 ? "f32b309d4759446fc81de858322ed391a0c167a0" : $password;
                     $challenge = substr($decrypted, $nlPos + 1);
                     //                        $this->logger->setDebugMessage("password={$password}", 2);
                     //                        $this->logger->setDebugMessage("paramAuthUser={$this->paramAuthUser}", 2);
                     if (!$this->checkChallenge($challenge, $clientId)) {
                         $access = "do nothing";
                         $this->dbSettings->setRequireAuthentication(true);
                     } else {
                         $this->dbSettings->setUserAndPasswordForAccess($this->paramAuthUser, $password);
                         $this->logger->setDebugMessage("[checkChallenge] returns true.", 2);
                     }
                 } else {
                     $this->logger->setDebugMessage("Can't decrypt.");
                     $access = "do nothing";
                     $this->dbSettings->setRequireAuthentication(true);
                 }
             } else {
                 $noAuthorization = true;
                 $authorizedGroups = $this->dbClass->getAuthorizedGroups($access);
                 $authorizedUsers = $this->dbClass->getAuthorizedUsers($access);
                 $this->logger->setDebugMessage("authorizedUsers=" . var_export($authorizedUsers, true) . "/authorizedGroups=" . var_export($authorizedGroups, true), 2);
                 if (count($authorizedUsers) == 0 && count($authorizedGroups) == 0) {
                     $noAuthorization = false;
                 } else {
                     $signedUser = $this->dbClass->authSupportUnifyUsernameAndEmail($this->dbSettings->getCurrentUser());
                     if (in_array($signedUser, $authorizedUsers)) {
                         $noAuthorization = false;
                     } else {
                         if (count($authorizedGroups) > 0) {
                             $belongGroups = $this->dbClass->authSupportGetGroupsOfUser($signedUser);
                             $this->logger->setDebugMessage($signedUser . "=belongGroups=" . var_export($belongGroups, true), 2);
                             if (count(array_intersect($belongGroups, $authorizedGroups)) != 0) {
                                 $noAuthorization = false;
                             }
                         }
                     }
                 }
                 if ($noAuthorization) {
                     $this->logger->setDebugMessage("Authorization doesn't meet the settings.");
                     $access = "do nothing";
                     $this->dbSettings->setRequireAuthentication(true);
                 }
                 $signedUser = $this->dbClass->authSupportUnifyUsernameAndEmail($this->paramAuthUser);
                 if (!$this->checkAuthorization($signedUser, $paramResponse, $clientId)) {
                     $this->logger->setDebugMessage("Authentication doesn't meet valid.{$signedUser}/{$paramResponse}/{$clientId}");
                     // Not Authenticated!
                     $access = "do nothing";
                     $this->dbSettings->setRequireAuthentication(true);
                 }
             }
         }
     }
     //        $this->logger->setDebugMessage("requireAuthentication={$this->dbSettings->getRequireAuthentication()}", 2);
     //        $this->logger->setDebugMessage("requireAuthorization={$this->dbSettings->getRequireAuthorization()}", 2);
     //        $this->logger->setDebugMessage("access={$access}, target={$this->dbSettings->getTargetName()}", 2);
     // Come here access=challenge or authenticated access
     switch ($access) {
         case 'describe':
             $result = $this->dbClass->getSchema($this->dbSettings->getTargetName());
             $this->outputOfPrcessing = 'dbresult=' . arrayToJS($result, '') . ';' . "resultCount=0;";
             break;
         case 'select':
             $result = $this->getFromDB($this->dbSettings->getTargetName());
             if (isset($tableInfo['protect-reading']) && is_array($tableInfo['protect-reading'])) {
                 $recordCount = count($result);
                 for ($index = 0; $index < $recordCount; $index++) {
                     foreach ($result[$index] as $field => $value) {
                         if (in_array($field, $tableInfo['protect-reading'])) {
                             $result[$index][$field] = "[protected]";
                         }
                     }
                 }
             }
             $this->outputOfPrcessing = 'dbresult=' . arrayToJS($result, '') . ';' . "resultCount='{$this->countQueryResult($this->dbSettings->getTargetName())}';";
             break;
         case 'update':
             if (isset($tableInfo['protect-writing']) && is_array($tableInfo['protect-writing'])) {
                 $fieldArray = array();
                 $valueArray = array();
                 $counter = 0;
                 $fieldValues = $this->dbSettings->getValue();
                 foreach ($this->dbSettings->getFieldsRequired() as $field) {
                     if (!in_array($field, $tableInfo['protect-writing'])) {
                         $fieldArray[] = $field;
                         $valueArray[] = $fieldValues[$counter];
                     }
                     $counter++;
                 }
                 $this->dbSettings->setTargetFields($fieldArray);
                 $this->dbSettings->setValue($valueArray);
             }
             $this->setToDB($this->dbSettings->getTargetName());
             break;
         case 'new':
             $result = $this->newToDB($this->dbSettings->getTargetName(), $bypassAuth);
             $this->outputOfPrcessing = "newRecordKeyValue='{$result}';";
             break;
         case 'delete':
             $this->deleteFromDB($this->dbSettings->getTargetName());
             break;
         case 'challenge':
             break;
         case 'changepassword':
             if (isset($_POST['newpass'])) {
                 $changeResult = $this->changePassword($this->paramAuthUser, $_POST['newpass']);
                 $this->outputOfPrcessing = "changePasswordResult=" . ($changeResult ? "true;" : "false;");
             } else {
                 $this->outputOfPrcessing = "changePasswordResult=false;";
             }
             break;
     }
     //        $this->logger->setDebugMessage("requireAuthentication={$this->dbSettings->getRequireAuthentication()}", 2);
     //        $this->logger->setDebugMessage("requireAuthorization={$this->dbSettings->getRequireAuthorization()}", 2);
     if ($this->logger->getDebugLevel() !== false) {
         $fInfo = $this->getFieldInfo($this->dbSettings->getTargetName());
         if ($fInfo != null) {
             foreach ($this->dbSettings->getFieldsRequired() as $fieldName) {
                 if (!in_array($fieldName, $fInfo)) {
                     $this->logger->setErrorMessage($messageClass->getMessageAs(1033, array($fieldName)));
                 }
             }
         }
     }
 }