From 01a91bb4e54f40c96af293066b99c3a4a99c1410 Mon Sep 17 00:00:00 2001 From: Wisdurm Date: Wed, 26 Nov 2025 13:36:51 +0200 Subject: [PATCH] =?UTF-8?q?Lis=C3=A4=C3=A4=20asuntola?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + CMakeLists.txt | 2 +- src/main.cpp | 258 ++++++++++++++++++++++++++++++++----------- templates/admin.html | 6 +- templates/login.html | 8 +- 5 files changed, 200 insertions(+), 75 deletions(-) diff --git a/.gitignore b/.gitignore index a4fb4fb..70bcea8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ .cache/ +sessions/ diff --git a/CMakeLists.txt b/CMakeLists.txt index f9f8f46..3fffb07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ find_package(ZLIB REQUIRED) include(${CMAKE_SOURCE_DIR}/cmake/CPM.cmake) CPMAddPackage(Crow - VERSION 1.2.1 + VERSION 1.3.0 GITHUB_REPOSITORY CrowCpp/Crow OPTIONS "CROW_BUILD_EXAMPLES Off" diff --git a/src/main.cpp b/src/main.cpp index ddd3ac1..6f0af7c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,60 +2,82 @@ #include "crow/http_response.h" #include "crow/middlewares/cookie_parser.h" #include "crow/middlewares/session.h" +#include "crow/multipart_view.h" #include "crow/mustache.h" #include #include +#include +#include +#include +#include + +namespace utils +{ + // Katso onko kirjautumistiedot oikein + bool logged_in(const std::string& name, const std::string& password) { + try + { + pqxx::connection cx("dbname = postgres user = postgres password = 1234 \ + hostaddr = 127.0.0.1 port = 5432"); + if (not cx.is_open()) + { + CROW_LOG_CRITICAL << "Can't open database"; + return false; + } + // Connection established + CROW_LOG_INFO << "Opened database successfully: " << cx.dbname(); + // Etsi kayttajan tiedot + pqxx::work tx(cx); + pqxx::result r = tx.exec( + "SELECT * FROM kayttajat_table " + "WHERE nimi='" + tx.esc(name) + "'" + ); // pqxx:params too difficult + tx.commit(); + if (r.size() != 1) { + CROW_LOG_ERROR << "Unexpected SQL query results"; + return false; + } + // Tarkista tiedot + return r[0][2].as() == password; + } + catch (const std::exception &e) + { + CROW_LOG_ERROR << e.what(); + return false; + } + return true; + } + + // Generoi satunnainen tiedosto nimi + std::string fileName(const std::string& fileExtension) { + const char allowed[] = "abcedfghijklmnopqrstuvwxyz1234567890"; + srand(time(NULL)); + std::string r; + for (int i = 0; i < 20; ++i) { + r += allowed[rand() % (sizeof(allowed) / sizeof(*allowed) )]; + } + r += fileExtension; + return r; + } +} struct Asunto { std::string osoite; std::string kuvaPolku; }; -bool logged_in(const std::string& name, const std::string& password) { - try - { - pqxx::connection cx("dbname = postgres user = postgres password = 1234 \ - hostaddr = 127.0.0.1 port = 5432"); - if (not cx.is_open()) - { - CROW_LOG_CRITICAL << "Can't open database"; - return false; - } - // Connection established - CROW_LOG_INFO << "Opened database successfully: " << cx.dbname(); - // Etsi kayttajan tiedot - CROW_LOG_INFO << name; - pqxx::work tx(cx); - pqxx::row r = tx.exec( - "SELECT * FROM kayttajat_table WHERE nimi='$1'", - pqxx::params{name} - ).one_row(); - tx.commit(); - // Tarkista tiedot - return r[2].as() == password; - } - catch (const std::exception &e) - { - CROW_LOG_ERROR << e.what(); - return false; - } - return true; -} - int main() { // Typedef - using Session = crow::SessionMiddleware; + using Session = crow::SessionMiddleware; // Crow App - crow::App app{Session{ - crow::CookieParser::Cookie("session").max_age(24 * 60 * 60).path("/"), - AUTA MUA, - crow::InMemoryStore{}}}; + crow::App app{Session{ + crow::FileStore{"./sessions"}}}; // Asunnot lista std::vector asunnot; - CROW_ROUTE(app, "/")([&asunnot](){ + CROW_ROUTE(app, "/")([&asunnot](){ auto page = crow::mustache::load("index.html"); crow::json::wvalue asunnotJson; for (int i = 0; i < asunnot.size(); ++i) { @@ -63,8 +85,8 @@ int main() asunnotJson[i]["kuva"] = asunnot.at(i).kuvaPolku; } crow::mustache::context ctx({{"asunnot", asunnotJson}}); - return page.render(ctx); - }); + return page.render(ctx); + }); CROW_ROUTE(app, "/login") .methods("GET"_method, "POST"_method)([&app](const crow::request& req, crow::response& res){ @@ -79,17 +101,23 @@ int main() // Hanki params std::string reqName = req.get_body_params().get("name"); std::string reqPass = req.get_body_params().get("pass"); - // Aseta session muuttujat - session.set("name", reqName); - session.set("pass", reqPass); - // Kun POST request ohi, redirect admin sivulle - + // Tarkista kirjautuminen + if (utils::logged_in(reqName, reqPass)) { + CROW_LOG_INFO << "Account: " << reqName << " logged in"; + // Aseta session muuttujat + session.set("name", reqName); + // Kun POST request ohi, redirect admin sivulle + res.redirect("/admin"); + res.end(); + } + else { // Kirjautuminen ei onnistunut + CROW_LOG_INFO << "Account " << reqName << " failed login"; + } } crow::mustache::context ctx; auto page = crow::mustache::load("login.html"); - if (session.contains("name") and session.contains("pass")) { // Näytä kirjautumistiedot jos kirjautunut + if (session.contains("name")) { // Näytä kirjautumistiedot jos kirjautunut ctx["name"] = session.get("name", "_HELP_"); - ctx["pass"] = session.get("pass", "_HELP_"); } res.body = page.render(ctx).body_; res.end(); @@ -99,30 +127,125 @@ int main() .methods("GET"_method, "POST"_method)([&app](const crow::request& req, crow::response& res){ auto& session = app.get_context(req); - if (not logged_in(session.get("name","_NO_"), session.get("pass","_NO_"))) { - // Jos ei kirjauduttu sisään + if (session.get("name","_NO_") == "_NO_") { + // Jos ei kirjauduttu sisään, potki pois res.redirect("/"); res.end(); } - - if (req.method == "POST"_method) { // Jos POST request - - } - + // Jatka jos kirjautunut sisään + // Renderöi sivu auto page = crow::mustache::load("admin.html"); res.body = page.render().body_; res.end(); }); + CROW_ROUTE(app, "/asunto") + .methods("POST"_method)([&app, &asunnot](const crow::request& req){ + auto& session = app.get_context(req); + if (session.get("name","_NO_") == "_NO_") { + // Jos ei kirjauduttu sisään, potki pois + return crow::response(401); + } + // Jatka jos kirjautunut sisään + std::string asuntoOsoite; + std::string asuntoKuva; + // Uusi asuntola + crow::multipart::message_view file_message(req); + // File upload + for (const auto& part : file_message.part_map) { + const auto& part_name = part.first; + const auto& part_value = part.second; + CROW_LOG_DEBUG << "Part: " << part_name; + // Jos teksti + if (part_name != "image") { + CROW_LOG_DEBUG << "Value: " << part_value.body; // debug + asuntoOsoite = part_value.body; + continue; + } + // Jos kuva + + // Extract the file name + auto headers_it = part_value.headers.find("Content-Disposition"); + if (headers_it == part_value.headers.end()) { + CROW_LOG_ERROR << "No Content-Disposition found"; + return crow::response(400); + } + auto params_it = headers_it->second.params.find("filename"); + if (params_it == headers_it->second.params.end()) { + CROW_LOG_ERROR << "Part with name \"image\" should have a file"; + return crow::response(400); + } + const std::filesystem::path reqFile = params_it->second; + const std::string outfileName = utils::fileName(reqFile.extension()); + const std::filesystem::path outfilePath = "static/images/" + outfileName; + // Debug info + for (const auto& part_header : part_value.headers) { + const auto& part_header_name = part_header.first; + const auto& part_header_val = part_header.second; + CROW_LOG_DEBUG << "Header: " << part_header_name << '=' << part_header_val.value; + + for (const auto& param : part_header_val.params) + { + const auto& param_key = param.first; + const auto& param_val = param.second; + CROW_LOG_DEBUG << " Param: " << param_key << ',' << param_val; + } + } + // Write file to hard drive + std::ofstream file(outfilePath); + if (file.fail()) { + CROW_LOG_ERROR << "Cannot write file"; + return crow::response(500); + } + file << part_value.body; + file.close(); + CROW_LOG_INFO << "File written to " << outfilePath; + // Tietokantaa varten + asuntoKuva = outfileName; + } + // Lisää SQL tietokantaan + try + { + pqxx::connection cx("dbname = postgres user = postgres password = 1234 \ + hostaddr = 127.0.0.1 port = 5432"); + if (not cx.is_open()) + { + CROW_LOG_CRITICAL << "Can't open database"; + return crow::response(500); + } + // Connection established + CROW_LOG_INFO << "Opened database successfully: " << cx.dbname(); + // Do work + pqxx::work tx(cx); + + pqxx::result r = tx.exec( + "INSERT INTO public.asuntolat_table (osoite,kuva)" + "VALUES ('" + tx.esc(asuntoOsoite) + "','" + tx.esc(asuntoKuva) + "');"); + CROW_LOG_INFO << "Record added to database"; + // Valmista ollaan, nyt vaan päivitetään ramissa olevaa listaa + const struct Asunto asunto(asuntoOsoite, asuntoKuva); + asunnot.push_back(asunto); + tx.commit(); + } + catch (const std::exception &e) + { + CROW_LOG_ERROR << e.what(); + return crow::response(500); + } + // Valmis + return crow::response(200); + }); + + try - { + { pqxx::connection cx("dbname = postgres user = postgres password = 1234 \ - hostaddr = 127.0.0.1 port = 5432"); - if (not cx.is_open()) - { + hostaddr = 127.0.0.1 port = 5432"); + if (not cx.is_open()) + { CROW_LOG_CRITICAL << "Can't open database"; - return EXIT_FAILURE; - } + return EXIT_FAILURE; + } // Connection established CROW_LOG_INFO << "Opened database successfully: " << cx.dbname(); // Do work @@ -139,14 +262,15 @@ int main() //CROW_LOG_INFO << asunto.osoite << ":" << asunto.kuvaPolku << "\n"; asunnot.push_back( asunto ); } - } - catch (const std::exception &e) - { + } + catch (const std::exception &e) + { CROW_LOG_ERROR << e.what(); - return EXIT_FAILURE; - } + return EXIT_FAILURE; + } - // :D - app.port(18080).multithreaded().run(); + // :D + //app.loglevel(crow::LogLevel::Debug); + app.port(18080).multithreaded().run(); + return EXIT_SUCCESS; } - diff --git a/templates/admin.html b/templates/admin.html index 015b650..a593169 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -8,15 +8,15 @@
Tietoa meistä: -
+
Lisää asuntola -
-
+ +



diff --git a/templates/login.html b/templates/login.html index 03de722..b8f081a 100644 --- a/templates/login.html +++ b/templates/login.html @@ -6,10 +6,10 @@ - {{ #name }} -

Kirjauduttu sisään, tervetuloa {{ name }}!

- {{ /name }} - + {{#name}} +

Kirjauduttu sisään, tervetuloa {{name}}!

+ {{/name}} +


-- 2.47.3