From a4505b1408e70f62f2e8063f6068ee5fa9bbf29c Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Sun, 27 Jun 2021 00:01:00 -0700 Subject: [PATCH] :construction --- include/bank.h | 6 +-- include/bank_api.h | 19 ++++----- src/bank.cpp | 28 +++++-------- src/bank_api.cpp | 97 ++++++++++++++++++++++++++-------------------- 4 files changed, 76 insertions(+), 74 deletions(-) diff --git a/include/bank.h b/include/bank.h index 497d3ab..32d50e2 100644 --- a/include/bank.h +++ b/include/bank.h @@ -49,19 +49,19 @@ public: BankResponse SendFunds(const std::string &a_name, const std::string &b_name, uint32_t amount) noexcept; bool VerifyPassword(const std::string &name, const std::string &attempt) const noexcept; //internally used + void ChangePassword(const std::string &name, std::string &&new_pass) noexcept; + int_fast8_t AddUser(const std::string &name, const std::string &init_pass) noexcept; int_fast8_t AdminAddUser(const std::string &attempt, std::string &&name, uint32_t init_bal, std::string &&init_pass) noexcept; int_fast8_t DelUser(const std::string &name, const std::string &attempt) noexcept; int_fast8_t AdminDelUser(const std::string &name, const std::string &attempt) noexcept; - bool Contains(const std::string &name) const noexcept; //done + bool Contains(const std::string &name) const noexcept; int_fast8_t AdminVerifyPass(const std::string &attempt) noexcept; int_fast8_t SetBal(const std::string &name, const std::string &attempt, uint32_t amount) noexcept; - int_fast8_t ChangePassword(const std::string &name, const std::string &attempt, std::string &&new_pass) noexcept; - void Save(); void Load(); }; diff --git a/include/bank_api.h b/include/bank_api.h index b95db67..5881c0f 100644 --- a/include/bank_api.h +++ b/include/bank_api.h @@ -14,10 +14,12 @@ namespace v1 public: api(Bank &b); - void GetBal(req_args) const; + void GetBal(req_args, const std::string &name) const; void GetLog(req_args, const std::string &name); - void SendFunds(req_args, const std::string name) const; - void VerifyPassword(req_args) const; + void SendFunds(req_args, const std::string &name) const; + void VerifyPassword(req_args, const std::string &name) const; + + void ChangePassword(req_args, const std::string &name) const; void Help(req_args) const; void Ping(req_args) const; @@ -26,7 +28,6 @@ namespace v1 void AdminAddUser(req_args, std::string &&name, uint32_t init_bal) const; void DelUser(req_args, const std::string &name) const; void AdminDelUser(req_args, const std::string &name) const; - void ChangePassword(req_args, const std::string &name) const; void Contains(req_args, const std::string &name) const; void SetBal(req_args, const std::string &name, uint32_t amount) const; void AdminVerifyPass(req_args); @@ -34,13 +35,13 @@ namespace v1 METHOD_LIST_BEGIN //Usage - METHOD_ADD(api::GetBal, "/user/bal", Get, Options); //done - METHOD_ADD(api::GetLog, "/user/log", Get, Options, "UserFilter"); //snapshot not implemented - METHOD_ADD(api::SendFunds, "/user/transfer", Post, Options, "UserFilter"); //responses incomplete - METHOD_ADD(api::VerifyPassword, "/{name}/pass/verify", Get, Options); //done + METHOD_ADD(api::GetBal, "/users/{name}/bal", Get, Options); //done + METHOD_ADD(api::GetLog, "/users/{name}/log", Get, Options, "UserFilter"); //snapshot not implemented + METHOD_ADD(api::SendFunds, "/users/{name}/transfer", Post, Options, "UserFilter"); //responses incomplete + METHOD_ADD(api::VerifyPassword, "/users/{name}/verify_password", Get, Options); //done //Meta Usage - METHOD_ADD(api::ChangePassword, "/{name}/pass/change", Patch, Options); + METHOD_ADD(api::ChangePassword, "/users/{name}/change_password", Patch, Options); //done METHOD_ADD(api::SetBal, "/admin/{name}/bal?amount={amount}", Patch, Options); //System Usage diff --git a/src/bank.cpp b/src/bank.cpp index be4fdf7..468496e 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -81,7 +81,7 @@ BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_nam //if A can afford it and A's password matches attempt if (a.balance < amount) { - state = {ErrorResponse::InsufficientFunds, "Sender has insufficient funds"}; + state = {k200OK, "Sender has insufficient funds"}; } else { @@ -107,7 +107,7 @@ BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_nam //if A can afford it and A's password matches attempt if (a.balance < amount) { - state = {ErrorResponse::InsufficientFunds, "Sender has insufficient funds"}; + state = {k200OK, "Sender has insufficient funds"}; } else { @@ -134,6 +134,13 @@ bool Bank::VerifyPassword(const std::string &name, const std::string &attempt) c return res; } +void Bank::ChangePassword(const std::string &name, std::string &&new_pass) noexcept +{ + users.modify_if(name, [&new_pass](User &u) { + u.password = XXH3_64bits(new_pass.data(), new_pass.size()); + }); +} + int_fast8_t Bank::AddUser(const std::string &name, const std::string &init_pass) noexcept { if (name.size() > max_name_size) @@ -265,23 +272,6 @@ int_fast8_t Bank::SetBal(const std::string &name, const std::string &attempt, ui : ErrorResponse::UserNotFound; } -int_fast8_t Bank::ChangePassword(const std::string &name, const std::string &attempt, std::string &&new_pass) noexcept -{ - int_fast8_t res = ErrorResponse::UserNotFound; - users.modify_if(name, [&res, &attempt, &new_pass](User &u) { - if (u.password != XXH3_64bits(attempt.data(), attempt.size())) - { - res = ErrorResponse::WrongPassword; - } - else - { - res = true; - u.password = XXH3_64bits(new_pass.data(), new_pass.size()); - } - }); - return res; -} - void Bank::Save() { if (GetChangeState()) diff --git a/src/bank_api.cpp b/src/bank_api.cpp index f5e2787..edd9d23 100644 --- a/src/bank_api.cpp +++ b/src/bank_api.cpp @@ -7,12 +7,14 @@ const auto temp_req = req->getJsonObject(); \ const auto body = temp_req ? *temp_req : Json::Value(); -#define RESPONSE_PARSE(R) \ - auto resp = HttpResponse::newHttpJsonResponse(JsonCast(R.second)); \ - resp->setStatusCode(R.first); \ +#define RESPONSE_PARSE(R) \ + auto resp = HttpResponse::newHttpJsonResponse(JsonCast(std::move(R.second))); \ + resp->setStatusCode(R.first); \ callback(resp); -#define NAME_PARAM req->getParameter("name") +#define NAME_PARAM req->getBody() + +#define NAME_CHECK(suc) BankResponse b = (name == NAME_PARAM ? suc : BankResponse(k400BadRequest, "Requests name must match Auth's name")); namespace v1 { @@ -39,10 +41,56 @@ namespace v1 api::api(Bank &b) : bank(b) {} + void api::GetBal(req_args, const std::string &name) const + { + RESPONSE_PARSE(bank.GetBal(name)); + } + void api::GetLog(req_args, const std::string &name) + { + if constexpr (max_log_size > 0) + { + NAME_CHECK(bank.GetLogs(name)); + RESPONSE_PARSE(b); + } + else + { + auto resp = HttpResponse::newHttpJsonResponse("Logs are Disabled"); + resp->setStatusCode(k404NotFound); + resp->setExpiredTime(0); //cached forever + callback(resp); + } + } + void api::SendFunds(req_args, const std::string &name) const + { + GEN_BODY + NAME_CHECK(bank.SendFunds(name, body["to"].asCString(), body["amount"].asUInt())); + RESPONSE_PARSE(b); + } + void api::VerifyPassword(req_args, const std::string &name) const + { + NAME_CHECK(BankResponse(k200OK, true)); + RESPONSE_PARSE(b); + } + + void api::ChangePassword(req_args, const std::string &name) const + { + GEN_BODY + bank.ChangePassword(name, std::move(body["new_pass"].asCString())); //may make asString() + NAME_CHECK(BankResponse(k200OK, true)); + RESPONSE_PARSE(b); + } + void api::Help(req_args) const { auto resp = HttpResponse::newHttpResponse(); - resp->setBody("# Meta Usage

Error Responses

# meaning
-1 UserNotFound
-2 WrongPassword
-3 InvalidRequest
-4 NameTooLong
-5 UserAlreadyExists
-6 InsufficientFunds

Things of Note

Usage

Name Path Method A Description
GetBal api/{name}/bal GET false returns the balance of a given user {name}
GetLog api/{name}/log GET true returns a list of last n number of transactions (a configurable amount) of a given user {name}
SendFunds api/{name}/send/{to}?amount={amount} POST true sends {amount} from user {name} to user {to}
VerifyPassword api/{name}/pass/verify GET true returns 1 if the supplied user {name}'s password matches the password supplied in the header

Meta Usage

Name Path Method A Description
ChangePassword api/{name}/pass/change PATCH true if the password supplied in the header matches the user {name}'s password, the user’s password is changed to the one given in the body
SetBal api/admin/{name}/bal?amount={amount} PATCH true sets the balance of a give user {name} if the supplied password matches the admin password

System Usage

Name Path Method A Description
Help api/help GET false the page you’re looking at right now!
Ping api/ping GET false for pinging the server to see if its online
Close api/admin/close POST true saves and then closes the program if the supplied password matches the admin password
Contains api/contains/{name} GET false returns 1 if the supplied user {name} exists
AdminVerifyPass api/admin/verify GET true returns 1 if the password supplied in the header matches the admin password

User Management

Name Path Method A Description
AddUser api/user/{name} POST true registers a user with the name {name}, balance of 0 and a password of the password supplied in the header
AdminAddUser api/admin/user/{name}?init_bal={init_bal} POST true if the password supplied in the header matches the admin password, then it registers a user with the name {name}, balance of init_bal and a password supplied by the body of the request
DelUser api/user/{name} DELETE true if the password supplied in the header matches the user {name}'s password, then the user is deleted
AdminDelUser api/admin/user/{name} DELETE true if the password supplied in the header matches the admin password, then the user is deleted
"); + resp->setBody(""); + resp->setExpiredTime(0); + callback(resp); + } + void api::Ping(req_args) const + { + auto resp = HttpResponse::newHttpResponse(); + resp->setBody("pong"); resp->setExpiredTime(0); callback(resp); } @@ -62,13 +110,6 @@ namespace v1 } JSON(res); } - void api::Ping(req_args) const - { - auto resp = HttpResponse::newHttpResponse(); - resp->setBody("pong"); - resp->setExpiredTime(0); - callback(resp); - } void api::AddUser(req_args, const std::string &name) const { JSON(bank.AddUser(std::move(name), PASS_HEADER)); @@ -85,27 +126,10 @@ namespace v1 { JSON(bank.AdminDelUser(name, PASS_HEADER)); } - void api::SendFunds(req_args, const std::string name) const - { - GEN_BODY - RESPONSE_PARSE(bank.SendFunds(NAME_PARAM, body["to"].asCString(), body["amount"].asUInt())); - } - void api::ChangePassword(req_args, const std::string &name) const - { - JSON(bank.ChangePassword(name, PASS_HEADER, std::string(req->getBody()))); - } void api::Contains(req_args, const std::string &name) const { JSON(bank.Contains(name)); } - void api::GetBal(req_args) const - { - RESPONSE_PARSE(bank.GetBal(NAME_PARAM)); - } - void api::VerifyPassword(req_args) const - { - RESPONSE_PARSE(BankResponse(k200OK, true)); - } void api::SetBal(req_args, const std::string &name, uint32_t amount) const { JSON(bank.SetBal(name, PASS_HEADER, amount)); @@ -114,18 +138,5 @@ namespace v1 { JSON(bank.AdminVerifyPass(PASS_HEADER)); } - void api::GetLog(req_args, const std::string &name) - { - if constexpr (max_log_size > 0) - { - RESPONSE_PARSE(bank.GetLogs(NAME_PARAM)); - } - else - { - auto resp = HttpResponse::newHttpJsonResponse("Logs are Disabled"); - resp->setStatusCode(k404NotFound); - resp->setExpiredTime(0); //cached forever - callback(resp); - } - } + } \ No newline at end of file