/**
  * This is the authenticate method where we check the X-Hash header from the client against
  * a hash that we will recreate here on the server. If the 2 match, it's a pass.
  *
  * @param String $public_key
  * @return boolean If success or not
  */
 public function authenticate($public_key)
 {
     //get request and X-Hash HTTP header
     $request = $this->app->request();
     $contentHash = $request->headers('X-Hash');
     $oUser = new User();
     $user = $oUser->getUserByPublicKey($public_key);
     //get private key for hashing
     $private_key = $oUser->getPrivateKey($user['LoginID']);
     //get HTTP request body for hashing
     $requestBody = $request->getBody();
     //hash the body and clientside timestamp and our private key from the user
     $hash = hash_hmac('sha256', $requestBody, $private_key);
     //if they match, the request is valid.
     if (md5($contentHash) === md5($hash)) {
         Log::write("authenticated for " . strtoupper($request->getMethod()) . "/" . $request->getPath(), $user['username']);
         return TRUE;
     } else {
         Log::write("Hashes do not match.", $user['username']);
         Log::write("Clienthash: " . $contentHash, $user['username']);
         Log::write("Serverhash: " . $hash, $user['username']);
         return FALSE;
     }
 }
        $body = $app->request()->getBody();
        $request = json_decode($body, true);
        $response = array();
        $intervID = $request['IntervID'];
        $action = $request['Action'];
        $date_action = $request['Date_action'];
        $time = $request['Time'];
        //read user db and name from request
        $userdb = R::readDbFromRequest();
        $by_user = R::readUsernameFromRequest();
        //add work
        $oIntervention = new Intervention($userdb);
        $workId = $oIntervention->addWork($intervID, $action, $date_action, $time, $by_user);
        //read old total work
        $oldTotalWork = $oIntervention->getTotalWork($intervID);
        //update new total work as hours (not as minutes)
        $newTotalWork = $oldTotalWork + $time / 60;
        $InUpdated = $oIntervention->updateInterventionWork($intervID, $newTotalWork, $by_user);
        if ($workId != NULL & $InUpdated) {
            $response["error"] = false;
            $response["message"] = "Intervention work created";
            Log::write("Intervention work with ID " . $workId . " created successfully.", $by_user);
            R::echoResponse(201, $response);
        } else {
            $response["error"] = true;
            $response["message"] = "Could not create intervention work";
            Log::write("Failed to create new intervention work.", $by_user);
            R::echoResponse(500, $response);
        }
    });
});
        $request = $app->request();
        $public_key = $request->headers('X-PublicKey');
        //get User array from sent public key
        $user = $oUser->getUserByPublicKey($public_key);
        $userdb = $oUser->setDefaultDatabase($user['LoginID']);
        //get access level string of user
        $access_level = $oUser->getAccessLevel($user['LoginID']);
        //create new instance with the user specific database
        $tempTool = new DbExport($userdb);
        //read relevant table names with the user specific access level
        $export = $tempTool->readRelevantTables($access_level);
        $app->contentType('application/json;charset=utf-8');
        echo json_encode($export);
    });
    /**
     * GET route to export database meta information to JSON
     *
     */
    $app->get('/database/scheme', function () use($app) {
        $userdb = R::readDbFromRequest();
        $by_user = R::readUsernameFromRequest();
        $tempTool = new DbExport($userdb);
        //read metainformation of tables
        $export = $tempTool->readRelevantTablesMetaInformation($userdb);
        if (!isset($export)) {
            Log::write("The user's DefaultDB does not exist on the server!", $by_user);
        }
        $app->contentType('application/json;charset=utf-8');
        echo json_encode($export);
    });
});
 /**
  * deletes a request with a requestID on a users DB.
  *
  * @param $userdb
  * @param $requestId
  * @return bool
  */
 public function deleteRequest($userdb, $requestId)
 {
     $username = RequestHelper::readUsernameFromRequest();
     //control variable
     $all_query_ok = true;
     //disable autocommit so commit/rollback is possible
     $this->core->dbh->autocommit(false);
     // select all intervention IDs with the specified RequestID as an array
     if ($stmt = $this->core->dbh->query("SELECT IntervID FROM intervention WHERE Request_id = '" . $requestId . "'")) {
         $row = $stmt->fetch_row();
         $stmt->close();
     } else {
         $all_query_ok = false;
     }
     if (!$all_query_ok) {
         LogHelper::write("select intervid failed", $username);
     }
     //skip deleting intervention work and material if no interventions are in the DB
     //delete from intervention_material and intervention_work
     if (!empty($row)) {
         $oIntervention = new Intervention($userdb);
         foreach ($row as $intervID) {
             $all_query_ok &= $oIntervention->deleteInterventionMaterial($intervID);
             $all_query_ok &= $oIntervention->deleteInterventionWork($intervID);
         }
     }
     //delete from interventions
     $this->core->dbh->query("DELETE FROM intervention WHERE Request_id = '" . $requestId . "'") ? false : ($all_query_ok = false);
     if (!$all_query_ok) {
         LogHelper::write("delete intervention failed", $username);
     }
     //delete from requests
     $this->core->dbh->query("DELETE FROM request WHERE Request_id = '" . $requestId . "'") ? false : ($all_query_ok = false);
     if (!$all_query_ok) {
         LogHelper::write("delete request failed", $username);
     }
     // commit or rollback
     if ($all_query_ok) {
         $this->core->dbh->commit();
         $this->core->dbh->close();
         return TRUE;
     } else {
         $this->core->dbh->rollback();
         $this->core->dbh->close();
         return FALSE;
     }
 }
    });
    /**
     * DELETE route for deleting request
     *
     */
    $app->delete('/request/:requestid', function ($requestId) use($app) {
        $userdb = R::readDbFromRequest();
        $by_user = R::readUsernameFromRequest();
        $oReq = new Request($userdb);
        //check if asset exists, if not, throw 404 error.
        $exists = $oReq->checkIfRequestExists($requestId);
        if (!$exists) {
            $response["error"] = true;
            $response["message"] = "Request does not exist";
            R::echoResponse(404, $response);
        } else {
            $result = $oReq->deleteRequest($userdb, $requestId);
            if ($result) {
                $response["error"] = false;
                $response["message"] = "Request deleted";
                Log::write("Request " . $requestId . " deleted.", $by_user);
                R::echoResponse(200, $response);
            } else {
                $response["error"] = true;
                $response["message"] = "Could not delete request";
                Log::write("Could not delete Request " . $requestId . " - Possible failures on deleting associated interventions/intervention_work/_material", $by_user);
                R::echoResponse(500, $response);
            }
        }
    });
});
    });
    /**
     * DELETE route for deleting asset
     *
     */
    $app->delete('/asset/:assetid', function ($assetid) use($app) {
        $userdb = R::readDbFromRequest();
        $username = R::readUsernameFromRequest();
        $oAsset = new Asset($userdb);
        //check if asset exists, if not, throw 404 error.
        $exists = $oAsset->checkIfAssetExists($assetid);
        if (!$exists) {
            $response["error"] = true;
            $response["message"] = "Asset does not exist";
            R::echoResponse(404, $response);
        } else {
            $result = $oAsset->deleteAsset($userdb, $assetid);
            if ($result) {
                $response["error"] = false;
                $response["message"] = "Asset deleted";
                Log::write("Asset " . $assetid . " deleted.", $username);
                R::echoResponse(200, $response);
            } else {
                $response["error"] = true;
                $response["message"] = "Could not delete asset";
                Log::write("Could not delete Asset " . $assetid . " - Possible failures on deleting associated requests/interventions/intervention_work/_material", $username);
                R::echoResponse(500, $response);
            }
        }
    });
});
                    $response['public_key'] = $public_key;
                    $code = 200;
                } else {
                    $response['public_key'] = "could not create or read keys";
                    $code = 500;
                    Log::write("Could not create or read keys from user", $user['username']);
                }
                //get access level of user (stored in employee table)
                $access_level = $oUser->getAccessLevel($loginId);
                $response['access_level'] = $access_level;
                if ($access_level == NULL) {
                    Log::write("*** access_level of user is NULL", $user['username']);
                }
            } else {
                // unknown error occurred
                $response['error'] = true;
                $response['message'] = "An error occurred. Possible duplicate username?";
                $code = 500;
                Log::write("Could not get user from database", $user['username']);
            }
        } else {
            // user credentials are wrong
            $response['error'] = true;
            $response['message'] = 'Login failed. Incorrect credentials';
            $code = 401;
            Log::write("Login failed. Incorrect credentials");
        }
        //finally the response
        R::echoResponse($code, $response);
    });
});
ConfigHelper::write('db.basename', '');
ConfigHelper::write('db.user', '');
ConfigHelper::write('db.password', '');
// LOGGING =================================
// enable logging on whole server. Log file under directory /log/log.log.
// it logs e.g. who logged in, who deleted assets, error messages, ...
ConfigHelper::write('log', TRUE);
// how long the logging should be kept on the server before the file gets deleted.
// e.g. 168 => 168/24 = 7 days.
ConfigHelper::write('log.hours', 168);
// DEBUG MODE =================================
// enable debug mode on whole server. See slim docs.
ConfigHelper::write('debug', TRUE);
// COMPRESSION =================================
// determine if serverside compression library zlib for gzip is enabled. Otherwise data usage can get large!
if (extension_loaded("zlib")) {
    ob_start("ob_gzhandler");
} else {
    $message = 'No zlib extension for HTTP compression installed on server.
    Please contact webhoster to install the zlib extension.
    PHPinfo can be found under www.example.com/api/info.php';
    echo $message;
    LogHelper::write($message);
}
/****************************************************************
B. DEVELOPMENT SETTINGS
 ****************************************************************/
// MOBILE SCOPE FOR MYSQL DB TABLES ==================
// relevant tables in mobile scope
$tables = array('assets', 'location', 'facilities', 'contacttype', 'contact', 'donors', 'agents', 'suppliers', 'manufactures', 'consumables', 'consumables_linked', 'employees', 'stock', 'department', 'essential_equipment', 'assetgenericname', 'assetutilization', 'assetstatus', 'assetcategory', 'intervention', 'request', 'request_st', 'warrantycontract', 'intervention_material', 'intervention_work', 'visit_type', 'failurcateg', 'failurecause');
ConfigHelper::write('db.mysql_tables', $tables);
 /**
  * Read the user belonging to the incoming request and get his/her defaultDB.
  *
  * @return String $userdb
  */
 public static function readDbFromRequest()
 {
     $app = \Slim\Slim::getInstance();
     $oUser = new User();
     $request = $app->request();
     $public_key = $request->headers('X-PublicKey');
     //get User array from sent public key
     $user = $oUser->getUserByPublicKey($public_key);
     $userdb = $oUser->setDefaultDatabase($user['LoginID']);
     if ($userdb != NULL) {
         return $userdb;
     } else {
         $response["error"] = true;
         $response["defaultdb"] = "Could not select database of user.";
         LogHelper::write("Could not select database, check if the user's DefaultDB is available.", $user['username']);
         RequestHelper::echoResponse(500, $response);
         $app->stop();
     }
 }