mirror of
https://github.com/Expand-sys/CCash
synced 2025-12-15 15:52:13 +11:00
Merge branch 'EntireTwix:main' into main
This commit is contained in:
commit
8f85e13f11
12 changed files with 257 additions and 101 deletions
|
|
@ -96,23 +96,10 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
Op(Bank::GetLogsV2("twix"), "get logs init (v2): ", 1);
|
||||
Op(Bank::GetLogsV2("twix"), "get logs cached (v2): ", 1000000);
|
||||
Op(Bank::GetLogsRange("twix", 0, 100), "get logs range: ", 1000000);
|
||||
#endif
|
||||
Op(Bank::PruneUsers(0, 0), "prune users: ", 1);
|
||||
Op(Bank::Save(), "saving: ", 1);
|
||||
|
||||
//GetBal scalining test
|
||||
//std::default_random_engine generator;
|
||||
//std::uniform_real_distribution<double> distribution(0.0, 1.0);
|
||||
|
||||
// for (size_t i = 0; i < 10000000; ++i)
|
||||
// {
|
||||
// Bank::AddUser(std::to_string(i), 100000, "root");
|
||||
// if (i % 10000 == 0)
|
||||
// {
|
||||
// auto u = std::to_string((int)(distribution(generator) * i));
|
||||
// Op(Bank::GetBal(u), std::to_string(i) + ", ", 100000);
|
||||
// }
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
You can with [build docs](https://github.com/EntireTwix/CCash/blob/main/docs/building.md) you can build from source or use the Docker package.
|
||||
### Why is my username invalid
|
||||
Usernames are restricted by minecraft's requirements
|
||||
* lowercase letters
|
||||
* letters
|
||||
* numbers
|
||||
* _
|
||||
* length must be atleast 3 and at most 16 characters.
|
||||
|
|
@ -16,7 +16,5 @@ Because this usecase requires none of the features a database would offer.
|
|||
Consider disabling `ADD_USER_OPEN` in the [build proccess](https://github.com/EntireTwix/CCash/blob/main/docs/building.md).
|
||||
### My instance is taking up too much storage or RAM
|
||||
Reduce log size and/or use the prune users endpoint to remove dead accounts.
|
||||
### How do I start an economy
|
||||
I believe setting up a commodities exchange is the best way to get an economy going initially.
|
||||
### Why not use an economy mod
|
||||
Speed of operations, CCash being external to MC (and so compatible with any version/configuration), and the API are the main advantages to an economy mod.
|
||||
|
|
@ -6,21 +6,23 @@
|
|||
| supported | :heavy_check_mark: |
|
||||
| uses deprecated endpoints | ⚠ |
|
||||
| uses defunt endpoints | :no_entry: |
|
||||
| in development | :hammer: |
|
||||
|
||||
## General
|
||||
| author | name | support | image |
|
||||
| :-------------------------------------- | ----------------------------------------------------------- | :----------------: | :-------------------------------------------------------------------------------------------------------------: |
|
||||
| [Expand](https://github.com/Expand-sys) | [Web Frontend](https://github.com/Expand-sys/ccashfrontend) | :heavy_check_mark: |  |
|
||||
| [Expand](https://github.com/Expand-sys) | [Discord Bot](https://github.com/Expand-sys/ccashbot) | :heavy_check_mark: | |
|
||||
| [Expand](https://github.com/Expand-sys) | [Web Frontend](https://github.com/Expand-sys/ccashfrontend) | :heavy_check_mark: |  | |
|
||||
| [ArcNyxx](https://github.com/ArcNyxx) | [CCash CLI](https://github.com/ArcNyxx/ccash_cmd) | ⚠ | |
|
||||
|
||||
## Minecraft
|
||||
| author | name | support | image |
|
||||
| :------------------------------------------ | --------------------------------------------------------------------------- | :----------------: | :-------------------------------------------------------------------------------------------------------------: |
|
||||
| [Reactified](https://github.com/Reactified) | [Shop](https://github.com/Reactified/rpm/tree/main/packages/ccash-shop) | :heavy_check_mark: |  |
|
||||
| [Reactified](https://github.com/Reactified) | [Wallet](https://github.com/Reactified/rpm/tree/main/packages/ccash-wallet) | ⚠ |  |
|
||||
| [Reactified](https://github.com/Reactified) | [ATM](https://github.com/Reactified/rpm/tree/main/packages/ccash-bank) | :heavy_check_mark: |  |
|
||||
| [STBoyden](https://github.com/STBoyden) | Commodities Exchange (in-development) | :heavy_check_mark: | |
|
||||
| author | name | support | image |
|
||||
| :------------------------------------------ | ---------------------------------------------------------------------------------------- | :----------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||
| [Reactified](https://github.com/Reactified) | [Shop](https://github.com/Reactified/rpm/tree/main/packages/ccash-shop) | :heavy_check_mark: |  |
|
||||
| [Reactified](https://github.com/Reactified) | [Wallet](https://github.com/Reactified/rpm/tree/main/packages/ccash-wallet) | ⚠ |  |
|
||||
| [Reactified](https://github.com/Reactified) | [ATM](https://github.com/Reactified/rpm/tree/main/packages/ccash-bank) | :heavy_check_mark: |  |
|
||||
| [Reactified](https://github.com/Reactified) | [Chunk Loader Shop](https://github.com/Reactified/rpm/tree/main/packages/forceload-shop) | :heavy_check_mark: |   |
|
||||
| [STBoyden](https://github.com/STBoyden) | [Commodities Exchange](https://github.com/STBoyden/ccash-market) | :hammer: | |
|
||||
|
||||
|
||||
## Desired
|
||||
| idea | description |
|
||||
|
|
|
|||
|
|
@ -17,73 +17,77 @@
|
|||
## all error responses have JSON string along with them to describe
|
||||
|
||||
### Usage endpoints
|
||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :------------- | :------: | ------------------------------------------------------------------------------ | -------------------------------- | ------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------------: | :----------------: | :----------------: | :---: | :----------------: |
|
||||
| GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: |
|
||||
| GetLog | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| GetLogV2 | `v2.5.1` | retrieves the logs of a given user, length varies by server configuration | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `{name}` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :------------- | :---------: | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------------: | :----------------: | :----------------: | :---: | :----------------: |
|
||||
| GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: |
|
||||
| GetLogs | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration (oldest to newest transactions) | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| GetLogsV2 | `v2.6.1` | retrieves the logs of a given user, length varies by server configuration (newest to oldest transactions) | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| GetLogsRange | `v2.6.1` | retrieves the logs of a given user, where `{start}` is the 0-indexed first log and `{length}` is the number of logs after that index. | `N/A` | api/v1/user/log_range | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `"name"` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
|
||||
### Usage enpoint errors
|
||||
| name | 400 | 401 | 404 | 406 |
|
||||
| :------------- | :----------------: | :----------------: | :----------------: | :----------------: |
|
||||
| GetBal | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| GetLog | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| GetLogV2 | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| GetLogs | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| GetLogsV2 | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| GetLogsRange | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| SendFunds | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| VerifyPassword | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| ChangePassword | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
|
||||
### Meta Usage endpoints
|
||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :------------------ | :------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :---------: | :----------------------------: | :----------------: | :----------------: | :----------------: | :----------------: |
|
||||
| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| AdminChangePassword | `v2.3.0` | changes the password of a given user `{name}` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| SetBal | `v2.3.0` | sets the balance of a given user `{name}` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| ImpactBal | `v2.3.0` | modifies the user `{name}`'s balance by `{amount}` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :------------------ | :---------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: |
|
||||
| AdminGetLogs | `v2.6.1` | retreives the logs of a given user `{name}`, length varies by server configuration | `N/A` | api/v1/admin/user/log?name={name} | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: |
|
||||
| AdminChangePassword | `v2.3.0` | changes the password of a given user `"name"` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: |
|
||||
| SetBal | `v2.3.0` | sets the balance of a given user `"name"` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| ImpactBal | `v2.3.0` | modifies the user `"name"`'s balance by `"amount"` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
|
||||
### Meta Usage endpoint errors
|
||||
| name | 400 | 401 | 404 | 406 |
|
||||
| :------------------ | :----------------: | :----------------: | :----------------: | :----------------: |
|
||||
| ChangePassword | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| AdminGetLogs | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| AdminChangePassword | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| AdminVerifyAccount | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| SetBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| ImpactBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
|
||||
### Sytem Usage endpoints
|
||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :----------------- | :------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------ | :---------: | :------------: | :---------: | :-----------------------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: |
|
||||
| Help | `v2.3.0` | redirects to GitHub projects Docs | `N/A` | api/help | `GET` | 301 | `N/A` | `N/A` | :x: | :x: | :x: | :x: |
|
||||
| Close | `v2.3.0` | saves & closes the CCash webserver | `N/A` | api/v1/admin/shutdown | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: |
|
||||
| Contains | `v2.3.0` | checks wether a user exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: |
|
||||
| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: |
|
||||
| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `{time}` (if logs are enabled) and have less money then `{amount}` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| ApiProperties | `v2.5.1` | properties of the given instance | `N/A` | api/properties | `GET` | 200 | json object | {"max_log":uint64, "add_user_open":boolean, "return_on_del":string} | :heavy_check_mark: | :x: | :x: | :x: |
|
||||
| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :------------ | :---------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------ | :---------: | :------------: | :---------: | :-----------------------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: |
|
||||
| Help | `v2.3.0` | redirects to GitHub projects Docs | `N/A` | api/help | `GET` | 301 | `N/A` | `N/A` | :x: | :x: | :x: | :x: |
|
||||
| Close | `v2.3.0` | saves & closes the CCash webserver | `N/A` | api/v1/admin/shutdown | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: |
|
||||
| Contains | `v2.3.0` | checks wether a given user `{name}` exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: |
|
||||
| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `"time"` (if logs are enabled) and have less money then `"amount"` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| ApiProperties | `v2.5.1` | properties of the given instance | `N/A` | api/properties | `GET` | 200 | json object | {"max_log":uint64, "add_user_open":boolean, "return_on_del":string} | :heavy_check_mark: | :x: | :x: | :x: |
|
||||
|
||||
### System Usage endpoin errors
|
||||
| name | 401 | 404 | 406 |
|
||||
| :----------------- | :----------------: | :----------------: | :----------------: |
|
||||
| Help | :x: | :x: | :x: |
|
||||
| Close | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| Contains | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| AdminVerifyAccount | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| PruneUsers | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| ApiProperties | :x: | :x: | :x: |
|
||||
| name | 401 | 404 | 406 |
|
||||
| :------------ | :----------------: | :----------------: | :----------------: |
|
||||
| Help | :x: | :x: | :x: |
|
||||
| Close | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| Contains | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| PruneUsers | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||
| ApiProperties | :x: | :x: | :x: |
|
||||
|
||||
### Username Requirements
|
||||
Valid
|
||||
* lowercase letters
|
||||
* letters
|
||||
* numbers
|
||||
* _
|
||||
* Length must be atleast 3 and at most 16 characters.
|
||||
|
||||
### User Management endpoints
|
||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :----------- | :------: | --------------------------------------- | --------------------------------------------- | -------------------------- | :---------: | :------------: | :---------: | :----------: | :----------------: | :----------------: | :----------------: | :----------------: |
|
||||
| AddUser | `v2.3.0` | adding a user with a balance of 0 | {"name":string,"pass":string} | api/v1/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: |
|
||||
| AdminAddUser | `v2.3.0` | adding a user with an arbitrary balance | {"name":string,"amount":uint32,"pass":string} | api/v1/admin/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| DelSelf | `v2.3.0` | deletes a user | `N/A` | api/v1/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| AdminDelUser | `v2.3.0` | deletes a given user `{name}` | {"name":string} | api/v1/admin/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
||||
| :----------- | :---------: | --------------------------------------- | --------------------------------------------- | -------------------------- | :---------: | :------------: | :---------: | :----------: | :----------------: | :----------------: | :----------------: | :----------------: |
|
||||
| AddUser | `v2.3.0` | adding a user with a balance of 0 | {"name":string,"pass":string} | api/v1/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: |
|
||||
| AdminAddUser | `v2.3.0` | adding a user with an arbitrary balance | {"name":string,"amount":uint32,"pass":string} | api/v1/admin/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
| DelSelf | `v2.3.0` | deletes a user | `N/A` | api/v1/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
||||
| AdminDelUser | `v2.3.0` | deletes a given user `"name"` | {"name":string} | api/v1/admin/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: |
|
||||
|
||||
### User Management endpoint errors
|
||||
| name | 400 | 401 | 404 | 406 | 409 |
|
||||
|
|
|
|||
|
|
@ -49,13 +49,13 @@ public:
|
|||
static BankResponse GetLogs(const std::string &name) noexcept;
|
||||
#endif
|
||||
static BankResponse GetLogsV2(const std::string &name) noexcept;
|
||||
static BankResponse GetLogsRange(const std::string &name, size_t n, size_t m) noexcept;
|
||||
#endif
|
||||
|
||||
static BankResponse SendFunds(const std::string &a_name, const std::string &b_name, uint32_t amount) noexcept;
|
||||
static bool VerifyPassword(const std::string &name, const std::string_view &attempt) noexcept;
|
||||
|
||||
static void ChangePassword(const std::string &name, const std::string &new_pass) noexcept;
|
||||
static BankResponse SetBal(const std::string &name, uint32_t amount) noexcept;
|
||||
static BankResponse SetBal(const std::string &name, int64_t amount) noexcept;
|
||||
static BankResponse ImpactBal(const std::string &name, int64_t amount) noexcept;
|
||||
static bool Contains(const std::string &name) noexcept;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,18 +16,20 @@ public:
|
|||
static void GetLogs(req_args);
|
||||
#endif
|
||||
static void GetLogsV2(req_args);
|
||||
static void GetLogsRange(req_args, size_t start, size_t length);
|
||||
static void SendFunds(req_args);
|
||||
static void ChangePassword(req_args);
|
||||
static void VerifyPassword(req_args);
|
||||
|
||||
static void ChangePassword(req_args);
|
||||
static void AdminGetLogs(req_args, const std::string& name);
|
||||
static void AdminChangePassword(req_args);
|
||||
static void AdminVerifyAccount(req_args);
|
||||
static void SetBal(req_args);
|
||||
static void ImpactBal(req_args);
|
||||
|
||||
static void Help(req_args);
|
||||
static void Close(req_args);
|
||||
static void Contains(req_args, const std::string &name);
|
||||
static void AdminVerifyAccount(req_args);
|
||||
static void PruneUsers(req_args);
|
||||
static void ApiProperties(req_args);
|
||||
|
||||
|
|
@ -38,39 +40,49 @@ public:
|
|||
|
||||
METHOD_LIST_BEGIN
|
||||
|
||||
METHOD_ADD(api::Help, "/help", Get, Options);
|
||||
METHOD_ADD(api::ApiProperties, "/properties", Get, Options);
|
||||
|
||||
//Usage
|
||||
METHOD_ADD(api::GetBal, "/v1/user/balance?name={name}", Get, Options, "JsonFilter<false>");
|
||||
|
||||
#if MAX_LOG_SIZE > 0
|
||||
|
||||
#if USE_DEPRECATED_ENDPOINTS
|
||||
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
||||
#endif
|
||||
|
||||
METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
||||
METHOD_ADD(api::GetLogsRange, "/v1/user/log_range?start={start}&length={length}", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
||||
METHOD_ADD(api::AdminGetLogs, "/v1/admin/user/log?name={name}", Get, Options, "JsonFilter<false>", "UserFilter<false, true>");
|
||||
#else
|
||||
|
||||
#if USE_DEPRECATED_ENDPOINTS
|
||||
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>");
|
||||
#endif
|
||||
|
||||
METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter<false>");
|
||||
METHOD_ADD(api::GetLogsRange, "/v1/user/log_range?start={start}&length={length}", Get, Options, "JsonFilter<false>");
|
||||
METHOD_ADD(api::AdminGetLogs, "/v1/admin/user/log?name={name}", Get, Options, "JsonFilter<false>");
|
||||
#endif
|
||||
|
||||
METHOD_ADD(api::SendFunds, "/v1/user/transfer", Post, Options, "JsonFilter<true>", "UserFilter<true, false>"); //expects ["name"](string) and ["amount"](uint32)
|
||||
METHOD_ADD(api::ChangePassword, "/v1/user/change_password", Patch, Options, "JsonFilter<true>", "UserFilter<true, false>"); //expects ["pass"](string)
|
||||
METHOD_ADD(api::VerifyPassword, "/v1/user/verify_password", Post, Options, "UserFilter<false, false>", "JsonFilter<false>");
|
||||
|
||||
//Meta Usage
|
||||
METHOD_ADD(api::ChangePassword, "/v1/user/change_password", Patch, Options, "JsonFilter<true>", "UserFilter<true, false>"); //expects ["pass"](string)
|
||||
METHOD_ADD(api::AdminChangePassword, "/v1/admin/user/change_password", Patch, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) and ["pass"](string)
|
||||
METHOD_ADD(api::SetBal, "/v1/admin/set_balance", Patch, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) and ["amount"](uint32)
|
||||
METHOD_ADD(api::ImpactBal, "/v1/admin/impact_balance", Post, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) and ["amount"](uint32)
|
||||
METHOD_ADD(api::AdminVerifyAccount, "/v1/admin/verify_account", Post, Options, "UserFilter<false, true>", "JsonFilter<false>");
|
||||
METHOD_ADD(api::SetBal, "/v1/admin/set_balance", Patch, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) and ["amount"](uint32)
|
||||
METHOD_ADD(api::ImpactBal, "/v1/admin/impact_balance", Post, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) and ["amount"](uint32)
|
||||
|
||||
//System Usage
|
||||
METHOD_ADD(api::Help, "/help", Get, Options);
|
||||
METHOD_ADD(api::Close, "/v1/admin/shutdown", Post, Options, "UserFilter<false, true>", "JsonFilter<false>");
|
||||
METHOD_ADD(api::Contains, "/v1/user/exists?name={name}", Get, Options, "JsonFilter<false>");
|
||||
METHOD_ADD(api::AdminVerifyAccount, "/v1/admin/verify_account", Post, Options, "UserFilter<false, true>", "JsonFilter<false>");
|
||||
METHOD_ADD(api::PruneUsers, "/v1/admin/prune_users", Post, "UserFilter<false, true>", "JsonFilter<true>"); //expects ["time"](int64) and ["amount"](uint32)
|
||||
METHOD_ADD(api::ApiProperties, "/properties", Get, Options);
|
||||
|
||||
//User Managment
|
||||
METHOD_ADD(api::AddUser, "/v1/user/register", Post, Options); //expects ["name"](string) ["pass"](string)
|
||||
METHOD_ADD(api::AddUser, "/v1/user/register", Post, Options); //expects ["name"](string) ["pass"](string)
|
||||
METHOD_ADD(api::AdminAddUser, "/v1/admin/user/register", Post, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) ["amount"](uint32) ["pass"](string)
|
||||
METHOD_ADD(api::DelSelf, "/v1/user/delete", Delete, Options, "UserFilter<true, false>", "JsonFilter<false>");
|
||||
METHOD_ADD(api::AdminDelUser, "/v1/admin/user/delete", Delete, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string)
|
||||
|
|
|
|||
|
|
@ -26,5 +26,6 @@ public:
|
|||
std::string GetLogs(const std::string& name) noexcept;
|
||||
#endif
|
||||
std::string GetLogsV2() noexcept;
|
||||
std::string GetLogsRange(size_t n, size_t m) noexcept;
|
||||
void AddTrans(const std::string &counterparty_str, bool receiving, uint32_t amount, time_t time) noexcept;
|
||||
};
|
||||
|
|
|
|||
35
main.cpp
35
main.cpp
|
|
@ -34,28 +34,29 @@ int main(int argc, char **argv)
|
|||
uint8_t temp[16]{16, 0, 0, 0, 4};
|
||||
users_save.write((char *)temp, 16);
|
||||
users_save.close();
|
||||
std::cout << "User save file generated\nUsage: sudo ./bank <admin account name> <saving frequency in minutes> [daemon flag {default: false}]\n";
|
||||
std::cout << "User save file generated\n" << "Usage: sudo ./bank <admin account> <saving frequency in minutes> [daemon flag {default: false}]\n";
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "File cannot be created (may already exist)\n";
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "Usage: sudo ./bank <admin account> <saving frequency in minutes> [daemon flag {default: false}]\n";
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (geteuid() != 0)
|
||||
{
|
||||
std::cerr << "ERROR: CCash MUST be ran as root\n";
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
const unsigned long saving_freq = std::stoul(std::string(argv[2]));
|
||||
std::cout
|
||||
<< "\nAPI : v2.5.1"
|
||||
<< "\n\nAVX : " << (__builtin_cpu_supports("avx") ? "enabled" : "disabled")
|
||||
<< "\nAPI : v2.6.1\n"
|
||||
<< "\nAVX : " << (__builtin_cpu_supports("avx") ? "enabled" : "disabled")
|
||||
<< "\nAVX 2 : " << (__builtin_cpu_supports("avx2") ? "enabled" : "disabled")
|
||||
<< "\nSSE 2 : " << (__builtin_cpu_supports("sse2") ? "enabled" : "disabled")
|
||||
<< "\nSSE 3 : " << (__builtin_cpu_supports("sse3") ? "enabled" : "disabled")
|
||||
|
|
@ -92,18 +93,22 @@ int main(int argc, char **argv)
|
|||
if (saving_freq) //if saving frequency is 0 then auto saving is turned off
|
||||
{
|
||||
std::thread([saving_freq]()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::minutes(saving_freq));
|
||||
std::cout << "Saving " << std::time(0) << "...\n"
|
||||
<< Bank::Save();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::minutes(saving_freq));
|
||||
std::cout << "Saving " << std::time(0) << "...\n" << Bank::Save();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp(argv[3], "true")) { app().enableRunAsDaemon(); }
|
||||
else if (argc == 4 && strcmp(argv[3], "false"))
|
||||
{
|
||||
std::cerr << "daemon flag must be \"true\" or \"false\"\n";
|
||||
return -1;
|
||||
}
|
||||
} //destroying setup variables
|
||||
|
||||
app()
|
||||
|
|
|
|||
43
src/bank.cpp
43
src/bank.cpp
|
|
@ -36,7 +36,7 @@ inline bool ValidUsername(const std::string &name) noexcept
|
|||
}
|
||||
for (char c : name)
|
||||
{
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_'))
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -116,6 +116,28 @@ BankResponse Bank::GetLogsV2(const std::string &name) noexcept
|
|||
}
|
||||
}
|
||||
|
||||
BankResponse Bank::GetLogsRange(const std::string &name, size_t start, size_t length) noexcept
|
||||
{
|
||||
BankResponse res;
|
||||
if (start >= MAX_LOG_SIZE)
|
||||
{
|
||||
return {k400BadRequest, "\"Invalid {start} index\""};
|
||||
}
|
||||
if (!length)
|
||||
{
|
||||
return {k400BadRequest, "\"Invalid {length}\""};
|
||||
}
|
||||
|
||||
if (!Bank::users.modify_if(name, [&name, &res, start, length](User &u) { res = {k200OK, u.log.GetLogsRange(start, length)}; }))
|
||||
{
|
||||
return {k404NotFound, "\"User not found\""};
|
||||
}
|
||||
else
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_name, uint32_t amount) noexcept
|
||||
|
|
@ -179,15 +201,20 @@ bool Bank::VerifyPassword(const std::string &name, const std::string_view &attem
|
|||
Bank::users.if_contains(name, [&res, &attempt](const User &u) { res = (u.password == xxHashStringGen{}(attempt)); });
|
||||
return res;
|
||||
}
|
||||
|
||||
void Bank::ChangePassword(const std::string &name, const std::string &new_pass) noexcept
|
||||
{
|
||||
SET_CHANGES_ON;
|
||||
Bank::users.modify_if(name, [&new_pass](User &u) { u.password = xxHashStringGen{}(new_pass); });
|
||||
}
|
||||
BankResponse Bank::SetBal(const std::string &name, uint32_t amount) noexcept
|
||||
BankResponse Bank::SetBal(const std::string &name, int64_t amount) noexcept
|
||||
{
|
||||
if (ValidUsername(name) && Bank::users.modify_if(name, [amount](User &u) { u.balance = amount; }))
|
||||
if (ValidUsername(name) && Bank::users.modify_if(name, [&amount](User &u) {
|
||||
amount -= u.balance;
|
||||
u.balance += amount;
|
||||
#if MAX_LOG_SIZE > 0
|
||||
u.log.AddTrans("Ω", (amount > 0), std::abs(amount), time(NULL));
|
||||
#endif
|
||||
}))
|
||||
{
|
||||
SET_CHANGES_ON;
|
||||
return {k204NoContent, std::nullopt}; //returns new balance
|
||||
|
|
@ -204,7 +231,13 @@ BankResponse Bank::ImpactBal(const std::string &name, int64_t amount) noexcept
|
|||
return {k400BadRequest, "\"Amount cannot be 0\""};
|
||||
}
|
||||
uint32_t bal;
|
||||
if (ValidUsername(name) && Bank::users.modify_if(name, [&bal, amount](User &u) { bal = (u.balance < (amount * -1) ? u.balance = 0 : u.balance += amount); }))
|
||||
if (ValidUsername(name) && Bank::users.modify_if(name, [&bal, &amount](User &u) {
|
||||
if (u.balance < (amount * -1)) { amount = -int64_t(u.balance); };
|
||||
bal = u.balance += amount;
|
||||
#if MAX_LOG_SIZE > 0
|
||||
u.log.AddTrans("Ω", (amount > 0), std::abs(amount), time(NULL));
|
||||
#endif
|
||||
}))
|
||||
{
|
||||
SET_CHANGES_ON;
|
||||
return {k200OK, std::to_string(bal)}; //may return new balance
|
||||
|
|
|
|||
|
|
@ -54,6 +54,30 @@ void api::GetLogsV2(req_args)
|
|||
#endif
|
||||
}
|
||||
|
||||
void api::GetLogsRange(req_args, size_t start, size_t length)
|
||||
{
|
||||
#if MAX_LOG_SIZE > 0
|
||||
RESPONSE_PARSE(Bank::GetLogsRange(NAME_PARAM, start, length));
|
||||
#else
|
||||
auto resp = HttpResponse::newCustomHttpResponse(BankResponse{k404NotFound, "\"Logs are Disabled\""});
|
||||
CORS;
|
||||
CACHE_FOREVER;
|
||||
callback(resp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void api::AdminGetLogs(req_args, const std::string& name)
|
||||
{
|
||||
#if MAX_LOG_SIZE > 0
|
||||
RESPONSE_PARSE(Bank::GetLogsV2(name));
|
||||
#else
|
||||
auto resp = HttpResponse::newCustomHttpResponse(BankResponse{k404NotFound, "\"Logs are Disabled\""});
|
||||
CORS;
|
||||
CACHE_FOREVER;
|
||||
callback(resp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void api::SendFunds(req_args)
|
||||
{
|
||||
SIMD_JSON_GEN;
|
||||
|
|
|
|||
100
src/log.cpp
100
src/log.cpp
|
|
@ -9,7 +9,7 @@ void Log::AddTrans(const std::string &counterparty_str, bool receiving, uint32_t
|
|||
|
||||
if (data.size() == MAX_LOG_SIZE)
|
||||
{
|
||||
data.pop_back();
|
||||
data.pop_front();
|
||||
}
|
||||
data.emplace_back(counterparty_str, receiving, amount, time);
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ void Log::AddTrans(const std::string &counterparty_str, bool receiving, uint32_t
|
|||
#if USE_DEPRECATED_ENDPOINTS
|
||||
std::string Log::GetLogs(const std::string& name) noexcept
|
||||
{
|
||||
if (log_flag.GetChangeState() && data.size()) //if there are changes
|
||||
if (log_flag.GetChangeState() && data.size()) // if there are changes
|
||||
{
|
||||
log_snapshot.resize(0);
|
||||
//re-generate snapshot
|
||||
|
|
@ -49,7 +49,7 @@ std::string Log::GetLogs(const std::string& name) noexcept
|
|||
|
||||
std::string Log::GetLogsV2() noexcept
|
||||
{
|
||||
if (log_flag_v2.GetChangeState() && data.size()) //if there are changes
|
||||
if (log_flag_v2.GetChangeState() && data.size()) // if there are changes
|
||||
{
|
||||
log_snapshot_v2.resize(0);
|
||||
//re-generate snapshot
|
||||
|
|
@ -59,11 +59,11 @@ std::string Log::GetLogsV2() noexcept
|
|||
log_snapshot_v2.reserve(predicted_size);
|
||||
}
|
||||
log_snapshot_v2 = '['; //1
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
for (size_t i = data.size(); i --> 0;)
|
||||
{
|
||||
log_snapshot_v2 += "{\"counterparty\":\""; //17
|
||||
log_snapshot_v2 += data[i].counterparty; //max_name_size?
|
||||
log_snapshot_v2 += "\",\"amount\":"; //11
|
||||
log_snapshot_v2 += "\",\"amount\":"; //11
|
||||
if (!data[i].receiving) { log_snapshot_v2 += '-'; } //1
|
||||
log_snapshot_v2 += std::to_string(data[i].amount); //10?
|
||||
log_snapshot_v2 += ",\"time\":"; //8
|
||||
|
|
@ -76,3 +76,93 @@ std::string Log::GetLogsV2() noexcept
|
|||
|
||||
return log_snapshot_v2;
|
||||
}
|
||||
|
||||
std::string Log::GetLogsRange(size_t start, size_t length) noexcept
|
||||
{
|
||||
if (start >= data.size()) { return "[]"; }
|
||||
if (start == 0 && length == MAX_LOG_SIZE) { return log_snapshot_v2; }
|
||||
if (log_flag_v2.GetChangeState() && data.size()) { GetLogsV2(); }
|
||||
|
||||
size_t log_index_n, i;
|
||||
if (start < (0.5 * MAX_LOG_SIZE))
|
||||
{
|
||||
// std::cout << "a\n";
|
||||
i = 0;
|
||||
log_index_n = 0;
|
||||
while(i < log_snapshot_v2.size())
|
||||
{
|
||||
if (log_index_n == start)
|
||||
{
|
||||
log_index_n = i;
|
||||
break;
|
||||
}
|
||||
i += (41 + min_name_size);
|
||||
while (log_snapshot_v2[i] != ',') { ++i; }
|
||||
++log_index_n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cout << "b\n";
|
||||
i = log_snapshot_v2.size();
|
||||
log_index_n = data.size();
|
||||
while(i --> 0)
|
||||
{
|
||||
if (log_index_n == start)
|
||||
{
|
||||
log_index_n = i + 1;
|
||||
break;
|
||||
}
|
||||
i -= (41 + min_name_size);
|
||||
while (log_snapshot_v2[i] != ',') { --i; }
|
||||
--log_index_n;
|
||||
}
|
||||
}
|
||||
|
||||
size_t log_index_m = std::string::npos;
|
||||
if ((start + length) < data.size())
|
||||
{
|
||||
if (length < (0.5 * MAX_LOG_SIZE))
|
||||
{
|
||||
// std::cout << "c\n";
|
||||
log_index_m = 0;
|
||||
while(i < log_snapshot_v2.size())
|
||||
{
|
||||
if (log_index_m == length)
|
||||
{
|
||||
log_index_m = i + 1;
|
||||
break;
|
||||
}
|
||||
i += (41 + min_name_size);
|
||||
while (log_snapshot_v2[i] != ',') { ++i; }
|
||||
++log_index_m;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cout << "d\n";
|
||||
i = log_snapshot_v2.size();
|
||||
log_index_m = data.size();
|
||||
while(i --> 0)
|
||||
{
|
||||
if (log_index_m == length)
|
||||
{
|
||||
log_index_m = i + 1;
|
||||
break;
|
||||
}
|
||||
i -= (41 + min_name_size);
|
||||
while (log_snapshot_v2[i] != ',') { --i; }
|
||||
--log_index_m;
|
||||
}
|
||||
}
|
||||
|
||||
log_index_m -= log_index_n;
|
||||
}
|
||||
|
||||
std::string res(log_snapshot_v2.substr(log_index_n, log_index_m));
|
||||
res[0] = '[';
|
||||
res[res.size() - 1] = ']';
|
||||
// std::cout << res << '\n';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ inline bool ValidUsername(const std::string &name) noexcept
|
|||
}
|
||||
for (char c : name)
|
||||
{
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_'))
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue