diff --git a/src/database.cpp b/src/database.cpp index de11988..d0057fa 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -490,6 +490,33 @@ namespace Database { return 0; } + /* //todo:implement + * Executes the prepared statement INSERT_FREELANCER_FILE_SUBMISSION_ALIAS + * Takes an open pqxx::connection and aliasname as {ID}/{Alias}, freelancerid, filename + * returns errorLevel + * 0 = no error + * 1 = query error + * 2 = critical error + */ + int executePreparedStatement_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS(pqxx::connection &connection, const int freelancerID, const std::string& fileName, const std::string& aliasname) { + try { + pqxx::work work(connection); + work.exec_prepared(PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS, freelancerID, fileName, aliasname); + work.commit(); + } + catch (pqxx::sql_error const &e) { + std::cerr + << "Database error: " << e.what() << std::endl + << "Query was: " << e.query() << std::endl; + return 1; + } + catch (std::exception const &e) { + std::cerr << e.what() << std::endl; + return 2; + } + return 0; + } + /* * Executes the prepared statement SELECT_FREELANCER_ALIAS * Takes an open pqxx::connection and the freelancer email to select by @@ -706,6 +733,20 @@ namespace Database { work.commit(); return result; } + + /* + * Executes the prepared statement SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH + * Takes an open pqxx::connection the alias and the freelancer ID + * returns the path to the file + */ + pqxx::result executePreparedStatement_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH(pqxx::connection &connection, const int& freelancerID, const std::string& alias) { + pqxx::work work(connection); + pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH, freelancerID, alias); + work.commit(); + return result; + } + + /* * Executes the prepared statement INSERT_FREELANCER_FILE_SUBMISSION * Takes an open pqxx::connection and the freelancer email, the file name, the full path and the filesize in byte diff --git a/src/databaseStatementConstCollection.cpp b/src/databaseStatementConstCollection.cpp index 8c64e33..4971518 100644 --- a/src/databaseStatementConstCollection.cpp +++ b/src/databaseStatementConstCollection.cpp @@ -254,6 +254,20 @@ namespace DatabaseStatementConstCollection { const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_PATH = "selectFreelancerFileSubmissionPATH"; const static std::string SQL_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_PATH = "select fullpath from freelancersubmissions where freelancerid = (select freelancers.id from freelancers where emailaddress = $1) and filename = $2"; + /* + * Name and Statement for prepared statement to select fullpath of a submission based on freelancer ID and alias + * Aliasname must follow the format {ID}/{Alias} + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH = "selectFreelancerFileSubmissionAliasPATH"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH = "select fullpath from freelancersubmissions where freelancerid = $1 and filename = (select route from aliasroutes where freelancerid = $1 and aliasname = $2 and routeparameter = 'FILESUBMISSION')"; + + /* + * Name and Statement for prepared statement to insert alias for a file submission + * 1=freelancer id, 2=filename, 3=aliasname as {ID}/{Alias} + */ + const static std::string PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS = "insertFreelancerFileSubmissionAlias"; + const static std::string SQL_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS = "insert into aliasroutes (aliasname, freelancerid, route, routeparameter) values($3, $1, $2, 'FILESUBMISSION');"; + /* * Name and Statement for prepared statement to delete a submission based on freelancer email and filename */ @@ -320,6 +334,8 @@ namespace DatabaseStatementConstCollection { const static int ID_DELETE_FREELANCER_FILE_SUBMISSION = 40; const static int ID_PRUGE_FREELANCER_FILE_SUBMISSION = 41; const static int ID_INSERT_FREELANCER_FILE_SUBMISSION = 42; + const static int ID_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH = 43; + const static int ID_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS = 44; @@ -369,7 +385,9 @@ namespace DatabaseStatementConstCollection { {PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_PATH, SQL_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_PATH}, {PREPARED_STATEMENT_DELETE_FREELANCER_FILE_SUBMISSION, SQL_STATEMENT_DELETE_FREELANCER_FILE_SUBMISSION_PATH}, {PREPARED_STATEMENT_PRUGE_FREELANCER_FILE_SUBMISSION, SQL_STATEMENT_PRUGE_FREELANCER_FILE_SUBMISSION}, - {PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION, SQL_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION} + {PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION, SQL_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION}, + {PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH, SQL_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH}, + {PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS, SQL_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS} }; /* * Easy access to prepared statement name via int @@ -417,7 +435,9 @@ namespace DatabaseStatementConstCollection { {ID_SELECT_FREELANCER_FILE_SUBMISSION_PATH, PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_PATH}, {ID_DELETE_FREELANCER_FILE_SUBMISSION, PREPARED_STATEMENT_DELETE_FREELANCER_FILE_SUBMISSION}, {ID_PRUGE_FREELANCER_FILE_SUBMISSION, PREPARED_STATEMENT_PRUGE_FREELANCER_FILE_SUBMISSION}, - {ID_INSERT_FREELANCER_FILE_SUBMISSION, PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION} + {ID_INSERT_FREELANCER_FILE_SUBMISSION, PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION}, + {ID_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH, PREPARED_STATEMENT_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH}, + {ID_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS, PREPARED_STATEMENT_INSERT_FREELANCER_FILE_SUBMISSION_ALIAS} }; /* diff --git a/src/main.cpp b/src/main.cpp index e3460b6..5fde3e8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1160,6 +1160,38 @@ int main(int argc, char *argv[]) { } }); + /* + * Serves a freelancers file based on alias without login validation + */ + CROW_ROUTE(app, "/commissionSubmission//").methods(crow::HTTPMethod::GET) + ([&, configuration](const crow::request &postRequest, const int& freelancerID, const string& alias) { + pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatement(databaseConnection, ID_SELECT_FREELANCER_FILE_SUBMISSION_PATH); + + string submissionFilePath = Utilities::getFreelancerSubmissionAlias(configuration, freelancerID, alias); + + if (submissionFilePath.empty()) + return crow::response(404, "File does not exist."); + + 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; + }); + /* * Page for freelancer to view existing submissions */ diff --git a/src/utilities.cpp b/src/utilities.cpp index f582115..0fa5648 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -516,6 +516,26 @@ namespace Utilities { return resultJsonAlias; } + /* + * Gets The Alias of a freelancers Submission + * takes configuration the freelancerID and the Alias + * returns file path + */ + std::string getFreelancerSubmissionAlias(const Utilities::config& configuration, const int freelancerID, const std::string& alias) { + std::string filePath; + std::string decodedAlias = alias; + decodeString(decodedAlias); + std::string idAlias = std::to_string(freelancerID); + idAlias.append("/"); + idAlias.append(decodedAlias); + pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatement(databaseConnection, ID_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH); + pqxx::result resultAlias = Database::executePreparedStatement_SELECT_FREELANCER_FILE_SUBMISSION_ALIAS_PATH(databaseConnection, freelancerID, idAlias); + if (!resultAlias.empty()) + filePath = resultAlias.at(0).at(0).c_str(); + return filePath; + } + /* * Gets The freelancer listing * takes configuration