mirror of
https://github.com/Expand-sys/CCash
synced 2025-12-16 08:12:12 +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
|
#endif
|
||||||
Op(Bank::GetLogsV2("twix"), "get logs init (v2): ", 1);
|
Op(Bank::GetLogsV2("twix"), "get logs init (v2): ", 1);
|
||||||
Op(Bank::GetLogsV2("twix"), "get logs cached (v2): ", 1000000);
|
Op(Bank::GetLogsV2("twix"), "get logs cached (v2): ", 1000000);
|
||||||
|
Op(Bank::GetLogsRange("twix", 0, 100), "get logs range: ", 1000000);
|
||||||
#endif
|
#endif
|
||||||
Op(Bank::PruneUsers(0, 0), "prune users: ", 1);
|
Op(Bank::PruneUsers(0, 0), "prune users: ", 1);
|
||||||
Op(Bank::Save(), "saving: ", 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;
|
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.
|
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
|
### Why is my username invalid
|
||||||
Usernames are restricted by minecraft's requirements
|
Usernames are restricted by minecraft's requirements
|
||||||
* lowercase letters
|
* letters
|
||||||
* numbers
|
* numbers
|
||||||
* _
|
* _
|
||||||
* length must be atleast 3 and at most 16 characters.
|
* 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).
|
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
|
### My instance is taking up too much storage or RAM
|
||||||
Reduce log size and/or use the prune users endpoint to remove dead accounts.
|
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
|
### 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.
|
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: |
|
| supported | :heavy_check_mark: |
|
||||||
| uses deprecated endpoints | ⚠ |
|
| uses deprecated endpoints | ⚠ |
|
||||||
| uses defunt endpoints | :no_entry: |
|
| uses defunt endpoints | :no_entry: |
|
||||||
|
| in development | :hammer: |
|
||||||
|
|
||||||
## General
|
## General
|
||||||
| author | name | support | image |
|
| 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) | [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: | |
|
|
||||||
| [ArcNyxx](https://github.com/ArcNyxx) | [CCash CLI](https://github.com/ArcNyxx/ccash_cmd) | ⚠ | |
|
| [ArcNyxx](https://github.com/ArcNyxx) | [CCash CLI](https://github.com/ArcNyxx/ccash_cmd) | ⚠ | |
|
||||||
|
|
||||||
## Minecraft
|
## Minecraft
|
||||||
| author | name | support | image |
|
| 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) | [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) | [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) | [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: | |
|
| [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
|
## Desired
|
||||||
| idea | description |
|
| idea | description |
|
||||||
|
|
|
||||||
|
|
@ -17,73 +17,77 @@
|
||||||
## all error responses have JSON string along with them to describe
|
## all error responses have JSON string along with them to describe
|
||||||
|
|
||||||
### Usage endpoints
|
### Usage endpoints
|
||||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
| 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: |
|
| 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: |
|
| 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: |
|
||||||
| 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: |
|
| 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: |
|
||||||
| 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: |
|
| 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: |
|
||||||
| 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: |
|
| 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
|
### Usage enpoint errors
|
||||||
| name | 400 | 401 | 404 | 406 |
|
| name | 400 | 401 | 404 | 406 |
|
||||||
| :------------- | :----------------: | :----------------: | :----------------: | :----------------: |
|
| :------------- | :----------------: | :----------------: | :----------------: | :----------------: |
|
||||||
| GetBal | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
|
| GetBal | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| GetLog | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
| GetLogs | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| GetLogV2 | :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: |
|
| SendFunds | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| VerifyPassword | :x: | :heavy_check_mark: | :x: | :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
|
### Meta Usage endpoints
|
||||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
| name | last change | 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: |
|
| 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: |
|
| 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: |
|
| 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: |
|
||||||
| 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: |
|
| 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
|
### Meta Usage endpoint errors
|
||||||
| name | 400 | 401 | 404 | 406 |
|
| 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: |
|
| 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: |
|
| 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: |
|
| ImpactBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
|
|
||||||
### Sytem Usage endpoints
|
### Sytem Usage endpoints
|
||||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
| 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: |
|
| 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: |
|
| 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: |
|
| 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: |
|
||||||
| 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: |
|
||||||
| 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: |
|
||||||
| 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
|
### System Usage endpoin errors
|
||||||
| name | 401 | 404 | 406 |
|
| name | 401 | 404 | 406 |
|
||||||
| :----------------- | :----------------: | :----------------: | :----------------: |
|
| :------------ | :----------------: | :----------------: | :----------------: |
|
||||||
| Help | :x: | :x: | :x: |
|
| Help | :x: | :x: | :x: |
|
||||||
| Close | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
| Close | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
||||||
| Contains | :heavy_check_mark: | :heavy_check_mark: | :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: |
|
||||||
| PruneUsers | :heavy_check_mark: | :x: | :heavy_check_mark: |
|
| ApiProperties | :x: | :x: | :x: |
|
||||||
| ApiProperties | :x: | :x: | :x: |
|
|
||||||
|
|
||||||
### Username Requirements
|
### Username Requirements
|
||||||
Valid
|
Valid
|
||||||
* lowercase letters
|
* letters
|
||||||
* numbers
|
* numbers
|
||||||
* _
|
* _
|
||||||
* Length must be atleast 3 and at most 16 characters.
|
* Length must be atleast 3 and at most 16 characters.
|
||||||
|
|
||||||
### User Management endpoints
|
### User Management endpoints
|
||||||
| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U |
|
| 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: |
|
| 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: |
|
| 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: |
|
| 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: |
|
| 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
|
### User Management endpoint errors
|
||||||
| name | 400 | 401 | 404 | 406 | 409 |
|
| name | 400 | 401 | 404 | 406 | 409 |
|
||||||
|
|
|
||||||
|
|
@ -49,13 +49,13 @@ public:
|
||||||
static BankResponse GetLogs(const std::string &name) noexcept;
|
static BankResponse GetLogs(const std::string &name) noexcept;
|
||||||
#endif
|
#endif
|
||||||
static BankResponse GetLogsV2(const std::string &name) noexcept;
|
static BankResponse GetLogsV2(const std::string &name) noexcept;
|
||||||
|
static BankResponse GetLogsRange(const std::string &name, size_t n, size_t m) noexcept;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static BankResponse SendFunds(const std::string &a_name, const std::string &b_name, uint32_t amount) noexcept;
|
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 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 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 BankResponse ImpactBal(const std::string &name, int64_t amount) noexcept;
|
||||||
static bool Contains(const std::string &name) noexcept;
|
static bool Contains(const std::string &name) noexcept;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,20 @@ public:
|
||||||
static void GetLogs(req_args);
|
static void GetLogs(req_args);
|
||||||
#endif
|
#endif
|
||||||
static void GetLogsV2(req_args);
|
static void GetLogsV2(req_args);
|
||||||
|
static void GetLogsRange(req_args, size_t start, size_t length);
|
||||||
static void SendFunds(req_args);
|
static void SendFunds(req_args);
|
||||||
|
static void ChangePassword(req_args);
|
||||||
static void VerifyPassword(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 AdminChangePassword(req_args);
|
||||||
|
static void AdminVerifyAccount(req_args);
|
||||||
static void SetBal(req_args);
|
static void SetBal(req_args);
|
||||||
static void ImpactBal(req_args);
|
static void ImpactBal(req_args);
|
||||||
|
|
||||||
static void Help(req_args);
|
static void Help(req_args);
|
||||||
static void Close(req_args);
|
static void Close(req_args);
|
||||||
static void Contains(req_args, const std::string &name);
|
static void Contains(req_args, const std::string &name);
|
||||||
static void AdminVerifyAccount(req_args);
|
|
||||||
static void PruneUsers(req_args);
|
static void PruneUsers(req_args);
|
||||||
static void ApiProperties(req_args);
|
static void ApiProperties(req_args);
|
||||||
|
|
||||||
|
|
@ -38,39 +40,49 @@ public:
|
||||||
|
|
||||||
METHOD_LIST_BEGIN
|
METHOD_LIST_BEGIN
|
||||||
|
|
||||||
METHOD_ADD(api::Help, "/help", Get, Options);
|
|
||||||
METHOD_ADD(api::ApiProperties, "/properties", Get, Options);
|
|
||||||
|
|
||||||
//Usage
|
//Usage
|
||||||
METHOD_ADD(api::GetBal, "/v1/user/balance?name={name}", Get, Options, "JsonFilter<false>");
|
METHOD_ADD(api::GetBal, "/v1/user/balance?name={name}", Get, Options, "JsonFilter<false>");
|
||||||
|
|
||||||
#if MAX_LOG_SIZE > 0
|
#if MAX_LOG_SIZE > 0
|
||||||
|
|
||||||
#if USE_DEPRECATED_ENDPOINTS
|
#if USE_DEPRECATED_ENDPOINTS
|
||||||
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
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
|
#else
|
||||||
|
|
||||||
#if USE_DEPRECATED_ENDPOINTS
|
#if USE_DEPRECATED_ENDPOINTS
|
||||||
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>");
|
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter<false>");
|
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
|
#endif
|
||||||
|
|
||||||
METHOD_ADD(api::SendFunds, "/v1/user/transfer", Post, Options, "JsonFilter<true>", "UserFilter<true, false>"); //expects ["name"](string) and ["amount"](uint32)
|
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>");
|
METHOD_ADD(api::VerifyPassword, "/v1/user/verify_password", Post, Options, "UserFilter<false, false>", "JsonFilter<false>");
|
||||||
|
|
||||||
//Meta Usage
|
//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::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::AdminVerifyAccount, "/v1/admin/verify_account", Post, Options, "UserFilter<false, true>", "JsonFilter<false>");
|
||||||
METHOD_ADD(api::ImpactBal, "/v1/admin/impact_balance", Post, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) and ["amount"](uint32)
|
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
|
//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::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::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::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
|
//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::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::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)
|
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;
|
std::string GetLogs(const std::string& name) noexcept;
|
||||||
#endif
|
#endif
|
||||||
std::string GetLogsV2() noexcept;
|
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;
|
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};
|
uint8_t temp[16]{16, 0, 0, 0, 4};
|
||||||
users_save.write((char *)temp, 16);
|
users_save.write((char *)temp, 16);
|
||||||
users_save.close();
|
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
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "File cannot be created (may already exist)\n";
|
std::cerr << "File cannot be created (may already exist)\n";
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
std::cerr << "Usage: sudo ./bank <admin account> <saving frequency in minutes> [daemon flag {default: false}]\n";
|
std::cerr << "Usage: sudo ./bank <admin account> <saving frequency in minutes> [daemon flag {default: false}]\n";
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
if (geteuid() != 0)
|
if (geteuid() != 0)
|
||||||
{
|
{
|
||||||
std::cerr << "ERROR: CCash MUST be ran as root\n";
|
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]));
|
const unsigned long saving_freq = std::stoul(std::string(argv[2]));
|
||||||
std::cout
|
std::cout
|
||||||
<< "\nAPI : v2.5.1"
|
<< "\nAPI : v2.6.1\n"
|
||||||
<< "\n\nAVX : " << (__builtin_cpu_supports("avx") ? "enabled" : "disabled")
|
<< "\nAVX : " << (__builtin_cpu_supports("avx") ? "enabled" : "disabled")
|
||||||
<< "\nAVX 2 : " << (__builtin_cpu_supports("avx2") ? "enabled" : "disabled")
|
<< "\nAVX 2 : " << (__builtin_cpu_supports("avx2") ? "enabled" : "disabled")
|
||||||
<< "\nSSE 2 : " << (__builtin_cpu_supports("sse2") ? "enabled" : "disabled")
|
<< "\nSSE 2 : " << (__builtin_cpu_supports("sse2") ? "enabled" : "disabled")
|
||||||
<< "\nSSE 3 : " << (__builtin_cpu_supports("sse3") ? "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
|
if (saving_freq) //if saving frequency is 0 then auto saving is turned off
|
||||||
{
|
{
|
||||||
std::thread([saving_freq]()
|
std::thread([saving_freq]()
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::minutes(saving_freq));
|
std::this_thread::sleep_for(std::chrono::minutes(saving_freq));
|
||||||
std::cout << "Saving " << std::time(0) << "...\n"
|
std::cout << "Saving " << std::time(0) << "...\n" << Bank::Save();
|
||||||
<< Bank::Save();
|
}
|
||||||
}
|
})
|
||||||
})
|
.detach();
|
||||||
.detach();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 4 && !strcmp(argv[3], "true")) { app().enableRunAsDaemon(); }
|
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
|
} //destroying setup variables
|
||||||
|
|
||||||
app()
|
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)
|
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;
|
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
|
#endif
|
||||||
|
|
||||||
BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_name, uint32_t amount) noexcept
|
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)); });
|
Bank::users.if_contains(name, [&res, &attempt](const User &u) { res = (u.password == xxHashStringGen{}(attempt)); });
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bank::ChangePassword(const std::string &name, const std::string &new_pass) noexcept
|
void Bank::ChangePassword(const std::string &name, const std::string &new_pass) noexcept
|
||||||
{
|
{
|
||||||
SET_CHANGES_ON;
|
SET_CHANGES_ON;
|
||||||
Bank::users.modify_if(name, [&new_pass](User &u) { u.password = xxHashStringGen{}(new_pass); });
|
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;
|
SET_CHANGES_ON;
|
||||||
return {k204NoContent, std::nullopt}; //returns new balance
|
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\""};
|
return {k400BadRequest, "\"Amount cannot be 0\""};
|
||||||
}
|
}
|
||||||
uint32_t bal;
|
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;
|
SET_CHANGES_ON;
|
||||||
return {k200OK, std::to_string(bal)}; //may return new balance
|
return {k200OK, std::to_string(bal)}; //may return new balance
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,30 @@ void api::GetLogsV2(req_args)
|
||||||
#endif
|
#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)
|
void api::SendFunds(req_args)
|
||||||
{
|
{
|
||||||
SIMD_JSON_GEN;
|
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)
|
if (data.size() == MAX_LOG_SIZE)
|
||||||
{
|
{
|
||||||
data.pop_back();
|
data.pop_front();
|
||||||
}
|
}
|
||||||
data.emplace_back(counterparty_str, receiving, amount, time);
|
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
|
#if USE_DEPRECATED_ENDPOINTS
|
||||||
std::string Log::GetLogs(const std::string& name) noexcept
|
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);
|
log_snapshot.resize(0);
|
||||||
//re-generate snapshot
|
//re-generate snapshot
|
||||||
|
|
@ -49,7 +49,7 @@ std::string Log::GetLogs(const std::string& name) noexcept
|
||||||
|
|
||||||
std::string Log::GetLogsV2() 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);
|
log_snapshot_v2.resize(0);
|
||||||
//re-generate snapshot
|
//re-generate snapshot
|
||||||
|
|
@ -59,11 +59,11 @@ std::string Log::GetLogsV2() noexcept
|
||||||
log_snapshot_v2.reserve(predicted_size);
|
log_snapshot_v2.reserve(predicted_size);
|
||||||
}
|
}
|
||||||
log_snapshot_v2 = '['; //1
|
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 += "{\"counterparty\":\""; //17
|
||||||
log_snapshot_v2 += data[i].counterparty; //max_name_size?
|
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
|
if (!data[i].receiving) { log_snapshot_v2 += '-'; } //1
|
||||||
log_snapshot_v2 += std::to_string(data[i].amount); //10?
|
log_snapshot_v2 += std::to_string(data[i].amount); //10?
|
||||||
log_snapshot_v2 += ",\"time\":"; //8
|
log_snapshot_v2 += ",\"time\":"; //8
|
||||||
|
|
@ -76,3 +76,93 @@ std::string Log::GetLogsV2() noexcept
|
||||||
|
|
||||||
return log_snapshot_v2;
|
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)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue