From d26c16aa69a5841f407e6afc2333b92d6eb29694 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Sun, 18 Aug 2019 11:57:08 -0400 Subject: [PATCH] database stuff --- .gitmodules | 6 +++ 3rdparty/mysql-connector-cpp | 1 + CMakeLists.txt | 20 +++++++- include/database/base_repository.h | 19 ++++++++ include/models.h | 10 ++++ include/token_manager.h | 7 +-- src/controller/loginController.hpp | 16 +++---- src/database/base_repository.cpp | 25 ++++++++++ src/dto/loginResultDto.hpp | 9 ++++ src/main.cpp | 71 +++++++++++++++++++++++++++- src/token_manager.cpp | 75 ++++++++++++++++-------------- 11 files changed, 211 insertions(+), 48 deletions(-) create mode 160000 3rdparty/mysql-connector-cpp create mode 100644 include/database/base_repository.h create mode 100644 src/database/base_repository.cpp diff --git a/.gitmodules b/.gitmodules index d18c440..a71061f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,9 @@ [submodule "3rdparty/jwt-cpp"] path = 3rdparty/jwt-cpp url = https://github.com/Thalhammer/jwt-cpp +[submodule "3rdparty/ormpp"] + path = 3rdparty/ormpp + url = https://github.com/qicosmos/ormpp +[submodule "3rdparty/mysql-connector-cpp"] + path = 3rdparty/mysql-connector-cpp + url = https://github.com/mysql/mysql-connector-cpp diff --git a/3rdparty/mysql-connector-cpp b/3rdparty/mysql-connector-cpp new file mode 160000 index 0000000..64731f9 --- /dev/null +++ b/3rdparty/mysql-connector-cpp @@ -0,0 +1 @@ +Subproject commit 64731f9625d5bcff86236c9fce2a1f5c55d60242 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9815658..1cce78a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,9 +5,12 @@ project(icarus) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 17) +#add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + set(SOURCES src/appComponent.hpp src/controller/loginController.hpp + src/database/base_repository.cpp src/directory_manager.cpp src/dto/loginResultDto.hpp src/imageFile.cpp @@ -16,6 +19,7 @@ set(SOURCES src/token_manager.cpp ) set(HEADERS + include/database/base_repository.h include/models.h include/directory_manager.h include/imageFile.h @@ -52,18 +56,32 @@ set(TAGLIB_HEADERS "${CMAKE_SOURCE_DIR}/3rdparty/taglib/taglib/xm" ) +set (ORM_DIR + ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/ormpp +) + +set (MYSQL + /usr/local/mysql/connector-c++-8.0/lib64 + ) +set (MYSQL_INCLUDE + /usr/local/mysql/connector-c++-8.0/include/mysqlx + /usr/local/mysql/connector-c++-8.0/include/mysqlx/common + ) + include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() +link_directories(${MYSQL}) include_directories(include ${CPR_INCLUDE_DIRS} ${TAGLIB} ${TAGLIB_HEADERS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/cpr) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/taglib) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/oatpp) +#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/mysql-connector-cpp) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/appsettings.json ${CMAKE_BINARY_DIR}/bin/appsettings.json COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/authcredentials.json ${CMAKE_BINARY_DIR}/bin/authcredentials.json COPYONLY) add_executable(icarus ${SOURCES} ${HEADERS}) target_include_directories(icarus PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/jwt-cpp/include) -target_link_libraries(icarus "-lstdc++fs" tag oatpp ${CONAN_LIBS} ${CPR_LIBRARIES}) +target_link_libraries(icarus "-lstdc++fs" tag oatpp mysqlclient ${CONAN_LIBS} ${CPR_LIBRARIES}) diff --git a/include/database/base_repository.h b/include/database/base_repository.h new file mode 100644 index 0000000..d8c8e43 --- /dev/null +++ b/include/database/base_repository.h @@ -0,0 +1,19 @@ +#ifndef BASE_REPOSITORY_H_ +#define BASE_REPOSITORY_H_ + +#include + +#include + +#include "models.h" + +class base_repository +{ +public: + MYSQL* setup_mysql_connection(database_connection); + + MYSQL_RES* perform_mysql_query(MYSQL*, std::string&); +private: +}; + +#endif diff --git a/include/models.h b/include/models.h index 1b71544..c2532e1 100644 --- a/include/models.h +++ b/include/models.h @@ -48,6 +48,16 @@ struct auth_credentials std::string api_identifier; std::string client_id; std::string client_secret; + std::string uri; + std::string endpoint; +}; + +struct database_connection +{ + std::string server; + std::string username; + std::string password; + std::string database; }; struct TokenReq diff --git a/include/token_manager.h b/include/token_manager.h index 6d32217..4d7b80b 100644 --- a/include/token_manager.h +++ b/include/token_manager.h @@ -1,6 +1,8 @@ #ifndef TOKEN_MANAGER_H_ #define TOKEN_MANAGER_H_ +#include + #include "models.h" class token_manager @@ -9,10 +11,9 @@ public: token_manager(); loginResult retrieve_token(); - - //LoginRes* retrieve_token(TokenReq *tok); + loginResult retrieve_token(std::string_view); private: - auth_credentials parse_auth_credentials(); + auth_credentials parse_auth_credentials(std::string_view); }; #endif diff --git a/src/controller/loginController.hpp b/src/controller/loginController.hpp index 7cd7683..772a17d 100644 --- a/src/controller/loginController.hpp +++ b/src/controller/loginController.hpp @@ -18,32 +18,32 @@ class loginController : public oatpp::web::server::api::ApiController { public: loginController(std::string p, OATPP_COMPONENT(std::shared_ptr, objectMapper)) - : oatpp::web::server::api::ApiController(objectMapper), exe_path(fs::canonical(p.c_str()).parent_path().string()) - { - std::cout << "p is " << p << std::endl; - std::cout << "working path " << exe_path.string() << std::endl; - } + : oatpp::web::server::api::ApiController(objectMapper), exe_path(std::move(p)) + { } #include OATPP_CODEGEN_BEGIN(ApiController) - ENDPOINT("POST", "/api/v1/login", root) + ENDPOINT("POST", "/api/v1/login", data, BODY_DTO(userDto::ObjectWrapper, usr)) { OATPP_LOGI("icarus", "logging in"); + std::cout << "user: " << usr->username->c_str() << std::endl; + token_manager tok; - auto token = tok.retrieve_token(); + auto token = tok.retrieve_token(exe_path); auto logRes = loginResultDto::createShared(); logRes->access_token = token.access_token.c_str(); logRes->token_type = token.token_type.c_str(); + logRes->expiration = token.expiration; return createDtoResponse(Status::CODE_200, logRes); } #include OATPP_CODEGEN_END(ApiController) private: - fs::path exe_path; + std::string exe_path; }; #endif diff --git a/src/database/base_repository.cpp b/src/database/base_repository.cpp new file mode 100644 index 0000000..c67c065 --- /dev/null +++ b/src/database/base_repository.cpp @@ -0,0 +1,25 @@ +#include "database/base_repository.h" + +MYSQL* base_repository::setup_mysql_connection(database_connection details) +{ + MYSQL *connection = mysql_init(NULL); + + // connect to the database with the details attached. + if (!mysql_real_connect(connection,details.server.c_str(), details.username.c_str(), details.password.c_str(), details.database.c_str(), 0, NULL, 0)) { + printf("Conection error : %s\n", mysql_error(connection)); + exit(1); + } + return connection; +} + +MYSQL_RES* base_repository::perform_mysql_query(MYSQL *conn, std::string& query) +{ + // send the query to the database + if (mysql_query(conn, query.c_str())) + { + printf("MySQL query error : %s\n", mysql_error(conn)); + exit(1); + } + + return mysql_use_result(conn); +} diff --git a/src/dto/loginResultDto.hpp b/src/dto/loginResultDto.hpp index 05b7b88..a43ec02 100644 --- a/src/dto/loginResultDto.hpp +++ b/src/dto/loginResultDto.hpp @@ -12,6 +12,15 @@ class loginResultDto : public oatpp::data::mapping::type::Object DTO_FIELD(String, access_token); DTO_FIELD(String, token_type); + DTO_FIELD(Int32, expiration); +}; + +class userDto : public oatpp::data::mapping::type::Object +{ + DTO_INIT(userDto, Object) + + DTO_FIELD(String, username); + DTO_FIELD(String, password); }; #include OATPP_CODEGEN_END(DTO) diff --git a/src/main.cpp b/src/main.cpp index 68ea3b4..f779651 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,18 @@ +#include #include #include #include #include +#include "models.h" +#include #include "oatpp/network/server/Server.hpp" #include "oatpp/network/server/SimpleTCPConnectionProvider.hpp" #include "oatpp/web/server/HttpConnectionHandler.hpp" #include "appComponent.hpp" #include "controller/loginController.hpp" -//#include "loginHandler.hpp" +#include "database/base_repository.h" namespace fs = std::filesystem; @@ -35,13 +38,77 @@ void run(const std::string& working_path) server.run(); } +MYSQL* mysql_connection_setup(database_connection mysql_details) +{ + // first of all create a mysql instance and initialize the variables within + MYSQL *connection = mysql_init(NULL); + + // connect to the database with the details attached. + if (!mysql_real_connect(connection,mysql_details.server.c_str(), mysql_details.username.c_str(), mysql_details.password.c_str(), mysql_details.database.c_str(), 0, NULL, 0)) { + printf("Conection error : %s\n", mysql_error(connection)); + exit(1); + } + return connection; +} + +MYSQL_RES* mysql_perform_query(MYSQL *connection, char *sql_query) +{ + // send the query to the database + if (mysql_query(connection, sql_query)) + { + printf("MySQL query error : %s\n", mysql_error(connection)); + exit(1); + } + + return mysql_use_result(connection); +} + +void test_database() +{ + database_connection mysqlD; + mysqlD.server = ""; // where the mysql database is + mysqlD.username = ""; // the root user of mysql + mysqlD.password = ""; // the password of the root user in mysql + mysqlD.database = ""; // the databse to pick + + base_repository base; + auto conn = base.setup_mysql_connection(mysqlD); + + // assign the results return to the MYSQL_RES pointer + const std::string query = "SELECT *, NULL FROM Song"; + auto res = base.perform_mysql_query(conn, query); + auto num_of_fields = mysql_num_fields(res); + + printf("MySQL Tables in mysql database:\n"); + auto row_count = 1; + + for (MYSQL_ROW row = NULL; (row = mysql_fetch_row(res)) != NULL;) { + std::cout << " row " << row_count << std::endl; + for (auto i = 0; i != num_of_fields; ++i) { + auto val = row[i]; + + if ( val == NULL) { + std::cout << "found null value " << std::endl; + continue; + } + std::cout << val << " "; + } + std::cout << std::endl; + } + + /* clean up the database result set */ + mysql_free_result(res); + /* clean up the database link */ + mysql_close(conn); +} + int main(int argc, char **argv) { oatpp::base::Environment::init(); std::string working_path = argv[0]; - //std::cout << fs::canonical(fs::path(working_path.c_str())).parent_path().string() << std::endl; + test_database(); run(working_path); oatpp::base::Environment::destroy(); diff --git a/src/token_manager.cpp b/src/token_manager.cpp index e529fd7..73aab95 100644 --- a/src/token_manager.cpp +++ b/src/token_manager.cpp @@ -1,20 +1,18 @@ #include +#include #include #include +#include #include #include #include #include -//#include "models.h" #include "token_manager.h" namespace fs = std::filesystem; -//extern "C" -//{ - token_manager::token_manager() { @@ -22,51 +20,60 @@ token_manager::token_manager() loginResult token_manager::retrieve_token() { - auto cred = parse_auth_credentials(); - loginResult lr; lr.access_token = "dsfdsf"; lr.token_type = "demo"; return lr; } - -auth_credentials token_manager::parse_auth_credentials() +loginResult token_manager::retrieve_token(std::string_view path) { - auth_credentials auth; - //auto ss = working_path.string(); - //auto path = fs::canonical(fs::path(".")); - //std::cout << "canonical path " << path.string() << std::endl; - - return auth; -} - -/** -LoginRes* token_manager::retrieve_token(TokenReq *tok) -{ - LoginRes *res = new LoginRes; + auto cred = parse_auth_credentials(path); nlohmann::json reqObj; - reqObj["client_id"] = tok->ClientId; - reqObj["client_secret"] = tok->ClientSecret; - reqObj["audience"] = tok->Audience; - reqObj["grant_type"] = tok->GrantType; + reqObj["client_id"] = cred.client_id; + reqObj["client_secret"] = cred.client_secret; + reqObj["audience"] = cred.api_identifier; + reqObj["grant_type"] = "client_credentials"; - std::string uri{tok->URI}; + std::string uri{cred.uri}; uri.append("/"); - uri.append(tok->Endpoint); + uri.append(cred.endpoint); auto r = cpr::Post(cpr::Url{uri}, cpr::Body{reqObj.dump()}, - cpr::Header{{"Content-Type", "application/json"}}); + cpr::Header{{"Content-Type", "application/json"}, + {"Connection", "keep-alive"}}); auto post_res = nlohmann::json::parse(r.text); - strcpy(res->Token, post_res["access_token"].get().c_str()); - strcpy(res->TokenType, post_res["token_type"].get().c_str()); - res->Expiration = post_res["expires_in"].get(); - strcpy(res->Message, "Success"); - return res; + loginResult lr; + lr.access_token = post_res["access_token"].get(); + lr.token_type = post_res["token_type"].get(); + lr.expiration = post_res["expires_in"].get(); + + return lr; +} + +auth_credentials token_manager::parse_auth_credentials(std::string_view path) +{ + auto exe_path = fs::canonical(path).parent_path().string(); + exe_path.append("/authcredentials.json"); + + std::fstream a(exe_path, std::ios::in); + std::stringstream s; + s << a.rdbuf(); + a.close(); + + auto con = nlohmann::json::parse(s.str()); + + auth_credentials auth; + auth.uri = "https://"; + auth.uri.append(con["Domain"]); + auth.api_identifier = con["ApiIdentifier"]; + auth.client_id = con["ClientId"]; + auth.client_secret = con["ClientSecret"]; + auth.endpoint = "oauth/token"; + + return auth; } -*/ -//}