Add new template consts

ErrorOut+Log function
Submission upload utility functions
This commit is contained in:
Tina_Azure
2023-07-11 20:21:21 +02:00
parent d4d5b1888d
commit 55eecbb046
3 changed files with 190 additions and 7 deletions

View File

@ -17,13 +17,19 @@ using namespace std;
using namespace TemplateConstCollection;
int main(int argc, char *argv[]) {
Utilities::errorOut("Cavecomm Start", true);
Utilities::config configuration;
if (argc > 1)
configuration.configPath = argv[1];
#ifndef CROW_ENABLE_SSL
Utilities::errorOut("CROW_ENABLE_SSL is not defined and thus SSL is deactivated", true);
#endif
if (configuration.readConfigFile()) {
cout << "ERROR: Unable to read configuration file: " << configuration.configPath << endl;
cout << "Aborting Startup!" << endl;
Utilities::errorOut("Unable to read configuration file: " + configuration.configPath + "\nAborting Startup!");
return 1;
}

View File

@ -87,6 +87,10 @@ namespace TemplateConstCollection {
const static std::string MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_EDIT = "OPERATION_EDIT";
const static std::string MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_DELETE = "OPERATION_DELETE";
const static std::string MUSTACHE_FREELANCER_SUBMISSION_NAME = "FILE_SUBMISSION";
const static std::string MUSTACHE_FREELANCER_AVAILIBLE_STORAGE_IN_MB = "AVAILIBLE_STORAGE_IN_MB";
const static std::string MUSTACHE_FREELANCER_MAXIMUM_STORAGE_IN_MB = "MAXIMUM_STORAGE_IN_MB";
const static std::string MUSTACHE_FREELANCER_ALLOWED_FILE_TYPES_LIST_COMMA_SEPARATED = "ALLOWED_FILE_TYPES_LIST_COMMA_SEPARATED";
const static std::string MUSTACHE_FREELANCER_UPLOAD_AVAILIBLE = "UPLOAD_AVAILIBLE";
//Cookie names
const static std::string COOKIE_LOGIN_KEY = "loginKey";

View File

@ -10,6 +10,7 @@
#include <stdexcept>
#include <thread>
#include <cmath>
#include <unistd.h>
#include <openssl/sha.h>
#include <pqxx/pqxx>
@ -34,6 +35,33 @@ namespace Utilities {
const static std::string MODULE_NAME_FREELANCER_RESET_KEY_CLEANER = "freelancerResetKeyCleaner";
const static std::string MODULE_NAME_SUBMISSION_STORAGE_CLEANER = "submissionStorageCleaner";
/*
* Outputs Error/Warning Messages and writes them to log.txt with a timestamp
*/
void errorOut(const std::string& errorMessage, bool warning = false) {
const auto timePointNow = std::chrono::system_clock::now();
const std::time_t time = std::chrono::system_clock::to_time_t(timePointNow);
if (warning)
std::cout << std::ctime(&time) << "----WARNING----" << std::endl;
else
std::cout << std::ctime(&time) << "----ERROR----" << std::endl;
std::cout << errorMessage << std::endl;
std::cout << "----------------" << std::endl;
std::ofstream logfile;
logfile.open("log.txt", std::ios_base::app);
logfile << std::endl << std::ctime(&time);
if (warning)
logfile << "----WARNING----" << std::endl;
else
logfile << "----ERROR----" << std::endl;
logfile << errorMessage << std::endl;
logfile << "----------------" << std::endl;
logfile.close();
}
/*
* Takes string to split it into a vector based on a given delimiter
*/
@ -68,6 +96,23 @@ namespace Utilities {
return true;
}
/*
* Checks if a path has a valid and accessible folder
*/
bool validateFolderWriteAccess(const std::string& path) {
if (path.empty())
return false;
if(access(path.c_str(), F_OK)) {
errorOut("submissionFileRootPath=" + path + " does not exist");
return false;
}
if(access(path.c_str(), R_OK | W_OK)) {
errorOut("submissionFileRootPath=" + path + " does not have Read/Write access");
return false;
}
return true;
}
/*
* Struct representing the configuration file
*/
@ -92,6 +137,7 @@ namespace Utilities {
int itemsPerPage = 20;
int bruteForceMitigationLockSeconds = 900;
int bruteForceMitigationAttempts = 5;
std::string submissionFileRootPath;
int submissionMaxFileSizeMB = 4096;
int submissionMaxtotalStorageMB = 131072;
int submissionMaxStorageDurationH = 0;
@ -112,6 +158,7 @@ namespace Utilities {
|| sslKeyPath.empty()
#endif
|| domain.empty()
|| !validateFolderWriteAccess(submissionFileRootPath)
)
return 1;
@ -139,7 +186,7 @@ namespace Utilities {
}
else {
errorLevel = 1;
std::cout << "ERROR: Config file is invalid" << std::endl;
errorOut("Config file is invalid");
break;
}
}
@ -228,6 +275,10 @@ namespace Utilities {
bruteForceMitigationAttempts = std::stoi(lineString);
continue;
}
if (lineVector.at(0) == "submissionFileRootPath") {
submissionFileRootPath = lineString;
continue;
}
if (lineVector.at(0) == "submissionMaxFileSizeMB") {
submissionMaxFileSizeMB = std::stoi(lineString);
continue;
@ -354,10 +405,10 @@ namespace Utilities {
std::string createHashSha256(const std::string& str){
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA512_CTX sha256;
SHA512_Init(&sha256);
SHA512_Update(&sha256, str.c_str(), str.size());
SHA512_Final(hash, &sha256);
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str.c_str(), str.size());
SHA256_Final(hash, &sha256);
std::stringstream ss;
@ -367,6 +418,28 @@ namespace Utilities {
return ss.str();
}
/*
* Sha1 hash for quick hash creation with the option to vary digest length to a max of SHA_DIGEST_LENGTH (20)
*/
std::string createShrinkableHashSha1(const std::string& str, size_t digestLength = SHA_DIGEST_LENGTH){
if (digestLength > SHA_DIGEST_LENGTH)
digestLength = SHA_DIGEST_LENGTH;
unsigned char hash[digestLength];
SHA_CTX sha1;
SHA1_Init(&sha1);
SHA1_Update(&sha1, str.c_str(), str.size());
SHA1_Final(hash, &sha1);
std::stringstream ss;
for(int i = 0; i < digestLength; i++){
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>( hash[i] );
}
return ss.str();
}
/*
* Generates a salt using Mersenne Twister
*/
@ -474,6 +547,20 @@ namespace Utilities {
return createHashSha256(generateSalt() + generateSalt());
}
/*
* Generates a hash based on a combination of 2 random salts
*/
std::string generateRandomHashValueSHA1() {
return createShrinkableHashSha1(generateSalt() + generateSalt());
}
/*
* Generates a hash based on a combination of 2 random salts with a limited length
*/
std::string generateRandomHashValueSHA1Short(size_t hashSize) {
return createShrinkableHashSha1(generateSalt() + generateSalt(), hashSize);
}
/*
* Generates a secure cookie
*/
@ -603,5 +690,91 @@ namespace Utilities {
std::string generateAliasRouteFreelancerTemplate(const std::string& freelancerName, const std::string& templateName) {
return "/customer/" + freelancerName + "/template/" + templateName;
}
std::string generateSubmissionFolderPath(const Utilities::config& configuration, const std::string& freelancerName, const std::string& freelancerID){
std::string folderPath = configuration.submissionFileRootPath;
folderPath.append("/");
folderPath.append(freelancerName);
folderPath.append(".");
folderPath.append(freelancerID);
return folderPath;
}
std::string generateSubmissionFilePath(const std::string& folderPath, const std::string& fileName){
std::string filePath = folderPath;
filePath.append("/[");
filePath.append(generateRandomHashValueSHA1Short(5));
filePath.append("]");
filePath.append(fileName);
return filePath;
}
/*
* Checks if a path has a valid and accessible folder and creates the submission folder if it doesn't yet exist
* returns true at success
*/
bool validateFolderPath(const std::string& path) {
if (path.empty()) {
errorOut("submissionFolderPath is empty");
return false;
}
if(access(path.c_str(), F_OK)) {
int errorCode = mkdir(path.c_str(), 0777);
if (errorCode < 0) {
errorOut("submissionFolderPath=" + path + " unable to create folder.");
return false;
}
}
if(access(path.c_str(), R_OK | W_OK)) {
errorOut("submissionFolderPath=" + path + " does not have Read/Write access");
return false;
}
return true;
}
/*
* Checks if a file can be written to a path
* returns true at success
*/
bool validateFilePath(const std::string& path) {
if (path.empty()) {
errorOut("submissionFilePath is empty");
return false;
}
if(access(path.c_str(), F_OK) == 0) {
errorOut("submissionFilePath=" + path + " already exists");
return false;
}
return true;
}
/*
* Checks if a filetype is within the submissionAllowedFiletypes within the config
* takes the config and the filename which has to include the extension
*/
bool checkFiletypeValidity(const Utilities::config& configuration, const std::string& fileName){
bool validity = false;
std::string::size_type position;
position = fileName.rfind('.');
if(position != std::string::npos)
{
std::string extension = fileName.substr(position+1);
for (const std::string& whitelistExtension : configuration.submissionAllowedFiletypes) {
if(extension == whitelistExtension) {
validity = true;
break;
}
}
}
return validity;
}
bool validateFileSize(const Utilities::config& configuration, const std::string& file){
size_t fileSizeMegaBytes = file.size() / 1048576;
if (configuration.submissionMaxFileSizeMB < fileSizeMegaBytes)
return false;
return true;
}
}
#endif