From 3c9488df66345de7ffec617afb11e9dafac6d15c Mon Sep 17 00:00:00 2001 From: Tina_Azure <-> Date: Fri, 4 Aug 2023 20:25:03 +0200 Subject: [PATCH] login gated freelancer specific file submission access --- src/database.cpp | 12 ++++++++++++ src/main.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/utilities.cpp | 16 ++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/database.cpp b/src/database.cpp index ebba9f9..4d2ff75 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -683,6 +683,18 @@ namespace Database { return result; } + /* + * Executes the prepared statement SELECT_FREELANCER_FILE_SUBMISSION_PATH + * Takes an open pqxx::connection the file name and the freelancer email + * returns the path to the file + */ + pqxx::result executePreparedStatement_SELECT_FREELANCER_FILE_SUBMISSION_PATH(pqxx::connection &connection, const std::string& fileName, const std::string& freelancerEmail) { + pqxx::work work(connection); + pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_PATH, freelancerEmail, fileName); + work.commit(); + return result; + } + /* * Prepares a statement based on ID * Takes an open pqxx::connection, the statement id diff --git a/src/main.cpp b/src/main.cpp index 7b27df3..1619c67 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1105,6 +1105,50 @@ int main(int argc, char *argv[]) { return crow::response(403, "Not logged in"); } }); + + + /* + * Serves a freelancers file based on [hash]Filename with login validation + */ + CROW_ROUTE(app, "/freelancer/submissionManagement/view/").methods(crow::HTTPMethod::GET) + ([&, configuration](const crow::request &postRequest, const string& fileName) { + auto &cookieCtx = app.get_context(postRequest); + if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { + pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatement(databaseConnection, ID_SELECT_FREELANCER_FILE_SUBMISSION_PATH); + + pqxx::result submissionFilePathResult = Database::executePreparedStatement_SELECT_FREELANCER_FILE_SUBMISSION_PATH(databaseConnection, fileName, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL)); + + if (submissionFilePathResult.empty()) + return crow::response(404, "File does not exist."); + + string submissionFilePath = submissionFilePathResult.at(0).at(0).c_str(); + + switch (Utilities::validateFileReadAccess(submissionFilePath)) { + case 1: + return crow::response(404, "File does not exist."); + break; + case 2: + return crow::response(500, "Filesystem Permission Error."); + break; + case 3: + return crow::response(400, "Invalid file request was executed."); + break; + } + + + crow::response fileResponse; + fileResponse.code = 200; + fileResponse.set_static_file_info(submissionFilePath); + + return fileResponse; + } + else { + //ERROR not logged in + return crow::response(403, "Not logged in"); + } + }); + /* CROW_ROUTE(app, "/freelancer/submissionManagement/add/fulfillment").methods(crow::HTTPMethod::Post) ([&, configuration](const crow::request& postRequest) { diff --git a/src/utilities.cpp b/src/utilities.cpp index ef982d9..10c1c4c 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -113,6 +113,22 @@ namespace Utilities { return true; } + /* + * Checks if a path has a readable file + * returns 0 = OK, 1 = does not exist, 2 = no read access, 3 = no path + */ + int validateFileReadAccess(const std::string& path) { + if (path.empty()) + return 3; + if(access(path.c_str(), F_OK)) + return 1; + if(access(path.c_str(), R_OK)) { + errorOut("validateFileReadAccess=" + path + " does not have Read/Write access"); + return 2; + } + return 0; + } + /* * Struct representing the configuration file */