diff --git a/engine/server/application/LoginServer/src/CMakeLists.txt b/engine/server/application/LoginServer/src/CMakeLists.txt index dc0bb23e..12cc8c7e 100644 --- a/engine/server/application/LoginServer/src/CMakeLists.txt +++ b/engine/server/application/LoginServer/src/CMakeLists.txt @@ -81,7 +81,6 @@ endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/shared ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCommandParser/include/public - ${SWG_ENGINE_SOURCE_DIR}/server/library/json ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCompression/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDatabaseInterface/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public @@ -111,7 +110,7 @@ include_directories( ${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/platform/projects ${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/platform/utils ${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/udplibrary - ${CURL_INCLUDE_DIRS} + ${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/webAPI ) add_executable(LoginServer @@ -120,6 +119,7 @@ add_executable(LoginServer ) target_link_libraries(LoginServer + webAPI sharedCommandParser sharedCompression sharedDatabaseInterface @@ -152,6 +152,5 @@ target_link_libraries(LoginServer CommonAPI LoginAPI MonAPI2 - ${CURL_LIBRARIES} ${CMAKE_DL_LIBS} ) diff --git a/engine/server/application/LoginServer/src/shared/ClientConnection.cpp b/engine/server/application/LoginServer/src/shared/ClientConnection.cpp index f9d8be62..a2daaaad 100755 --- a/engine/server/application/LoginServer/src/shared/ClientConnection.cpp +++ b/engine/server/application/LoginServer/src/shared/ClientConnection.cpp @@ -23,11 +23,9 @@ #include "sharedNetworkMessages/GenericValueTypeMessage.h" #include "sharedNetworkMessages/LoginEnumCluster.h" +#include #include -#include -#include -using json = nlohmann::json; //----------------------------------------------------------------------- ClientConnection::ClientConnection(UdpConnectionMT * u, TcpClient * t) : @@ -171,89 +169,60 @@ void ClientConnection::onReceive(const Archive::ByteStream & message) } //----------------------------------------------------------------------- -// This is used by curl; arguably would be better placed elsewhere? -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - ((std::string*)userp)->append((char*)contents, size * nmemb); - return size * nmemb; -} - - -//----------------------------------------------------------------------- -// Stub routine for station API account validation. -// Grab a challenge key from the list and send it back to the client. +// originally was used to validate station API credentials, now uses our custom api void ClientConnection::validateClient(const std::string & id, const std::string & key) { - StationId suid = atoi(id.c_str()); + int authOK = 0; - if (suid==0) + if (suid == 0) { std::hash h; suid = h(id); //lint !e603 // Symbol 'h' not initialized (it's a functor) } - LOG("LoginClientConnection", ("validateClient() for stationId (%lu) at IP (%s), id (%s) key (%s), skipping validating session", m_stationId, getRemoteAddress().c_str(), id.c_str(), key.c_str())); + LOG("LoginClientConnection", ("validateClient() for stationId (%lu) at IP (%s), id (%s)", m_stationId, getRemoteAddress().c_str(), id.c_str())); - const char * authURL = ConfigLoginServer::getExternalAuthUrl(); + std::string authURL(ConfigLoginServer::getExternalAuthUrl()); - if (authURL != NULL && strcmp(authURL, "") != 0) + if (!authURL.empty()) { - CURL *curl = curl_easy_init(); + std::ostringstream postBuf; + std::string postData; - if (curl) + postBuf << "user_name=" << id << "&user_password=" << key << "&stationID=" << suid << "&ip=" << getRemoteAddress(); + postData = std::string(postBuf.str()); + + std::string response = webAPI::simplePost(authURL, postData, nullptr); + + if (!response.empty()) { - std::ostringstream postBuf; - std::string readBuffer; - std::string postData; - - postBuf << "user_name=" << id << "&user_password=" << key << "&stationID=" << suid << "&ip=" << getRemoteAddress(); - postData = std::string(postBuf.str()); - - curl_easy_setopt(curl, CURLOPT_URL, authURL); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - - CURLcode res = curl_easy_perform(curl); - - if (res == CURLE_OK && !(readBuffer.empty())) + if (response == "success") { - json j = json::parse(readBuffer); - - if (j.count("status") && j["status"].get() == "success") - { - LoginServer::getInstance().onValidateClient(suid, id, this, true, NULL, 0xFFFFFFFF, 0xFFFFFFFF); - } - else - { - std::string errMsg; - - if (j.count("message")) - { - errMsg = j["message"].get(); - } - else - { - errMsg = "Message not provided by authentication service."; - } - - ErrorMessage err("Login Failed", errMsg); - this->send(err, true); - } + authOK = 1; } else { - ErrorMessage err("Login Failed", "Could not connect to authentication service."); + ErrorMessage err("Login Failed", response); this->send(err, true); } - curl_easy_cleanup(curl); + } + else + { + ErrorMessage err("Login Failed", "Error connecting to authentication provider."); + this->send(err, true); } } else + { + authOK = 1; + } + + if (authOK) { LoginServer::getInstance().onValidateClient(suid, id, this, true, NULL, 0xFFFFFFFF, 0xFFFFFFFF); } + // else this case will never be reached, noop } // ---------------------------------------------------------------------------- diff --git a/engine/server/library/CMakeLists.txt b/engine/server/library/CMakeLists.txt index 810038ec..75f23aba 100644 --- a/engine/server/library/CMakeLists.txt +++ b/engine/server/library/CMakeLists.txt @@ -7,5 +7,3 @@ add_subdirectory(serverNetworkMessages) add_subdirectory(serverPathfinding) add_subdirectory(serverScript) add_subdirectory(serverUtility) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/json) diff --git a/external/3rd/library/CMakeLists.txt b/external/3rd/library/CMakeLists.txt index 9d0041c3..cee81091 100644 --- a/external/3rd/library/CMakeLists.txt +++ b/external/3rd/library/CMakeLists.txt @@ -1,4 +1,6 @@ - +add_subdirectory(webAPI) add_subdirectory(platform) add_subdirectory(soePlatform) add_subdirectory(udplibrary) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/webAPI) diff --git a/external/3rd/library/webAPI/CMakeLists.txt b/external/3rd/library/webAPI/CMakeLists.txt new file mode 100644 index 00000000..f4f8d562 --- /dev/null +++ b/external/3rd/library/webAPI/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SHARED_SOURCES + webAPI.cpp + webAPI.h + json.hpp +) + +include_directories( + ${CURL_INCLUDE_DIRS} +) + +#target_link_libraries( +# ${CURL_LIBRARIES} +#) diff --git a/engine/server/library/json/json.hpp b/external/3rd/library/webAPI/json.hpp similarity index 100% rename from engine/server/library/json/json.hpp rename to external/3rd/library/webAPI/json.hpp diff --git a/external/3rd/library/webAPI/webAPI.cpp b/external/3rd/library/webAPI/webAPI.cpp new file mode 100644 index 00000000..e2b8446c --- /dev/null +++ b/external/3rd/library/webAPI/webAPI.cpp @@ -0,0 +1,86 @@ + +#include "webAPI.h" + +// if status == success, returns "success", or slotName's contents if specified... +// otherwise returns the "message" if no success +std::string simplePost(std::string endpoint, std::string data, std::string slotName) +{ + nlohmann::json response = request(endpoint, data, 1); + std::string output; + + if (response.count("status") && response["status"].get() == "success") + { + if (slotName && response.count(slotName)) + { + output = response[slotName].get(); + } + else + { + output = "success"; + } + } + else + { + if (j.count("message")) + { + output = j["message"].get(); + } + else + { + output = "Message not provided by authentication service."; + } + } + + return output; +} + +nlohmann::json request(std::string endpoint, std::string data, int reqType, ...) +{ + nlohmann::json response; + + if (!endpoint.empty()) //data is allowed to be an empty string if we're doing a normal GET + { + CURL *curl = curl_easy_init(); + + if (curl) + { + std::string readBuffer; + + curl_easy_setopt(curl, CURLOPT_URL, endpoint.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + if (reqType == 1) + { + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); + } + + CURLcode res = curl_easy_perform(curl); + + if (res == CURLE_OK && !(readBuffer.empty())) + { + response = json::parse(readBuffer); + } + curl_easy_cleanup(curl); + } + else + { + response["message"] = "Failed to initialize cURL."; + response["status"] = "failure"; + } + } + else + { + response["message"] = "Invalid endpoint URL."; + response["status"] = "failure"; + } + + return response; +} + +// This is used by curl to grab the response and put it into a var +size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) +{ + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; +} diff --git a/external/3rd/library/webAPI/webAPI.h b/external/3rd/library/webAPI/webAPI.h new file mode 100644 index 00000000..592d25aa --- /dev/null +++ b/external/3rd/library/webAPI/webAPI.h @@ -0,0 +1,18 @@ +#ifndef webAPI_H +#define webAPI_H + +#include "json.hpp" +#include + +namespace webAPI +{ + std::string simplePost(std::string endpoint, std::string data, std::string slotName); + //std::string simpleGet(char* endpoint, char* data); + //nlohmann::json post(char* endpoint, char* data); + //nlohmann::json get(char* endpoint, char* data); + + nlohmann::json request(std::string endpoint, std::string data, int reqType); // 1 for post, 0 for get + size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp); +}; + +#endif