diff --git a/src/main.cpp b/src/main.cpp index ea85fe7..9839013 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -979,72 +979,230 @@ int main(int argc, char *argv[]) { auto& cookieCtx = app.get_context(getRequest); crow::mustache::context ctx; if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { - - - - - - ctx[MUSTACHE_COOKIE_LOGGED_IN] = true; + + size_t usedStorageInMB = 0; //todo:database operation + size_t maxStorageInMB = configuration.submissionMaxtotalStorageMB; + ctx[MUSTACHE_FREELANCER_AVAILIBLE_STORAGE_IN_MB] = usedStorageInMB; + ctx[MUSTACHE_FREELANCER_MAXIMUM_STORAGE_IN_MB] = maxStorageInMB; + + string allowedFiletypes; + for (const string &filetype: configuration.submissionAllowedFiletypes) { + if (!allowedFiletypes.empty()) + allowedFiletypes.append(","); + allowedFiletypes.append("."); + allowedFiletypes.append(filetype); + } + + ctx[MUSTACHE_FREELANCER_ALLOWED_FILE_TYPES_LIST_COMMA_SEPARATED] = allowedFiletypes; + + if (usedStorageInMB < maxStorageInMB) + ctx[MUSTACHE_FREELANCER_UPLOAD_AVAILIBLE] = true; } auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_ADD); return page.render(ctx); }); + /* + * Execute adding of submission + */ + CROW_ROUTE(app, "/freelancer/submissionManagement/add/fulfillment").methods(crow::HTTPMethod::Post) + ([&, configuration](const crow::request &postRequest) { + auto &cookieCtx = app.get_context(postRequest); + if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { + pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_FREELANCER_ID, + ID_SELECT_FREELANCER_NAME + }); + + + string freelancerName, freelancerID; + pqxx::result freelancerNameResult = Database::executePreparedStatement_SELECT_FREELANCER_NAME(databaseConnection, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL)); + freelancerName = freelancerNameResult.at(0).at(0).c_str(); + pqxx::result freelancerIDResult = Database::executePreparedStatement_SELECT_FREELANCER_ID(databaseConnection, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL)); + freelancerID = freelancerIDResult.at(0).at(0).c_str(); + + string formDataBoundary; + + //get boundary + for (const auto &header: postRequest.headers) { + if (header.first == "Content-Type") { + string boundaryHeaderName = "boundary="; + std::size_t contentTypeStart = header.second.find(boundaryHeaderName); + if (contentTypeStart == string::npos) { + return crow::response(400, "Boundary could not be found"); + break; + } + contentTypeStart += boundaryHeaderName.size() + 1; + formDataBoundary = header.second.substr(contentTypeStart, header.second.size()); + } + } + + //check if boundary is in body + size_t positionBoundaryStart = postRequest.body.find(formDataBoundary); + if (positionBoundaryStart == string::npos) + return crow::response(400, "Content Boundary could not be found in the body of the request"); + size_t positionBoundaryEnd = postRequest.body.find(formDataBoundary + "--"); + if (positionBoundaryEnd == string::npos) + return crow::response(400, "Content Boundary could not be found in the body of the request"); + + //check if content disposition is in body + size_t contentDispositionTypeStart = postRequest.body.find("Content-Disposition"); + if (contentDispositionTypeStart == string::npos) + return crow::response(400, "Content-Disposition could not be found"); + size_t contentDispositionTypeEnd = postRequest.body.find(crow::crlf, contentDispositionTypeStart); + + //check if mustache submission name is in body + if (postRequest.body.find(MUSTACHE_FREELANCER_SUBMISSION_NAME) == string::npos) + return crow::response(400, "Mustache Submission name could not be found in the request"); + + //check if filename is in body + string filenameHeaderName = "filename=\""; + size_t filenamePositionStart = postRequest.body.find(filenameHeaderName); + if (filenamePositionStart == string::npos) + return crow::response(400, "File Submission does not have a filename"); + + filenamePositionStart += filenameHeaderName.size(); + + string filename = postRequest.body.substr(filenamePositionStart, contentDispositionTypeEnd - filenamePositionStart - 1); + + if (!Utilities::checkFiletypeValidity(configuration, filename)) { + return crow::response(400, "Submitted File does not have a valid filetype"); + if (!Utilities::validateFileSize(configuration, postRequest.body)) + return crow::response(400, "File Size is not valid"); + } + + const std::string outputFolderPath = Utilities::generateSubmissionFolderPath(configuration, freelancerName, freelancerID); + + if (!Utilities::validateFolderPath(outputFolderPath)) + return crow::response(400, "Unable to write to Freelancer folder"); + + const std::string& outputFilename = filename; + const std::string outputFilePath = Utilities::generateSubmissionFilePath(outputFolderPath, outputFilename); + + if (!Utilities::validateFilePath(outputFilePath)) + return crow::response(400, "file already exists - hash collision"); + + std::ofstream outputFileStream(outputFilePath); + if (!outputFileStream) + return crow::response(500, "File could not be written to disk"); + + size_t fileContentStart = postRequest.body.find(crow::crlf, contentDispositionTypeEnd + 1); + fileContentStart += 4; + for (size_t i = fileContentStart; i < positionBoundaryEnd - 5; i++) { + outputFileStream << postRequest.body[i]; + } + outputFileStream.close(); + return crow::response(200, "Upload was successfull"); + } + 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) { + auto& cookieCtx = app.get_context(postRequest); + if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { + pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_FREELANCER_ID, + ID_SELECT_FREELANCER_NAME + }); + + + string freelancerName, freelancerID; + pqxx::result freelancerNameResult = Database::executePreparedStatement_SELECT_FREELANCER_NAME(databaseConnection, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL)); + freelancerName = freelancerNameResult.at(0).at(0).c_str(); + pqxx::result freelancerIDResult = Database::executePreparedStatement_SELECT_FREELANCER_ID(databaseConnection, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL)); + freelancerID = freelancerIDResult.at(0).at(0).c_str(); + + + + crow::multipart::message multipartMessage(postRequest); + return crow::response(400); + for (const auto& part : multipartMessage.part_map) + { + const auto& mustacheSubmissionNameValue = part.first; + const auto& fileSubmission = part.second; + if (MUSTACHE_FREELANCER_SUBMISSION_NAME == mustacheSubmissionNameValue) + { + auto contentDispositionIt = fileSubmission.headers.find("Content-Disposition"); + + if (contentDispositionIt == fileSubmission.headers.end()) + return crow::response(400, "Content-Disposition could not be found"); + + auto filenameIt = contentDispositionIt->second.params.find("filename"); + if (filenameIt == contentDispositionIt->second.params.end()) + return crow::response(400, "File Submission does not have a filename"); + + if (!Utilities::checkFiletypeValidity(configuration, filenameIt->second)) + return crow::response(400, "Submitted File does not have a valid filetype"); + + if (!Utilities::validateFileSize(configuration, fileSubmission.body)) + return crow::response(400, "File Size is not valid"); + + const std::string outputFolderPath = Utilities::generateSubmissionFolderPath(configuration, freelancerName, freelancerID); + + if(!Utilities::validateFolderPath(outputFolderPath)) + return crow::response(400, "Unable to write to Freelancer folder"); + + const std::string outputFilename = filenameIt->second; + const std::string outputFilePath = Utilities::generateSubmissionFilePath(outputFolderPath, outputFilename); + cout << outputFolderPath << endl; + cout << outputFilePath << endl; + if(!Utilities::validateFilePath(outputFilePath)) + return crow::response(400, "file already exists - hash collision"); + + std::ofstream outputFileStream(outputFilePath); + if (!outputFileStream) + return crow::response(500, "File could not be written to disk"); + + outputFileStream << fileSubmission.body; + outputFileStream.close(); + } + else + { + return crow::response(400, "Mustache Submission name could not be found in the request"); + } + } + return crow::response(200); + } + else + { + //ERROR not logged in + return crow::response(403, "Not logged in"); + } + });*/ + /* * Page for freelancer to view existing submissions */ CROW_ROUTE(app, "/freelancer/submissionManagement/view") - ([&, configuration](const crow::request& getRequest ) { + ([&, configuration](const crow::request& getRequest) { auto& cookieCtx = app.get_context(getRequest); crow::mustache::context ctx; if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { - - - - ctx[MUSTACHE_COOKIE_LOGGED_IN] = true; } auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_VIEW); return page.render(ctx); }); - /* - * Execute adding of submission - */ - CROW_ROUTE(app, "/freelancer/submissionManagement/add/fulfillment") - ([&, configuration](const crow::request& getRequest ) { - auto& cookieCtx = app.get_context(getRequest); - crow::mustache::context ctx; - if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { - - - - - - - ctx[MUSTACHE_COOKIE_LOGGED_IN] = true; - } - auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_ADD); - return page.render(ctx); - }); - /* * Page for freelancer to generate link to a particular submission */ CROW_ROUTE(app, "/freelancer/submissionManagement/view/generateLink") - ([&, configuration](const crow::request& getRequest ) { + ([&, configuration](const crow::request& getRequest) { auto& cookieCtx = app.get_context(getRequest); crow::mustache::context ctx; if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { - - - - ctx[MUSTACHE_COOKIE_LOGGED_IN] = true; } auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_VIEW_GENERATE_LINK); @@ -1052,64 +1210,6 @@ int main(int argc, char *argv[]) { }); - CROW_ROUTE(app, "/fileuploadtest") - ([&, configuration](const crow::request& getRequest ) { - auto& cookieCtx = app.get_context(getRequest); - crow::mustache::context ctx; - if (Utilities::checkCookieLoginState(configuration, cookieCtx)) { - - - - - - - ctx[MUSTACHE_COOKIE_LOGGED_IN] = true; - } - auto page = crow::mustache::load("TEST_UPLOAD.html"); - return page.render(ctx); - }); - - - CROW_ROUTE(app, "/fileuploadtestExecution").methods(crow::HTTPMethod::Post)([](const crow::request& postRequest) { - crow::multipart::message multipartMessage(postRequest); - for (const auto& part : multipartMessage.part_map) - { - const auto& mustacheSubmissionNameValue = part.first; - const auto& fileSubmission = part.second; - if (MUSTACHE_FREELANCER_SUBMISSION_NAME == mustacheSubmissionNameValue) - { - auto contentDispositionIt = fileSubmission.headers.find("Content-Disposition"); - if (contentDispositionIt == fileSubmission.headers.end()) - { - //ERROR no content disposition found - return crow::response(400); - } - auto filenameIt = contentDispositionIt->second.params.find("filename"); - if (filenameIt == contentDispositionIt->second.params.end()) - { - //ERROR no filename found - return crow::response(400); - } - - const std::string outputFilename = filenameIt->second; - - std::ofstream outputFileStream(outputFilename); - if (!outputFileStream) - { - //ERROR Write to file failed - } - outputFileStream << fileSubmission.body; - outputFileStream.close(); - } - else - { - //ERROR Mustache Submission Name can not be found - } - } - return crow::response(200); - }); - -