Submission Routes WIP
#30 File upload testable via the logged in acces of /freelancer/submissionManagement/add or the button within the profile page
This commit is contained in:
284
src/main.cpp
284
src/main.cpp
@ -979,18 +979,204 @@ int main(int argc, char *argv[]) {
|
|||||||
auto& cookieCtx = app.get_context<crow::CookieParser>(getRequest);
|
auto& cookieCtx = app.get_context<crow::CookieParser>(getRequest);
|
||||||
crow::mustache::context ctx;
|
crow::mustache::context ctx;
|
||||||
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
|
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
|
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);
|
auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_ADD);
|
||||||
return page.render(ctx);
|
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<crow::CookieParser>(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<crow::CookieParser>(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
|
* Page for freelancer to view existing submissions
|
||||||
*/
|
*/
|
||||||
@ -1001,36 +1187,12 @@ int main(int argc, char *argv[]) {
|
|||||||
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
|
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
|
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
|
||||||
}
|
}
|
||||||
auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_VIEW);
|
auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_VIEW);
|
||||||
return page.render(ctx);
|
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<crow::CookieParser>(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
|
* Page for freelancer to generate link to a particular submission
|
||||||
*/
|
*/
|
||||||
@ -1041,10 +1203,6 @@ int main(int argc, char *argv[]) {
|
|||||||
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
|
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
|
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
|
||||||
}
|
}
|
||||||
auto page = crow::mustache::load(TEMPLATE_FREELANCER_SUBMISSION_MANAGEMENT_VIEW_GENERATE_LINK);
|
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<crow::CookieParser>(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);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user