Compare commits

...

10 Commits

Author SHA1 Message Date
MichaelYick 04dc38a944 Merge pull request 'Template Managment complete' (#27) from dev into master
Reviewed-on: #27
2023-05-23 01:46:47 +00:00
Tina_Azure 9e5f0a68ab Optimize template edit/creation requestbody parsing 2023-05-22 17:04:41 +02:00
Tina_Azure 549c98f673 implement freelancer alias creation 2023-05-19 18:10:52 +02:00
Tina_Azure bfddfd5271 implement freelancer alias deletion 2023-05-19 18:10:31 +02:00
Tina_Azure d83b427857 implement freelancer alias base management page
and minor fixes
2023-05-19 18:07:05 +02:00
Tina_Azure 1620967c45 implementation of the edit function for the template managment
+minor typo fixes
2023-05-17 18:39:32 +02:00
Tina_Azure d9f3fd711c implement base template operations with the corresponding templates
fully implement the delete operation
todo:edit operation
2023-05-15 19:32:21 +02:00
Tina_Azure bbf526f99f minor fix to avoid the creation of '' templates since crow is incapable of routing those to /<string> while trying to route them to / leading to a 404
obviously it's also possible to just give a general you have to name your template directive but as it stands i don't really see a need for it
2023-05-15 19:31:25 +02:00
Tina_Azure 383db248b7 Create new Template
+minor refactoring
2023-05-15 17:52:16 +02:00
Tina_Azure 09406b0852 Template for managment of templates + add button for creation of new template 2023-05-15 16:28:25 +02:00
17 changed files with 921 additions and 71 deletions

View File

@ -39,7 +39,7 @@ sudo -u postgres psql -c "CREATE TABLE freelancers(
sudo -u postgres psql -c "CREATE TABLE templates( sudo -u postgres psql -c "CREATE TABLE templates(
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
freelancerID int, freelancerID int,
name text, name text NOT NULL,
content text, content text,
contactData text, contactData text,
contactInformation text, contactInformation text,

View File

@ -296,7 +296,7 @@ namespace Database {
/* /*
* Executes the prepared statement SELECT_FREELANCER_ID * Executes the prepared statement SELECT_FREELANCER_ID
* Takes an open pqxx::connection and the id to select by * Takes an open pqxx::connection and the email to select by
*/ */
pqxx::result executePreparedStatement_SELECT_FREELANCER_ID(pqxx::connection &connection, const std::string& freelancerEmail) { pqxx::result executePreparedStatement_SELECT_FREELANCER_ID(pqxx::connection &connection, const std::string& freelancerEmail) {
pqxx::work work(connection); pqxx::work work(connection);
@ -305,10 +305,21 @@ namespace Database {
return result; return result;
} }
/*
* Executes the prepared statement SELECT_FREELANCER_NAME
* Takes an open pqxx::connection and the email to select by
*/
pqxx::result executePreparedStatement_SELECT_FREELANCER_NAME(pqxx::connection &connection, const std::string& freelancerEmail) {
pqxx::work work(connection);
pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_NAME, freelancerEmail);
work.commit();
return result;
}
/* /*
* Executes the prepared statement SELECT_CHECK_EMAIL_EXISTS * Executes the prepared statement SELECT_CHECK_EMAIL_EXISTS
* Takes an open pqxx::connection and the emailAddress to check * Takes an open pqxx::connection and the emailAddress to check
* Delivers count of emailaddress occurence 0 for none 1+ for more * Delivers count of emailaddress occurrence 0 for none 1+ for more
*/ */
pqxx::result executePreparedStatement_SELECT_CHECK_EMAIL_EXISTS(pqxx::connection &connection, const std::string& freelancerEmail) { pqxx::result executePreparedStatement_SELECT_CHECK_EMAIL_EXISTS(pqxx::connection &connection, const std::string& freelancerEmail) {
pqxx::work work(connection); pqxx::work work(connection);
@ -320,7 +331,7 @@ namespace Database {
/* /*
* Executes the prepared statement SELECT_CHECK_FREELANCER_LOGIN_STATE * Executes the prepared statement SELECT_CHECK_FREELANCER_LOGIN_STATE
* Takes an open pqxx::connection the loginKey and the id to check * Takes an open pqxx::connection the loginKey and the id to check
* Delivers count of loginValidationKey occurence 0 for none 1+ for more * Delivers count of loginValidationKey occurrence 0 for none 1+ for more
*/ */
pqxx::result executePreparedStatement_SELECT_CHECK_FREELANCER_LOGIN_STATE(pqxx::connection &connection, const std::string& freelancerEmail, const std::string& loginKey) { pqxx::result executePreparedStatement_SELECT_CHECK_FREELANCER_LOGIN_STATE(pqxx::connection &connection, const std::string& freelancerEmail, const std::string& loginKey) {
pqxx::work work(connection); pqxx::work work(connection);
@ -452,6 +463,68 @@ namespace Database {
return result; return result;
} }
/*
* Executes the prepared statement INSERT_FREELANCER_ALIAS
* Takes an open pqxx::connection and aliasname, freelanceremail, route, routeparameter, routevalue
* returns errorLevel
* 0 = no error
* 1 = query error
* 2 = critical error
*/
int executePreparedStatement_INSERT_FREELANCER_ALIAS(pqxx::connection &connection, const std::string& aliasname, const std::string& freelanceremail, const std::string& route, const std::string& routeparameter, const std::string& routevalue) {
try {
pqxx::work work(connection);
work.exec_prepared(PREPARED_STATEMENT_INSERT_FREELANCER_ALIAS, aliasname, freelanceremail, route, routeparameter, routevalue);
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
*/
pqxx::result executePreparedStatement_SELECT_FREELANCER_ALIAS(pqxx::connection &connection, const std::string& freelancerEmail) {
pqxx::work work(connection);
pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_ALIAS, freelancerEmail);
work.commit();
return result;
}
/*
* Executes the prepared statement DELETE_FREELANCER_ALIAS
* Deletes the entry for a reset key based on a freelancer email and the alias name
* Takes an open pqxx::connection and the freelancers email
*/
void executePreparedStatement_DELETE_FREELANCER_ALIAS(pqxx::connection &connection, const std::string& aliasName, const std::string& freelancerEmail) {
pqxx::work work(connection);
work.exec_prepared(PREPARED_STATEMENT_DELETE_FREELANCER_ALIAS, aliasName, freelancerEmail);
work.commit();
}
/*
* Executes the prepared statement SELECT_CHECK_FREELANCER_ALIAS
* Takes an open pqxx::connection and the alias name
* Delivers true if the alias is already used
*/
bool executePreparedStatement_SELECT_CHECK_FREELANCER_ALIAS(pqxx::connection &connection, const std::string& aliasName) {
pqxx::work work(connection);
pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_ALIAS, aliasName);
work.commit();
std::string extractedResult = result.at(0).at(0).c_str();
return extractedResult == "t";
}
/* /*
* Executes the prepared statement UPDATE_LOGIN_VALIDATION_KEY * Executes the prepared statement UPDATE_LOGIN_VALIDATION_KEY
* Takes an open pqxx::connection, the freelancerID and the loginKey to update the entry * Takes an open pqxx::connection, the freelancerID and the loginKey to update the entry
@ -548,6 +621,56 @@ namespace Database {
work.commit(); work.commit();
} }
/*
* Executes the prepared statement INSERT_FREELANCER_TEMPLATE
* Takes an open pqxx::connection and the strings name, content, contactdata, contactinformation, currencypreference, priceupfront, priceondeliver, freelancerEmail
* returns errorLevel
* 0 = no error
* 1 = query error
* 2 = critical error
*/
int executePreparedStatement_INSERT_FREELANCER_TEMPLATE(pqxx::connection &connection, const std::string& name, const std::string& content, const std::string& contactdata, const std::string& contactinformation, const std::string& currencypreference, const std::string& priceupfront, const std::string& priceondeliver, const std::string& freelancerEmail) {
try {
pqxx::work work(connection);
work.exec_prepared(PREPARED_STATEMENT_INSERT_FREELANCER_TEMPLATE, name, content, contactdata, contactinformation, currencypreference, priceupfront, priceondeliver, freelancerEmail);
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 UPDATE_EDIT_FREELANCER_TEMPLATE
* Takes an open pqxx::connection name, content, contactdata, contactinformation, currencypreference, priceupfront, priceondeliver, templateid and the freelancers email
* returns true if update occured
*/
bool executePreparedStatement_UPDATE_EDIT_FREELANCER_TEMPLATE(pqxx::connection &connection, const std::string& name, const std::string& content, const std::string& contactdata, const std::string& contactinformation, const std::string& currencypreference, const std::string& priceupfront, const std::string& priceondeliver, int templateid, const std::string& emailAddress) {
pqxx::work work(connection);
pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_UPDATE_EDIT_FREELANCER_TEMPLATE, name, content, contactdata, contactinformation, currencypreference, priceupfront, priceondeliver, templateid, emailAddress);
work.commit();
return result.affected_rows() != 0;
}
/*
* Executes the prepared statement DELETE_FREELANCER_TEMPLATE
* Deletes a templated based on the id and validated with the freelancer email
* Takes an open pqxx::connection the template id and the freelancers email
*/
void executePreparedStatement_DELETE_FREELANCER_TEMPLATE(pqxx::connection &connection, int templateID, const std::string& freelancerEmail) {
pqxx::work work(connection);
work.exec_prepared(PREPARED_STATEMENT_DELETE_FREELANCER_TEMPLATE, templateID, freelancerEmail);
work.commit();
}
/* /*
* Prepares a statement based on ID * Prepares a statement based on ID
* Takes an open pqxx::connection, the statement id * Takes an open pqxx::connection, the statement id

View File

@ -58,12 +58,19 @@ namespace DatabaseStatementConstCollection {
*/ */
const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_SALT = "selectFreelancerSalt"; const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_SALT = "selectFreelancerSalt";
const static std::string SQL_STATEMENT_SELECT_FREELANCER_SALT = "select salt from freelancers where emailaddress = $1;"; const static std::string SQL_STATEMENT_SELECT_FREELANCER_SALT = "select salt from freelancers where emailaddress = $1;";
/* /*
* Name and Statement for prepared statement to get id using a given email * Name and Statement for prepared statement to get id using a given email
*/ */
const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_ID = "selectFreelancerID"; const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_ID = "selectFreelancerID";
const static std::string SQL_STATEMENT_SELECT_FREELANCER_ID = "select id from freelancers where emailaddress = $1;"; const static std::string SQL_STATEMENT_SELECT_FREELANCER_ID = "select id from freelancers where emailaddress = $1;";
/*
* Name and Statement for prepared statement to get name using a given email
*/
const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_NAME = "selectFreelancerName";
const static std::string SQL_STATEMENT_SELECT_FREELANCER_NAME = "select name from freelancers where emailaddress = $1;";
/* /*
* Name and Statement for prepared statement to check if hash is valid * Name and Statement for prepared statement to check if hash is valid
*/ */
@ -100,6 +107,30 @@ namespace DatabaseStatementConstCollection {
const static std::string PREPARED_STATEMENT_SELECT_ALIAS = "selectAlias"; const static std::string PREPARED_STATEMENT_SELECT_ALIAS = "selectAlias";
const static std::string SQL_STATEMENT_SELECT_ALIAS = "select aliasname, route, routeparameter, routevalue from aliasroutes where aliasname = $1;"; const static std::string SQL_STATEMENT_SELECT_ALIAS = "select aliasname, route, routeparameter, routevalue from aliasroutes where aliasname = $1;";
/*
* Name and Statement for prepared statement to select an alias and its route via the alias name
*/
const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_ALIAS = "selectFreelancerAlias";
const static std::string SQL_STATEMENT_SELECT_FREELANCER_ALIAS = "select aliasname, route from aliasroutes where freelancerid = (select freelancers.id from freelancers where emailaddress = $1);";
/*
* Name and Statement for prepared statement to select an alias and its route via the alias name
*/
const static std::string PREPARED_STATEMENT_DELETE_FREELANCER_ALIAS = "deleteFreelancerAlias";
const static std::string SQL_STATEMENT_DELETE_FREELANCER_ALIAS = "delete from aliasroutes where aliasname = $1 and freelancerid = (select freelancers.id from freelancers where emailaddress = $2);";
/*
* Name and Statement for prepared statement to select an alias and its route via the alias name
*/
const static std::string PREPARED_STATEMENT_INSERT_FREELANCER_ALIAS = "insertFreelancerAlias";
const static std::string SQL_STATEMENT_INSERT_FREELANCER_ALIAS = "insert into aliasroutes (aliasname, freelancerid, route, routeparameter, routevalue) VALUES($1, (select freelancers.id from freelancers where emailaddress = $2), $3, $4, $5);";
/*
* Name and Statement for prepared statement to try to check if an alias already exists
*/
const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_ALIAS = "selectCheckFreelancerAlias";
const static std::string SQL_STATEMENT_SELECT_CHECK_FREELANCER_ALIAS = "select count(*) = 1 from aliasroutes where aliasname = $1;";
/* /*
* Name and Statement for prepared statement to update the loginvalidationkey of a freelancer via the freelancerID * Name and Statement for prepared statement to update the loginvalidationkey of a freelancer via the freelancerID
*/ */
@ -125,7 +156,7 @@ namespace DatabaseStatementConstCollection {
const static std::string SQL_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY = "select freelanceremail from passwordresetkeys where passwordresetkey = $1;"; const static std::string SQL_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY = "select freelanceremail from passwordresetkeys where passwordresetkey = $1;";
/* /*
* Name and Statement for prepared statement to check if an reset key is expired * Name and Statement for prepared statement to check if a reset key is expired
* returns 0 if key not expired * returns 0 if key not expired
*/ */
const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED = "checkFreelancerResetKeyExpired"; const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED = "checkFreelancerResetKeyExpired";
@ -186,6 +217,25 @@ namespace DatabaseStatementConstCollection {
const static std::string PREPARED_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT = "updateExpirationLoginLockOut"; const static std::string PREPARED_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT = "updateExpirationLoginLockOut";
const static std::string SQL_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT = "update loginlockout set (attempts, expiration) = (0, CURRENT_TIMESTAMP + make_interval(secs => $2)) where email = $1;"; const static std::string SQL_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT = "update loginlockout set (attempts, expiration) = (0, CURRENT_TIMESTAMP + make_interval(secs => $2)) where email = $1;";
/*
* Name and Statement for prepared statement to try to add a new template to a freelancer
* $1-8 -> name, content, contactdata, contactinformation, currencypreference, priceupfront, priceondeliver, emailaddress
*/
const static std::string PREPARED_STATEMENT_INSERT_FREELANCER_TEMPLATE = "insertFreelancerTemplate";
const static std::string SQL_STATEMENT_INSERT_FREELANCER_TEMPLATE = "INSERT INTO templates(freelancerid, name, content, contactdata, contactinformation, currencypreference, priceupfront, priceondeliver) VALUES((select freelancers.id from freelancers where emailaddress = $8), $1, $2, $3, $4, $5, $6, $7);";
/*
* Name and Statement for prepared statement to update the template of a freelancer
*/
const static std::string PREPARED_STATEMENT_UPDATE_EDIT_FREELANCER_TEMPLATE = "updateEeditFreelancerTemplate";
const static std::string SQL_STATEMENT_UPDATE_EDIT_FREELANCER_TEMPLATE = "UPDATE templates SET (name, content, contactdata, contactinformation, currencypreference, priceupfront, priceondeliver) = ($1, $2, $3, $4, $5, $6, $7) WHERE id = $8 and freelancerid = (select freelancers.id from freelancers where emailaddress = $9);";
/*
* Name and Statement for prepared statement to delete a template with ownership validation
*/
const static std::string PREPARED_STATEMENT_DELETE_FREELANCER_TEMPLATE = "deleteFreelancerTemplate";
const static std::string SQL_STATEMENT_DELETE_FREELANCER_TEMPLATE = "delete from templates where id = $1 and freelancerid = (select freelancers.id from freelancers where emailaddress = $2);";
/* /*
* IDs of prepared statements * IDs of prepared statements
*/ */
@ -218,6 +268,14 @@ namespace DatabaseStatementConstCollection {
const static int ID_INSERT_LOGIN_LOCK_OUT = 26; const static int ID_INSERT_LOGIN_LOCK_OUT = 26;
const static int ID_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS = 27; const static int ID_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS = 27;
const static int ID_UPDATE_EXPIRATION_LOGIN_LOCK_OUT = 28; const static int ID_UPDATE_EXPIRATION_LOGIN_LOCK_OUT = 28;
const static int ID_INSERT_FREELANCER_TEMPLATE = 29;
const static int ID_DELETE_FREELANCER_TEMPLATE = 30;
const static int ID_UPDATE_EDIT_FREELANCER_TEMPLATE = 31;
const static int ID_SELECT_FREELANCER_ALIAS = 32;
const static int ID_DELETE_FREELANCER_ALIAS = 33;
const static int ID_INSERT_FREELANCER_ALIAS = 34;
const static int ID_SELECT_CHECK_FREELANCER_ALIAS = 35;
const static int ID_SELECT_FREELANCER_NAME = 36;
/* /*
* Easy access to prepared statements via prepared statement name * Easy access to prepared statements via prepared statement name
@ -251,7 +309,15 @@ namespace DatabaseStatementConstCollection {
{PREPARED_STATEMENT_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS, SQL_STATEMENT_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS}, {PREPARED_STATEMENT_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS, SQL_STATEMENT_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS},
{PREPARED_STATEMENT_INSERT_LOGIN_LOCK_OUT, SQL_STATEMENT_INSERT_LOGIN_LOCK_OUT}, {PREPARED_STATEMENT_INSERT_LOGIN_LOCK_OUT, SQL_STATEMENT_INSERT_LOGIN_LOCK_OUT},
{PREPARED_STATEMENT_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS, SQL_STATEMENT_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS}, {PREPARED_STATEMENT_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS, SQL_STATEMENT_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS},
{PREPARED_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT, SQL_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT} {PREPARED_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT, SQL_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT},
{PREPARED_STATEMENT_INSERT_FREELANCER_TEMPLATE, SQL_STATEMENT_INSERT_FREELANCER_TEMPLATE},
{PREPARED_STATEMENT_DELETE_FREELANCER_TEMPLATE, SQL_STATEMENT_DELETE_FREELANCER_TEMPLATE},
{PREPARED_STATEMENT_UPDATE_EDIT_FREELANCER_TEMPLATE, SQL_STATEMENT_UPDATE_EDIT_FREELANCER_TEMPLATE},
{PREPARED_STATEMENT_SELECT_FREELANCER_ALIAS, SQL_STATEMENT_SELECT_FREELANCER_ALIAS},
{PREPARED_STATEMENT_DELETE_FREELANCER_ALIAS, SQL_STATEMENT_DELETE_FREELANCER_ALIAS},
{PREPARED_STATEMENT_INSERT_FREELANCER_ALIAS, SQL_STATEMENT_INSERT_FREELANCER_ALIAS},
{PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_ALIAS, SQL_STATEMENT_SELECT_CHECK_FREELANCER_ALIAS},
{PREPARED_STATEMENT_SELECT_FREELANCER_NAME, SQL_STATEMENT_SELECT_FREELANCER_NAME}
}; };
/* /*
* Easy access to prepared statement name via int * Easy access to prepared statement name via int
@ -285,7 +351,15 @@ namespace DatabaseStatementConstCollection {
{ID_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS, PREPARED_STATEMENT_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS}, {ID_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS, PREPARED_STATEMENT_UPDATE_INCREMENT_LOGIN_LOCK_OUT_ATTEMPTS},
{ID_INSERT_LOGIN_LOCK_OUT, PREPARED_STATEMENT_INSERT_LOGIN_LOCK_OUT}, {ID_INSERT_LOGIN_LOCK_OUT, PREPARED_STATEMENT_INSERT_LOGIN_LOCK_OUT},
{ID_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS, PREPARED_STATEMENT_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS}, {ID_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS, PREPARED_STATEMENT_SELECT_CHECK_LOGIN_LOCK_OUT_ATTEMPTS},
{ID_UPDATE_EXPIRATION_LOGIN_LOCK_OUT, PREPARED_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT} {ID_UPDATE_EXPIRATION_LOGIN_LOCK_OUT, PREPARED_STATEMENT_UPDATE_EXPIRATION_LOGIN_LOCK_OUT},
{ID_INSERT_FREELANCER_TEMPLATE, PREPARED_STATEMENT_INSERT_FREELANCER_TEMPLATE},
{ID_DELETE_FREELANCER_TEMPLATE, PREPARED_STATEMENT_DELETE_FREELANCER_TEMPLATE},
{ID_UPDATE_EDIT_FREELANCER_TEMPLATE, PREPARED_STATEMENT_UPDATE_EDIT_FREELANCER_TEMPLATE},
{ID_SELECT_FREELANCER_ALIAS, PREPARED_STATEMENT_SELECT_FREELANCER_ALIAS},
{ID_DELETE_FREELANCER_ALIAS, PREPARED_STATEMENT_DELETE_FREELANCER_ALIAS},
{ID_INSERT_FREELANCER_ALIAS, PREPARED_STATEMENT_INSERT_FREELANCER_ALIAS},
{ID_SELECT_CHECK_FREELANCER_ALIAS, PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_ALIAS},
{ID_SELECT_FREELANCER_NAME, PREPARED_STATEMENT_SELECT_FREELANCER_NAME}
}; };
/* /*

View File

@ -1,7 +1,6 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <thread> #include <thread>
#include <map>
#include <pqxx/pqxx> #include <pqxx/pqxx>
@ -72,7 +71,7 @@ int main(int argc, char *argv[]) {
*/ */
CROW_ROUTE(app, "/@<string>") CROW_ROUTE(app, "/@<string>")
([configuration](string alias) { ([configuration](string alias) {
crow::mustache::context ctx(getAlias(configuration, alias)); crow::mustache::context ctx(Utilities::getAlias(configuration, alias));
auto page = crow::mustache::load(TEMPLATE_ALIAS_REDIRECT); auto page = crow::mustache::load(TEMPLATE_ALIAS_REDIRECT);
return page.render(ctx); return page.render(ctx);
}); });
@ -144,7 +143,7 @@ int main(int argc, char *argv[]) {
if (!resultTemplate.empty()) { if (!resultTemplate.empty()) {
//use freelancerID based on SQL_STATEMENT_SELECT_TEMPLATE //use freelancerID based on SQL_STATEMENT_SELECT_TEMPLATE
pqxx::result resultCommissionState = Database::executePreparedStatement_SELECT_FREELANCER_COMMISSION_STATE(databaseConnection, stoi(resultTemplate.at(0).at(2).c_str())); pqxx::result resultCommissionState = Database::executePreparedStatement_SELECT_FREELANCER_COMMISSION_STATE(databaseConnection, stoi(resultTemplate.at(0).at(2).c_str()));
//the commissionstate //the commission-state
if (resultCommissionState.empty() || stoi(resultCommissionState.at(0).at(0).c_str()) == 1) if (resultCommissionState.empty() || stoi(resultCommissionState.at(0).at(0).c_str()) == 1)
commissionState = true; commissionState = true;
} }
@ -230,7 +229,7 @@ int main(int argc, char *argv[]) {
pqxx::result resultCommissionState = Database::executePreparedStatement_SELECT_FREELANCER_COMMISSION_STATE(databaseConnection, newRequest.freelancerID); pqxx::result resultCommissionState = Database::executePreparedStatement_SELECT_FREELANCER_COMMISSION_STATE(databaseConnection, newRequest.freelancerID);
//the commissionstate //the commission-state
if (resultCommissionState.empty() || stoi(resultCommissionState.at(0).at(0).c_str()) == 1) { if (resultCommissionState.empty() || stoi(resultCommissionState.at(0).at(0).c_str()) == 1) {
ctx[MUSTACHE_ERROR_COMMISSIONS_CLOSED] = true; ctx[MUSTACHE_ERROR_COMMISSIONS_CLOSED] = true;
} }
@ -639,7 +638,7 @@ int main(int argc, char *argv[]) {
}); });
/* /*
* Page for freelancer to create/delete/edit Templates * Page for freelancer to create/select Templates
*/ */
CROW_ROUTE(app, "/freelancer/templateManagement") CROW_ROUTE(app, "/freelancer/templateManagement")
([&, configuration](const crow::request& getRequest ) { ([&, configuration](const crow::request& getRequest ) {
@ -655,7 +654,60 @@ int main(int argc, char *argv[]) {
}); });
/* /*
* Page for freelancer to create/delete/edit Templates * Page for freelancer to create new Template
*/
CROW_ROUTE(app, "/freelancer/templateManagement/template/new")
([&, 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_TEMPLATE_MANAGEMENT_CREATE_NEW);
return page.render(ctx);
});
/*
* Page for freelancer to create new Template fulfilment
*/
CROW_ROUTE(app, "/freelancer/templateManagement/template/new/fulfilment").methods("POST"_method)
([&, configuration](const crow::request& postRequest ) {
auto& cookieCtx = app.get_context<crow::CookieParser>(postRequest);
crow::mustache::context ctx;
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
Utilities::templateItem newTemplate;
string postRequestBody = postRequest.body;
Utilities::decodeString(postRequestBody);
newTemplate.parseRequestBodyIntoItem(postRequestBody);
newTemplate.outputItem();
pqxx::connection databaseConnection(configuration.databaseConnectionString);
Database::prepareStatement(databaseConnection, ID_INSERT_FREELANCER_TEMPLATE);
int errorLevel = Database::executePreparedStatement_INSERT_FREELANCER_TEMPLATE(
databaseConnection, newTemplate.name, newTemplate.content, newTemplate.contactdata, newTemplate.contactinformation,
newTemplate.currencypreference, newTemplate.priceupfront, newTemplate.priceondeliver, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL));
if (errorLevel == 0) {
ctx["templatename"] = newTemplate.name;
ctx["contactdata"] = newTemplate.contactdata;
ctx["contactinformation"] = newTemplate.contactinformation;
ctx["currencypreference"] = newTemplate.currencypreference;
ctx["priceupfront"] = newTemplate.priceupfront;
ctx["priceondeliver"] = newTemplate.priceondeliver;
ctx["content"] = newTemplate.content;
}
else {
ctx[MUSTACHE_FREELANCER_TEMPLATE_CREATION_ERROR] = true;
}
}
auto page = crow::mustache::load(TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_CREATE_NEW_FULFILMENT);
return page.render(ctx);
});
/*
* Page for freelancer to view/delete/edit a Template
*/ */
CROW_ROUTE(app, "/freelancer/templateManagement/template/<string>").methods("POST"_method) CROW_ROUTE(app, "/freelancer/templateManagement/template/<string>").methods("POST"_method)
([&, configuration](const crow::request& postRequest, string templateName ) { ([&, configuration](const crow::request& postRequest, string templateName ) {
@ -691,11 +743,203 @@ int main(int argc, char *argv[]) {
} }
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true; ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
} }
auto page = crow::mustache::load(TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_FULFILMENT); auto page = crow::mustache::load(TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_FULFILMENT_STAGE_CONFIRMATION);
return page.render(ctx); return page.render(ctx);
}); });
/*
* Execute Template Operation
*/
CROW_ROUTE(app, "/freelancer/templateManagement/fulfilment/<string>").methods("POST"_method)
([&, configuration](const crow::request& postRequest, string operation ) {
auto& cookieCtx = app.get_context<crow::CookieParser>(postRequest);
crow::mustache::context ctx;
bool operationEdit = false;
bool operationDelete = false;
bool error = false;
if (operation == MUSTACHE_FREELANCER_TEMPLATE_OPERATION_EDIT) {
operationEdit = true;
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_EDIT] = true;
}
else if (operation == MUSTACHE_FREELANCER_TEMPLATE_OPERATION_DELETE) {
operationDelete = true;
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_DELETE] = true;
}
else {
error = true;
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_ERROR] = true;
}
if (!error) {
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
string freelancerEmail = cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL);
string postRequestBody = postRequest.body;
Utilities::decodeString(postRequestBody);
int templateid;
vector<string> splitPostRequestBody = Utilities::splitStringIntoVector(postRequestBody, '&');
for (const string& item : splitPostRequestBody) {
vector<string> splitItem = Utilities::splitStringIntoVector(item, '=');
if (splitItem[0] == "templateid") {
templateid = stoi(splitItem[1]);
break;
}
}
pqxx::connection databaseConnection(configuration.databaseConnectionString);
if (operationEdit) {
Utilities::templateItem toEditTemplate;
Database::prepareStatement(databaseConnection, ID_UPDATE_EDIT_FREELANCER_TEMPLATE);
toEditTemplate.parseRequestBodyIntoItem(postRequestBody);
toEditTemplate.outputItem();
bool updateSuccess = Database::executePreparedStatement_UPDATE_EDIT_FREELANCER_TEMPLATE(
databaseConnection, toEditTemplate.name, toEditTemplate.content, toEditTemplate.contactdata, toEditTemplate.contactinformation,
toEditTemplate.currencypreference, toEditTemplate.priceupfront, toEditTemplate.priceondeliver, templateid, freelancerEmail);
if (updateSuccess) {
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_COMPLETE] = true;
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_EDIT] = true;
}
else {
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_ERROR] = true;
}
} else if (operationDelete) {
Database::prepareStatement(databaseConnection, ID_DELETE_FREELANCER_TEMPLATE);
Database::executePreparedStatement_DELETE_FREELANCER_TEMPLATE(databaseConnection, templateid, freelancerEmail);
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_COMPLETE] = true;
ctx[MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_DELETE] = true;
}
}
}
auto page = crow::mustache::load(TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_FULFILMENT_STAGE_EXECUTION);
return page.render(ctx);
});
/*
* Page for freelancer to create/delete Alias
*/
CROW_ROUTE(app, "/freelancer/aliasManagement")
([&, configuration](const crow::request& getRequest ) {
auto& cookieCtx = app.get_context<crow::CookieParser>(getRequest);
crow::mustache::context ctx;
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
ctx = Utilities::getFreelancerAlias(configuration, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL));
ctx["freelanceremail"] = cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL);
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
}
auto page = crow::mustache::load(TEMPLATE_FREELANCER_ALIAS_MANAGEMENT);
return page.render(ctx);
});
/*
* Execute Alias deletion
*/
CROW_ROUTE(app, "/freelancer/aliasManagement/delete").methods("POST"_method)
([&, configuration](const crow::request& postRequest) {
auto& cookieCtx = app.get_context<crow::CookieParser>(postRequest);
crow::mustache::context ctx;
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
string postRequestBody = postRequest.body;
Utilities::decodeString(postRequestBody);
string aliasName;
vector<string> splitPostRequestBody = Utilities::splitStringIntoVector(postRequestBody, '&');
for (const string& item : splitPostRequestBody) {
vector<string> splitItem = Utilities::splitStringIntoVector(item, '=');
if (splitItem.at(0) == "alias")
aliasName = splitItem.at(1);
}
Utilities::deleteFreelancerAlias(configuration, aliasName, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL));
ctx["freelanceremail"] = cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL);
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
}
auto page = crow::mustache::load(TEMPLATE_FREELANCER_ALIAS_MANAGEMENT_DELETE);
return page.render(ctx);
});
/*
* Page for freelancer to create alias
*/
CROW_ROUTE(app, "/freelancer/aliasManagement/new")
([&, configuration](const crow::request& getRequest ) {
auto& cookieCtx = app.get_context<crow::CookieParser>(getRequest);
crow::mustache::context ctx;
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
ctx = Utilities::getFreelancerTemplates(configuration, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL));
ctx["freelanceremail"] = cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL);
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
}
auto page = crow::mustache::load(TEMPLATE_FREELANCER_ALIAS_MANAGEMENT_NEW);
return page.render(ctx);
});
/*
* Execute alias creation
*/
CROW_ROUTE(app, "/freelancer/aliasManagement/new/fulfilment").methods("POST"_method)
([&, configuration](const crow::request& postRequest) {
auto& cookieCtx = app.get_context<crow::CookieParser>(postRequest);
crow::mustache::context ctx;
if (Utilities::checkCookieLoginState(configuration, cookieCtx)) {
bool error = false;
ctx[MUSTACHE_COOKIE_LOGGED_IN] = true;
string postRequestBody = postRequest.body;
Utilities::decodeString(postRequestBody);
vector<string> splitPostRequestBody = Utilities::splitStringIntoVector(postRequestBody, '&');
string aliasname, templateNameID, templateName;
for (const string& item : splitPostRequestBody) {
vector<string> splitItem = Utilities::splitStringIntoVector(item, '=');
if (splitItem.at(0) == "freelanceralias")
aliasname = splitItem.at(1);
if (splitItem.at(0) == "aliasroute")
templateNameID = splitItem.at(1);
}
pqxx::connection databaseConnection(configuration.databaseConnectionString);
Database::prepareStatements(databaseConnection, {
ID_SELECT_CHECK_FREELANCER_ALIAS,
ID_INSERT_FREELANCER_ALIAS,
ID_SELECT_FREELANCER_ID,
ID_SELECT_FREELANCER_NAME
});
bool aliasAlreadyUsed = false;
if (aliasname.empty()) {
error = true;
ctx[MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR] = true;
ctx[MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR_UNNAMED] = true;
} else {
ctx["aliasname"] = aliasname;
aliasAlreadyUsed = Database::executePreparedStatement_SELECT_CHECK_FREELANCER_ALIAS(databaseConnection, aliasname);
}
if (aliasAlreadyUsed) {
error = true;
ctx[MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR] = true;
ctx[MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR_DUPLICATE] = true;
}
if (!error) {
string route, routeparameter, routevalue;
pqxx::result freelancerNameResult = Database::executePreparedStatement_SELECT_FREELANCER_NAME(databaseConnection, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL));
if (templateNameID.empty()) {
routeparameter = "freelancerID";
pqxx::result freelancerIDResult = Database::executePreparedStatement_SELECT_FREELANCER_ID(databaseConnection, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL));
routevalue = freelancerIDResult.at(0).at(0).c_str();
route = Utilities::generateAliasRouteFreelancer(freelancerNameResult.at(0).at(0).c_str());
} else {
routeparameter = "templateID";
vector<string> splitValues = Utilities::splitStringIntoVector(templateNameID, '|');
routevalue = splitValues.at(1);
route = Utilities::generateAliasRouteFreelancerTemplate(freelancerNameResult.at(0).at(0).c_str(), splitValues.at(0));
}
int errorLevel = Database::executePreparedStatement_INSERT_FREELANCER_ALIAS(databaseConnection, aliasname, cookieCtx.get_cookie(COOKIE_FREELANCER_EMAIL), route, routeparameter, routevalue);
ctx["aliasname"] = aliasname;
if (errorLevel != 0)
ctx[MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR] = true;
}
}
auto page = crow::mustache::load(TEMPLATE_FREELANCER_ALIAS_MANAGEMENT_NEW_FULFILMENT);
return page.render(ctx);
});

View File

@ -25,7 +25,14 @@ namespace TemplateConstCollection {
const static std::string TEMPLATE_FREELANCER_REDIRECT_PROFILE = "freelancer_Redirect_Profile.html"; const static std::string TEMPLATE_FREELANCER_REDIRECT_PROFILE = "freelancer_Redirect_Profile.html";
const static std::string TEMPLATE_FREELANCER_PROFILE = "freelancer_Profile.html"; const static std::string TEMPLATE_FREELANCER_PROFILE = "freelancer_Profile.html";
const static std::string TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT = "freelancer_Template_Management.html"; const static std::string TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT = "freelancer_Template_Management.html";
const static std::string TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_FULFILMENT = "freelancer_Template_Management_Fulfilment.html"; const static std::string TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_FULFILMENT_STAGE_CONFIRMATION = "freelancer_Template_Management_Fulfilment_Stage_Confirmation.html";
const static std::string TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_FULFILMENT_STAGE_EXECUTION = "freelancer_Template_Management_Fulfilment_Stage_Execution.html";
const static std::string TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_CREATE_NEW = "freelancer_Template_Management_Create_New.html";
const static std::string TEMPLATE_FREELANCER_TEMPLATE_MANAGEMENT_CREATE_NEW_FULFILMENT = "freelancer_Template_Management_Create_New_Fulfilment.html";
const static std::string TEMPLATE_FREELANCER_ALIAS_MANAGEMENT = "freelancer_Alias_Management.html";
const static std::string TEMPLATE_FREELANCER_ALIAS_MANAGEMENT_DELETE = "freelancer_Alias_Management_Delete.html";
const static std::string TEMPLATE_FREELANCER_ALIAS_MANAGEMENT_NEW = "freelancer_Alias_Management_New.html";
const static std::string TEMPLATE_FREELANCER_ALIAS_MANAGEMENT_NEW_FULFILMENT = "freelancer_Alias_Management_New_Fulfilment.html";
//Mustache Error/Success variable names //Mustache Error/Success variable names
const static std::string MUSTACHE_ERROR_COMMISSIONS_CLOSED = "ERROR_COMMISSIONS_CLOSED"; const static std::string MUSTACHE_ERROR_COMMISSIONS_CLOSED = "ERROR_COMMISSIONS_CLOSED";
@ -54,6 +61,12 @@ namespace TemplateConstCollection {
const static std::string MUSTACHE_RESET_SUCCESS = "RESET_SUCCESS"; const static std::string MUSTACHE_RESET_SUCCESS = "RESET_SUCCESS";
const static std::string MUSTACHE_LOGIN_SUCCESS = "LOGIN_SUCCESS"; const static std::string MUSTACHE_LOGIN_SUCCESS = "LOGIN_SUCCESS";
const static std::string MUSTACHE_FREELANCER_TEMPLATE_OPERATION_ERROR_NO_TEMPLATE = "TEMPLATE_OPERATION_ERROR_NO_TEMPLATE"; const static std::string MUSTACHE_FREELANCER_TEMPLATE_OPERATION_ERROR_NO_TEMPLATE = "TEMPLATE_OPERATION_ERROR_NO_TEMPLATE";
const static std::string MUSTACHE_FREELANCER_TEMPLATE_OPERATION_COMPLETE = "TEMPLATE_OPERATION_COMPLETE";
const static std::string MUSTACHE_FREELANCER_TEMPLATE_CREATION_ERROR = "TEMPLATE_CREATION_ERROR";
const static std::string MUSTACHE_FREELANCER_TEMPLATE_OPERATION_FULFILMENT_ERROR = "OPERATION_ERROR";
const static std::string MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR = "ALIAS_CREATION_ERROR";
const static std::string MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR_DUPLICATE = "ALIAS_CREATION_ERROR_DUPLICATE";
const static std::string MUSTACHE_FREELANCER_ALIAS_CREATION_ERROR_UNNAMED = "ALIAS_CREATION_ERROR_UNNAMED";
//Mustache Cookie variable names //Mustache Cookie variable names
const static std::string MUSTACHE_COOKIE_LOGGED_IN = "COOKIE_LOGGED_IN"; const static std::string MUSTACHE_COOKIE_LOGGED_IN = "COOKIE_LOGGED_IN";

View File

@ -59,6 +59,19 @@ namespace Utilities {
return stringToTrim; return stringToTrim;
} }
/*
* Checks if a given string is a valid number
*/
bool checkIfStrIsNumber(const std::string& numberString) {
try {
std::stod(numberString);
}
catch (const std::invalid_argument& ia) {
return false;
}
return true;
}
/* /*
* Struct representing the configuration file * Struct representing the configuration file
*/ */
@ -227,6 +240,54 @@ namespace Utilities {
} }
}; };
/*
* Struct representing a freelancers template
*/
struct templateItem {
std::string name;
std::string content;
std::string contactdata;
std::string contactinformation;
std::string currencypreference;
std::string priceupfront;
std::string priceondeliver;
/*
* Parses a decoded request body string and fills the struct
*/
void parseRequestBodyIntoItem(const std::string& requestBody) {
std::vector<std::string> splitPostRequestBody = Utilities::splitStringIntoVector(requestBody, '&');
for (const std::string& item : splitPostRequestBody) {
std::vector<std::string> splitItem = Utilities::splitStringIntoVector(item, '=');
if (splitItem[0] == "templatename")
name = splitItem[1];
if (splitItem[0] == "templatecontent")
content = splitItem[1];
if (splitItem[0] == "templatecontactdata")
contactdata = splitItem[1];
if (splitItem[0] == "templatecontactinformation")
contactinformation = splitItem[1];
if (splitItem[0] == "templatecurrencypreference")
currencypreference = splitItem[1];
if (splitItem[0] == "templatepriceupfront")
priceupfront = splitItem[1];
if (splitItem[0] == "templatepriceondeliver")
priceondeliver = splitItem[1];
}
if (name.empty())
name = "unnamed";
if (!checkIfStrIsNumber(priceupfront))
priceupfront = "0";
if (!checkIfStrIsNumber(priceondeliver))
priceondeliver = "0";
}
void outputItem() {
std::cout << name << " " << content << " " << contactdata << " " << contactinformation << " " << currencypreference
<< " " << priceupfront << "-" << priceondeliver << " " << std::endl;
}
};
/* /*
* Takes String and cuts from the start-up to the length of valueName * Takes String and cuts from the start-up to the length of valueName
*/ */
@ -359,9 +420,11 @@ namespace Utilities {
* returns crow::json::wvalue with the Alias * returns crow::json::wvalue with the Alias
*/ */
crow::json::wvalue getAlias(const Utilities::config& configuration, const std::string& alias) { crow::json::wvalue getAlias(const Utilities::config& configuration, const std::string& alias) {
std::string decodedAlias = alias;
decodeString(decodedAlias);
pqxx::connection databaseConnection(configuration.databaseConnectionString); pqxx::connection databaseConnection(configuration.databaseConnectionString);
Database::prepareStatement(databaseConnection, ID_SELECT_ALIAS); Database::prepareStatement(databaseConnection, ID_SELECT_ALIAS);
pqxx::result resultAlias = Database::executePreparedStatement_SELECT_ALIAS(databaseConnection, alias); pqxx::result resultAlias = Database::executePreparedStatement_SELECT_ALIAS(databaseConnection, decodedAlias);
crow::json::wvalue resultJsonAlias; crow::json::wvalue resultJsonAlias;
if (!resultAlias.empty()) if (!resultAlias.empty())
resultJsonAlias = Database::convertResultRowToJSON(resultAlias); resultJsonAlias = Database::convertResultRowToJSON(resultAlias);
@ -505,6 +568,10 @@ namespace Utilities {
} }
} }
/*
* Gets the freelancer templates and converts them into a wvalue JSON under the name "templates"
* takes config and freelancer email
*/
crow::json::wvalue getFreelancerTemplates(const Utilities::config& configuration, const std::string& emailAddress) { crow::json::wvalue getFreelancerTemplates(const Utilities::config& configuration, const std::string& emailAddress) {
crow::json::wvalue resultJsonFreelancerTemplate; crow::json::wvalue resultJsonFreelancerTemplate;
@ -522,5 +589,44 @@ namespace Utilities {
} }
return resultJsonFreelancerTemplate; return resultJsonFreelancerTemplate;
} }
/*
* Gets the freelancer alias and converts them into a wvalue JSON under the name "alias"
* takes config and freelancer email
*/
crow::json::wvalue getFreelancerAlias(const Utilities::config& configuration, const std::string& emailAddress) {
crow::json::wvalue resultJsonFreelancerAlias;
pqxx::connection databaseConnection(configuration.databaseConnectionString);
Database::prepareStatement(databaseConnection, ID_SELECT_FREELANCER_ALIAS);
pqxx::result aliasResult = Database::executePreparedStatement_SELECT_FREELANCER_ALIAS(databaseConnection, emailAddress);
resultJsonFreelancerAlias = Database::convertResultToJSON(aliasResult, "alias");
return resultJsonFreelancerAlias;
}
/*
* Deletes a freelancers alias
* takes config the alias name and the freelancers email
*/
void deleteFreelancerAlias(const Utilities::config& configuration, const std::string& aliasName, const std::string& emailAddress) {
pqxx::connection databaseConnection(configuration.databaseConnectionString);
Database::prepareStatement(databaseConnection, ID_DELETE_FREELANCER_ALIAS);
Database::executePreparedStatement_DELETE_FREELANCER_ALIAS(databaseConnection, aliasName, emailAddress);
}
/*
* Generates an alias route to the freelancers profile
* takes a freelancers name
*/
std::string generateAliasRouteFreelancer(const std::string& freelancerName) {
return "/customer/" + freelancerName;
}
/*
* Generates an alias route to the freelancers template
* takes a freelancers and a templates name
*/
std::string generateAliasRouteFreelancerTemplate(const std::string& freelancerName, const std::string& templateName) {
return "/customer/" + freelancerName + "/template/" + templateName;
}
} }
#endif #endif

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
{{^COOKIE_LOGGED_IN}}
Please Log in.
{{/COOKIE_LOGGED_IN}}
{{#COOKIE_LOGGED_IN}}
<h2>Freelancer: {{freelanceremail}}</h2>
<br>
<br>
<table>
{{#alias}}
<tr>
<th>@{{aliasname}}</th>
<th>{{route}}</th>
<th>
<form action="/freelancer/aliasManagement/delete" method="post">
<button type="submit" name="alias" value="{{aliasname}}" class="button">Delete</button>
</form>
</th>
</tr>
{{/alias}}
</table>
<form action="/freelancer/aliasManagement/new" method="get">
<button type="submit" class="button">Create New Alias Route</button>
</form>
{{/COOKIE_LOGGED_IN}}
{{> templateIncludes/freelancerLoginSignupProfileLogoutInterface.html.html}}
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
{{^COOKIE_LOGGED_IN}}
Please Log in.
{{/COOKIE_LOGGED_IN}}
{{#COOKIE_LOGGED_IN}}
Operation concluded:
<br>
<form action="/freelancer/aliasManagement" method="get">
<button type="submit" class="button">Return to Alias Managment</button>
</form>
<form action="/freelancer/aliasManagement/new" method="get">
<button type="submit" class="button">Create New Alias Route</button>
</form>
{{/COOKIE_LOGGED_IN}}
{{> templateIncludes/freelancerLoginSignupProfileLogoutInterface.html.html}}
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
{{^COOKIE_LOGGED_IN}}
Please Log in.
{{/COOKIE_LOGGED_IN}}
{{#COOKIE_LOGGED_IN}}
<h2>Freelancer: {{freelanceremail}}</h2>
<br>
<form action="/freelancer/aliasManagement/new/fulfilment" method="post">
<label for="freelanceralias">Alias Name: @</label> <input type="text" id="freelanceralias" name="freelanceralias" value=""><br>
<select name="aliasroute">
<option value="">Profile</option>
{{#templates}}
<option value="{{name}}|{{id}}">Template: {{name}}</option>
{{/templates}}
</select><br>
<button type="submit" class="button">Create new Alias</button>
</form>
{{/COOKIE_LOGGED_IN}}
{{> templateIncludes/freelancerLoginSignupProfileLogoutInterface.html.html}}
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
{{^COOKIE_LOGGED_IN}}
Please Log in.
{{/COOKIE_LOGGED_IN}}
{{#COOKIE_LOGGED_IN}}
{{^ALIAS_CREATION_ERROR}}
Alias has been created:
<form action="/@{{aliasname}}" method="get">
<button type="submit" class="button">Open @{{aliasname}}</button>
</form>
{{/ALIAS_CREATION_ERROR}}
{{#ALIAS_CREATION_ERROR}}
Alias has not been created:
{{#ALIAS_CREATION_ERROR_DUPLICATE}}
Alias with the chosen name (@{{aliasname}}) already exists.
{{/ALIAS_CREATION_ERROR_DUPLICATE}}
{{#ALIAS_CREATION_ERROR_UNNAMED}}
Alias can not be created without a name.
{{/ALIAS_CREATION_ERROR_UNNAMED}}
{{/ALIAS_CREATION_ERROR}}
<form action="/freelancer/aliasManagement" method="get">
<button type="submit" class="button">Return to Alias Management</button>
</form>
<form action="/freelancer/aliasManagement/new" method="get">
<button type="submit" class="button">Create New Alias Route</button>
</form>
{{/COOKIE_LOGGED_IN}}
{{> templateIncludes/freelancerLoginSignupProfileLogoutInterface.html.html}}
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -28,7 +28,7 @@
<form action="/freelancer/settings" method="get"> <form action="/freelancer/settings" method="get">
<button type="submit" class="button">Change Account Settings</button> <button type="submit" class="button">Change Account Settings</button>
</form> </form>
<form action="/freelancer/aliasSetup" method="get"> <form action="/freelancer/aliasManagement" method="get">
<button type="submit" class="button">Create/Remove Alias</button> <button type="submit" class="button">Create/Remove Alias</button>
</form> </form>
</div> </div>

View File

@ -8,23 +8,26 @@
Please Log in. Please Log in.
{{/COOKIE_LOGGED_IN}} {{/COOKIE_LOGGED_IN}}
{{#COOKIE_LOGGED_IN}} {{#COOKIE_LOGGED_IN}}
<h2>Freelancer: {{freelanceremail}}</h2> <h2>Freelancer: {{freelanceremail}}</h2>
<br> <br>
<br> <br>
<table> <table>
{{#templates}} {{#templates}}
<tr> <tr>
<th>{{name}}</th> <th>{{name}}</th>
<th> <th>
<form action="/freelancer/templateManagement/template/{{name}}" method="post"> <form action="/freelancer/templateManagement/template/{{name}}" method="post">
<button type="submit" name="templateaction" value="view|{{id}}" class="button">View</button> <button type="submit" name="templateaction" value="view|{{id}}" class="button">View</button>
<button type="submit" name="templateaction" value="edit|{{id}}" class="button">Edit</button> <button type="submit" name="templateaction" value="edit|{{id}}" class="button">Edit</button>
<button type="submit" name="templateaction" value="delete|{{id}}" class="button">Delete</button> <button type="submit" name="templateaction" value="delete|{{id}}" class="button">Delete</button>
</form> </form>
</th> </th>
</tr> </tr>
{{/templates}} {{/templates}}
</table> </table>
<form action="/freelancer/templateManagement/template/new" method="get">
<button type="submit" class="button">Create New Template</button>
</form>
{{/COOKIE_LOGGED_IN}} {{/COOKIE_LOGGED_IN}}
{{> templateIncludes/freelancerLoginSignupProfileLogoutInterface.html.html}} {{> templateIncludes/freelancerLoginSignupProfileLogoutInterface.html.html}}
<br> <br>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
{{^COOKIE_LOGGED_IN}}
Please Log in.
{{/COOKIE_LOGGED_IN}}
{{#COOKIE_LOGGED_IN}}
<br>
<form action="/freelancer/templateManagement/template/new/fulfilment" method="post">
<label for="templatename">Template Name:</label> <input type="text" id="templatename" name="templatename" value=""><br>
<label for="templatecontactdata">Contact Data:</label> <input type="text" id="templatecontactdata" name="templatecontactdata" value=""><br>
<label for="templatecontactinformation">Contact Information: </label> <input type="text" id="templatecontactinformation" name="templatecontactinformation" value=""><br>
<label for="templatecurrencypreference">Prefered Currency: </label> <input type="text" id="templatecurrencypreference" name="templatecurrencypreference" value=""><br>
<label for="templatepriceupfront">Upfront payment: </label> <input type="text" id="templatepriceupfront" name="templatepriceupfront" value=""><br>
<label for="templatepriceondeliver">On Delivery Payment: </label> <input type="text" id="templatepriceondeliver" name="templatepriceondeliver" value=""><br>
<label for="templatecontent">Description: </label> <textarea id="templatecontent" name="templatecontent" value=""></textarea><br>
<button type="submit" class="button">Create new Template</button>
</form>
<br>
{{/COOKIE_LOGGED_IN}}
<br>
<form action="/freelancer/profile" method="get">
<button type="submit" class="button">Return to profile</button>
</form>
<form action="/freelancer/templateManagement" method="get">
<button type="submit" class="button">Return to Template Management</button>
</form>
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
{{^COOKIE_LOGGED_IN}}
Please Log in.
{{/COOKIE_LOGGED_IN}}
{{#COOKIE_LOGGED_IN}}
{{^TEMPLATE_CREATION_ERROR}}
<h2>Template Successfully Created</h2>
<h3>Template: {{templatename}}</h3>
<div>Contact Information:</div>
<div>
{{contactdata}}<br>
{{contactinformation}}
</div>
<br>
<div>Payment Information:</div>
<div>
Prefered Currency: {{currencypreference}}<br>
Price: Upfront: {{priceupfront}} - On Delivery: {{priceondeliver}}<br>
</div>
<br>
<div>Description:</div>
<div>{{content}}</div>
{{/TEMPLATE_CREATION_ERROR}}
{{#TEMPLATE_CREATION_ERROR}}
Unable to create Template
<form action="/freelancer/templateManagement/template/new" method="get">
<button type="submit" class="button">Create New Template</button>
</form>
{{/TEMPLATE_CREATION_ERROR}}
{{/COOKIE_LOGGED_IN}}
<br>
<form action="/freelancer/profile" method="get">
<button type="submit" class="button">Return to profile</button>
</form>
<form action="/freelancer/templateManagement" method="get">
<button type="submit" class="button">Return to Template Management</button>
</form>
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -1,37 +0,0 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
<h2>Freelancer: {{freelancername}}</h2>
<h3>Template: {{templatename}}</h3>
<div>Contact Information:</div>
<div>
{{contactdata}}<br>
{{contactinformation}}
</div>
<br>
<div>Payment Information:</div>
<div>
Prefered Currency: {{currencypreference}}<br>
Price: {{pricetotal}} - Upfront: {{priceupfront}} - On Delivery: {{priceondeliver}}<br>
</div>
<br>
<div>Description:</div>
<div>{{content}}</div>
<br>
<form action="/freelancer/profile" method="get">
<button type="submit" class="button">Return to profile</button>
</form>
<form action="/freelancer/templateManagement" method="get">
<button type="submit" class="button">Return to Template Management</button>
</form>
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
<h2>Freelancer: {{freelancername}}</h2>
{{^OPERATION_EDIT}}
<h3>Template: {{templatename}}</h3>
<div>Contact Information:</div>
<div>
{{contactdata}}<br>
{{contactinformation}}
</div>
<br>
<div>Payment Information:</div>
<div>
Prefered Currency: {{currencypreference}}<br>
Price: {{pricetotal}} - Upfront: {{priceupfront}} - On Delivery: {{priceondeliver}}<br>
</div>
<br>
<div>Description:</div>
<div>{{content}}</div>
{{/OPERATION_EDIT}}
{{#OPERATION_EDIT}}
<br>
<form action="/freelancer/templateManagement/fulfilment/edit" method="post">
<label for="templatename">Template Name:</label> <input type="text" id="templatename" name="templatename" value="{{templatename}}"><br>
<label for="templatecontactdata">Contact Data:</label> <input type="text" id="templatecontactdata" name="templatecontactdata" value="{{contactdata}}"><br>
<label for="templatecontactinformation">Contact Information: </label> <input type="text" id="templatecontactinformation" name="templatecontactinformation" value="{{contactinformation}}"><br>
<label for="templatecurrencypreference">Prefered Currency: </label> <input type="text" id="templatecurrencypreference" name="templatecurrencypreference" value="{{currencypreference}}"><br>
<label for="templatepriceupfront">Upfront payment: </label> <input type="text" id="templatepriceupfront" name="templatepriceupfront" value="{{priceupfront}}"><br>
<label for="templatepriceondeliver">On Delivery Payment: </label> <input type="text" id="templatepriceondeliver" name="templatepriceondeliver" value="{{priceondeliver}}"><br>
<label for="templatecontent">Description: </label> <textarea id="templatecontent" name="templatecontent" value="">{{content}}</textarea><br>
<button type="submit" name="templateid" value="{{templateid}}" class="button">Confirm change of Template</button>
</form>
<br>
{{/OPERATION_EDIT}}
{{#OPERATION_DELETE}}
<br>
<form action="/freelancer/templateManagement/fulfilment/delete" method="post">
<button type="submit" name="templateid" value="{{templateid}}" class="button">Confirm Template Deletion</button>
</form>
<br>
{{/OPERATION_DELETE}}
{{#TEMPLATE_OPERATION_ERROR_NO_TEMPLATE}}
<div>
Template could not be found
</div>
{{/TEMPLATE_OPERATION_ERROR_NO_TEMPLATE}}
<br>
<form action="/freelancer/profile" method="get">
<button type="submit" class="button">Return to profile</button>
</form>
<form action="/freelancer/templateManagement" method="get">
<button type="submit" class="button">Return to Template Management</button>
</form>
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
{{> templateIncludes/style.css.html}}
</head>
<body>
{{#TEMPLATE_OPERATION_COMPLETE}}
The
{{#OPERATION_EDIT}}Edit{{/OPERATION_EDIT}}
{{#OPERATION_DELETE}}Delete{{/OPERATION_DELETE}}
Operation has been completed.
{{/TEMPLATE_OPERATION_COMPLETE}}
{{#OPERATION_ERROR}}
The Operation has not been completed
{{/OPERATION_ERROR}}
<br>
<form action="/freelancer/profile" method="get">
<button type="submit" class="button">Return to profile</button>
</form>
<form action="/freelancer/templateManagement" method="get">
<button type="submit" class="button">Return to Template Management</button>
</form>
<br>
{{> templateIncludes/returnToIndexButton.html.html}}
</body>
</html>