From 15d5ac704abc63c3f11ac8743cbd2ffa1fb70c88 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 30 Jan 2011 14:59:17 +0800 Subject: [PATCH] Removing explicit mentions to users in the cokebank - Also did more work on the SQLite implementation - Updated terminology in schema > Changed the wheel flag to a more general administrator flag --- notes/Database Structure.txt | 3 +- src/cokebank.h | 34 ++++++------ src/cokebank_basic/main.c | 48 ++++++++--------- src/cokebank_sqlite/main.c | 102 ++++++++++++++++++++++++++--------- src/server/dispense.c | 20 +++---- src/server/main.c | 5 +- src/server/server.c | 16 +++--- 7 files changed, 137 insertions(+), 91 deletions(-) diff --git a/notes/Database Structure.txt b/notes/Database Structure.txt index 2680507..07e290e 100644 --- a/notes/Database Structure.txt +++ b/notes/Database Structure.txt @@ -12,7 +12,8 @@ User DATETIME LastSeen BOOL bEnabled BOOL bCokeMember - BOOL bWheelMember + BOOL bDoorMember + BOOL bAdministrator ; Database admin (create/delete/lock accounts) BOOL bInternal diff --git a/src/cokebank.h b/src/cokebank.h index 30678c9..9450ecf 100644 --- a/src/cokebank.h +++ b/src/cokebank.h @@ -69,40 +69,40 @@ extern int Bank_Initialise(const char *Argument); * \param Ammount Amount of money (in cents) to transfer * \param Reason Reason for the transfer */ -extern int Bank_Transfer(int SourceUser, int DestUser, int Ammount, const char *Reason); +extern int Bank_Transfer(int SourceAcct, int DestAcct, int Ammount, const char *Reason); /** * \brief Get flags on an account - * \param User UID to get flags from + * \param AcctID UID to get flags from * \return Flag set as defined in eCokebank_Flags */ -extern int Bank_GetFlags(int User); +extern int Bank_GetFlags(int AcctID); /** * \brief Set an account's flags - * \param User UID to set flags on + * \param AcctID UID to set flags on * \param Mask Mask of flags changed * \param Value Final value of changed flags */ -extern int Bank_SetFlags(int User, int Mask, int Value); +extern int Bank_SetFlags(int AcctID, int Mask, int Value); /** * \brief Get an account's balance - * \param User UID to query + * \param AcctID Account to query */ -extern int Bank_GetBalance(int User); +extern int Bank_GetBalance(int AcctID); /** * \brief Get the name associated with an account * \return Heap string */ -extern char *Bank_GetUserName(int User); +extern char *Bank_GetAcctName(int AcctID); /** - * \brief Get a UID from a passed name + * \brief Get an account ID from a passed name */ -extern int Bank_GetUserID(const char *Username); +extern int Bank_GetAcctByName(const char *Name); /** * \brief Create a new account * \param Username Name for the new account (if NULL, an anoymous account is created) - * \return User ID of the new account + * \return ID of the new account */ -extern int Bank_CreateUser(const char *Username); +extern int Bank_CreateAcct(const char *Name); /** * \brief Create an account iterator @@ -119,7 +119,7 @@ extern tAcctIterator *Bank_Iterator(int FlagMask, int FlagValues, /** * \brief Get the current entry in the iterator and move to the next * \param It Iterator returned by Bank_Iterator - * \return User ID or -1 for end of list + * \return Accoun ID, or -1 for end of list */ extern int Bank_IteratorNext(tAcctIterator *It); @@ -139,14 +139,14 @@ extern void Bank_DelIterator(tAcctIterator *It); extern int Bank_GetUserAuth(const char *Salt, const char *Username, const char *Password); /** - * \brief Get a User ID from a MIFARE card ID + * \brief Get an account ID from a MIFARE card ID * \param CardID MIFARE card ID - * \return User ID + * \return Account ID */ -extern int Bank_GetUserByCard(const char *CardID); +extern int Bank_GetAcctByCard(const char *CardID); /** - * \brief Add a card to a user's account + * \brief Add a card to an git account * \param User User ID * \param CardID MIFARE card ID * \return Boolean failure diff --git a/src/cokebank_basic/main.c b/src/cokebank_basic/main.c index 7775dba..d5d7f25 100644 --- a/src/cokebank_basic/main.c +++ b/src/cokebank_basic/main.c @@ -51,23 +51,12 @@ struct sAcctIterator }; // === PROTOTYPES === -void Init_Cokebank(const char *Argument); static int Bank_int_ReadDatabase(void); static int Bank_int_WriteEntry(int ID); - int Bank_Transfer(int SourceUser, int DestUser, int Ammount, const char *Reason); - int Bank_CreateUser(const char *Username); -tAcctIterator *Bank_Iterator(int FlagMask, int FlagValues, - int Flags, int MinMaxBalance, time_t LastSeen); - int Bank_GetUserID(const char *Username); - int Bank_GetBalance(int User); - int Bank_GetFlags(int User); - int Bank_SetFlags(int User, int Mask, int Value); int Bank_int_AlterUserBalance(int ID, int Delta); int Bank_int_GetMinAllowedBalance(int ID); int Bank_int_AddUser(const char *Username); -char *Bank_GetUserName(int User); int Bank_int_GetUnixID(const char *Username); - int Bank_GetUserAuth(const char *Salt, const char *Username, const char *Password); #if USE_LDAP char *ReadLDAPValue(const char *Filter, char *Value); #endif @@ -89,7 +78,7 @@ tUser **gaBank_UsersByBalance; /* * \brief Load the cokebank database */ -void Init_Cokebank(const char *Argument) +int Bank_Initialise(const char *Argument) { #if USE_LDAP int rv; @@ -98,7 +87,10 @@ void Init_Cokebank(const char *Argument) // Open Cokebank gBank_File = fopen(Argument, "rb+"); if( !gBank_File ) gBank_File = fopen(Argument, "wb+"); - if( !gBank_File ) perror("Opening coke bank"); + if( !gBank_File ) { + perror("Opening coke bank"); + return -1; + } Bank_int_ReadDatabase(); // Open log file @@ -112,19 +104,19 @@ void Init_Cokebank(const char *Argument) rv = ldap_create(&gpLDAP); if(rv) { fprintf(stderr, "ldap_create: %s\n", ldap_err2string(rv)); - exit(1); + return 1; } rv = ldap_initialize(&gpLDAP, gsLDAPPath); if(rv) { fprintf(stderr, "ldap_initialize: %s\n", ldap_err2string(rv)); - exit(1); + return 1; } { int ver = LDAP_VERSION3; ldap_set_option(gpLDAP, LDAP_OPT_PROTOCOL_VERSION, &ver); } # if 0 rv = ldap_start_tls_s(gpLDAP, NULL, NULL); if(rv) { fprintf(stderr, "ldap_start_tls_s: %s\n", ldap_err2string(rv)); - exit(1); + return 1; } # endif { @@ -136,10 +128,12 @@ void Init_Cokebank(const char *Argument) "", &cred, NULL, NULL, &servcred); if(rv) { fprintf(stderr, "ldap_start_tls_s: %s\n", ldap_err2string(rv)); - exit(1); + return 1; } } #endif + + return 0; } /** @@ -188,7 +182,7 @@ static int Bank_int_ReadDatabase(void) gaBank_Users[i].UnixID = fu.UnixID; gaBank_Users[i].Balance = fu.Balance; gaBank_Users[i].Flags = fu.Flags; - gaBank_Users[i].Name = Bank_GetUserName(i); + gaBank_Users[i].Name = Bank_GetAcctName(i); gaBank_UsersByName[i] = &gaBank_Users[i]; // Add to name index gaBank_UsersByBalance[i] = &gaBank_Users[i]; // Add to balance index } @@ -259,14 +253,14 @@ int Bank_Transfer(int SourceUser, int DestUser, int Ammount, const char *Reason) return 0; } -int Bank_CreateUser(const char *Username) +int Bank_CreateAcct(const char *Name) { int ret; - ret = Bank_GetUserID(Username); + ret = Bank_GetAcctByName(Name); if( ret != -1 ) return -1; - return Bank_int_AddUser(Username); + return Bank_int_AddUser(Name); } tAcctIterator *Bank_Iterator(int FlagMask, int FlagValues, int Flags, int MinMaxBalance, time_t LastSeen) @@ -351,7 +345,7 @@ void Bank_DelIterator(tAcctIterator *It) /* * \brief Get the User ID of the named user */ -int Bank_GetUserID(const char *Username) +int Bank_GetAcctByName(const char *Username) { #if 0 int i, size; @@ -547,7 +541,7 @@ int Bank_int_AddUser(const char *Username) giBank_NumUsers ++; // Get name - gaBank_Users[giBank_NumUsers-1].Name = Bank_GetUserName(giBank_NumUsers-1); + gaBank_Users[giBank_NumUsers-1].Name = Bank_GetAcctName(giBank_NumUsers-1); // Update indexes qsort(gaBank_UsersByName, giBank_NumUsers, sizeof(tUser*), Bank_int_CompareNames); @@ -563,7 +557,7 @@ int Bank_int_AddUser(const char *Username) // Unix user dependent code // TODO: Modify to keep its own list of usernames // --- -char *Bank_GetUserName(int ID) +char *Bank_GetAcctName(int ID) { struct passwd *pwd; @@ -631,13 +625,13 @@ int Bank_GetUserAuth(const char *Salt, const char *Username, const char *Passwor #if HACK_TPG_NOAUTH if( strcmp(Username, "tpg") == 0 ) - return Bank_GetUserID("tpg"); + return Bank_GetAcctByName("tpg"); #endif #if HACK_ROOT_NOAUTH if( strcmp(Username, "root") == 0 ) { - int ret = Bank_GetUserID("root"); + int ret = Bank_GetAcctByName("root"); if( ret == -1 ) - return Bank_CreateUser("root"); + return Bank_CreateAcct("root"); return ret; } #endif diff --git a/src/cokebank_sqlite/main.c b/src/cokebank_sqlite/main.c index 959a81f..858f594 100644 --- a/src/cokebank_sqlite/main.c +++ b/src/cokebank_sqlite/main.c @@ -31,10 +31,13 @@ const char * const csBank_CreateCardsQry = "CREATE TABLE IF NOT EXISTS cards (" // === PROTOYPES === int Bank_Initialise(const char *Argument); - int Bank_Transfer(int SourceUser, int DestUser, int Ammount, const char *Reason); - int Bank_GetUserFlags(int UserID); - int Bank_SetUserFlags(int UserID, int Mask, int Value); + int Bank_Transfer(int SourceAcct, int DestAcct, int Ammount, const char *Reason); + int Bank_GetUserFlags(int AcctID); + int Bank_SetUserFlags(int AcctID, int Mask, int Value); + int Bank_GetBalance(int AcctID); +char *Bank_GetAcctName(int AcctID); sqlite3_stmt *Bank_int_MakeStatemnt(sqlite3 *Database, const char *Query); +sqlite3_stmt *Bank_int_QuerySingle(sqlite3 *Database, const char *Query); // === GLOBALS === sqlite3 *gBank_Database; @@ -143,28 +146,14 @@ int Bank_GetUserFlags(int UserID) int ret; // Build Query - query = mkstr("SELECT acct_is_disabled,acct_is_coke,acct_is_wheel,acct_is_door,acct_is_internal FROM accounts WHERE acct_id=%i LIMIT 1", UserID); - rv = sqlite3_prepare_v2(gBank_Database, query, strlen(query)+1, &statement, NULL); + query = mkstr( + "SELECT acct_is_disabled,acct_is_coke,acct_is_wheel,acct_is_door,acct_is_internal" + " FROM accounts WHERE acct_id=%i LIMIT 1", + UserID + ); + statement = Bank_int_QuerySingle(gBank_Database, query); free(query); - if( rv != SQLITE_OK ) { - fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(gBank_Database)); - return -1; - } - - // Execute Query - rv = sqlite3_step(statement); - if( rv != SQLITE_ROW ) - { - sqlite3_finalise(statement); - if( rv == SQLITE_DONE ) - { - return -1; // User not found - } - if( rv != SQLITE_OK ) { - fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(gBank_Database)); - return -1; - } - } + if( !statement ) return -1; // Get Flags ret = 0; @@ -221,16 +210,50 @@ int Bank_SetUserFlags(int UserID, int Mask, int Value) /* * Get user balance */ -int Bank_GetBalance(int User) +int Bank_GetBalance(int AcctID) { sqlite3_stmt *statement; char *query; + int ret; - query = mkstr("SELECT acct_balance FROM accounts WHERE acct_id=%i", User); + query = mkstr("SELECT acct_balance FROM accounts WHERE acct_id=%i LIMIT 1", AcctID); + statement = Bank_int_QuerySingle(gBank_Database, query); + free(query); + if( !statement ) return INT_MIN; + + // Read return value + ret = sqlite3_column_int(statement, 0); + // Clean up and return + sqlite3_finalise(statement); + return ret; } +/* + * Get the name of an account + */ +char *Bank_GetUserName(int AcctID) +{ + sqlite3_stmt *statement; + char *query; + char *ret; + + query = mkstr("SELECT acct_name FROM accounts WHERE acct_id=%i LIMIT 1", AcctID); + statement = Bank_int_QuerySingle(gBank_Database, query); + free(query); + if( !statement ) return NULL; + + // Read return value + ret = strdup( sqlite3_column_text(statement, 0) ); + + // Clean up and return + sqlite3_finalise(statement); + return ret; +} +/* + * Create a SQLite Statement + */ sqlite3_stmt *Bank_int_MakeStatemnt(sqlite3 *Database, const char *Query) { int rv; @@ -238,6 +261,33 @@ sqlite3_stmt *Bank_int_MakeStatemnt(sqlite3 *Database, const char *Query) rv = sqlite3_prepare_v2(Database, Query, strlen(Query)+1, &ret, NULL); free(query); if( rv != SQLITE_OK ) { + fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(Database)); + fprintf(stderr, "query = \"%s\"\n", Query); + return NULL; + } + + return ret; +} + +/* + * Create a SQLite statement and query it for the first row + * Returns NULL if the the set is empty + */ +sqlite3_stmt *Bank_int_QuerySingle(sqlite3 *Database, const char *Query) +{ + sqlite3_stmt *ret; + int rv; + + // Prepare query + ret = Bank_int_MakeStatemnt(Database, Query); + if( !statement ) return NULL; + + // Get row + rv = sqlite3_step(statement); + // - Empty result set + if( rv == SQLITE_DONE ) return NULL; + // - Other error + if( rv != SQLITE_ROW ) { fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(gBank_Database)); fprintf(stderr, "query = \"%s\"\n", Query); return NULL; diff --git a/src/server/dispense.c b/src/server/dispense.c index 137aab7..b77fa9c 100644 --- a/src/server/dispense.c +++ b/src/server/dispense.c @@ -27,12 +27,12 @@ int DispenseItem(int ActualUser, int User, tItem *Item) // Subtract the balance reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name); if( !reason ) reason = Item->Name; // TODO: Should I instead return an error? - ret = Bank_Transfer( User, Bank_GetUserID(COKEBANK_SALES_ACCT), Item->Price, reason); + ret = Bank_Transfer( User, Bank_GetAcctByName(COKEBANK_SALES_ACCT), Item->Price, reason); free(reason); if(ret) return 2; // 2: No balance // Get username for debugging - username = Bank_GetUserName(User); + username = Bank_GetAcctName(User); // Actually do the dispense if( handler->DoDispense ) { @@ -40,13 +40,13 @@ int DispenseItem(int ActualUser, int User, tItem *Item) if(ret) { Log_Error("Dispense failed after deducting cost (%s dispensing %s - %ic)", username, Item->Name, Item->Price); - Bank_Transfer( Bank_GetUserID(COKEBANK_SALES_ACCT), User, Item->Price, "rollback" ); + Bank_Transfer( Bank_GetAcctByName(COKEBANK_SALES_ACCT), User, Item->Price, "rollback" ); free( username ); return -1; // 1: Unkown Error again } } - actualUsername = Bank_GetUserName(ActualUser); + actualUsername = Bank_GetAcctName(ActualUser); // And log that it happened Log_Info("dispense '%s' (%s:%i) for %s by %s [cost %i, balance %i cents]", @@ -74,9 +74,9 @@ int DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const c if(ret) return 2; // No Balance - srcName = Bank_GetUserName(SrcUser); - dstName = Bank_GetUserName(DestUser); - actualUsername = Bank_GetUserName(ActualUser); + srcName = Bank_GetAcctName(SrcUser); + dstName = Bank_GetAcctName(DestUser); + actualUsername = Bank_GetAcctName(ActualUser); Log_Info("give %i to %s from %s by %s (%s) [balances %i, %i]", Ammount, dstName, srcName, actualUsername, ReasonGiven, @@ -98,11 +98,11 @@ int DispenseAdd(int User, int ByUser, int Ammount, const char *ReasonGiven) int ret; char *dstName, *byName; - ret = Bank_Transfer( Bank_GetUserID(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven ); + ret = Bank_Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven ); if(ret) return 2; - byName = Bank_GetUserName(ByUser); - dstName = Bank_GetUserName(User); + byName = Bank_GetAcctName(ByUser); + dstName = Bank_GetAcctName(User); Log_Info("add %i to %s by %s (%s) [balance %i]", Ammount, dstName, byName, ReasonGiven, Bank_GetBalance(User) diff --git a/src/server/main.c b/src/server/main.c index 8ffcd54..714f513 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -18,9 +18,9 @@ #include #include #include +#include "../cokebank.h" // === IMPORTS === -extern void Init_Cokebank(const char *Argument); // cokebank.c extern void Init_Handlers(void); extern void Load_Itemlist(void); extern void Server_Start(void); @@ -85,7 +85,8 @@ int main(int argc, char *argv[]) openlog("odispense2", 0, LOG_LOCAL4); - Init_Cokebank(gsCokebankPath); + if( Bank_Initialise(gsCokebankPath) ) + return -1; Init_Handlers(); diff --git a/src/server/server.c b/src/server/server.c index b0eb42a..c997c43 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -395,7 +395,7 @@ void Server_Cmd_AUTOAUTH(tClient *Client, char *Args) } // Get UID - Client->UID = Bank_GetUserID( Args ); + Client->UID = Bank_GetAcctByName( Args ); if( Client->UID < 0 ) { if(giDebugLevel) printf("Client %i: Unknown user '%s'\n", Client->ID, Args); @@ -439,7 +439,7 @@ void Server_Cmd_SETEUSER(tClient *Client, char *Args) } // Set id - Client->EffectiveUID = Bank_GetUserID(Args); + Client->EffectiveUID = Bank_GetAcctByName(Args); if( Client->EffectiveUID == -1 ) { sendf(Client->Socket, "404 User not found\n"); return ; @@ -599,7 +599,7 @@ void Server_Cmd_GIVE(tClient *Client, char *Args) reason ++; // Get recipient - uid = Bank_GetUserID(recipient); + uid = Bank_GetAcctByName(recipient); if( uid == -1 ) { sendf(Client->Socket, "404 Invalid target user\n"); return ; @@ -675,7 +675,7 @@ void Server_Cmd_ADD(tClient *Client, char *Args) } // Get recipient - uid = Bank_GetUserID(user); + uid = Bank_GetAcctByName(user); if( uid == -1 ) { sendf(Client->Socket, "404 Invalid user\n"); return ; @@ -797,7 +797,7 @@ void Server_Cmd_USERINFO(tClient *Client, char *Args) if(space) *space = '\0'; // Get recipient - uid = Bank_GetUserID(user); + uid = Bank_GetAcctByName(user); if( uid == -1 ) { sendf(Client->Socket, "404 Invalid user"); return ; @@ -835,7 +835,7 @@ void _SendUserInfo(tClient *Client, int UserID) // TODO: User flags/type sendf( Client->Socket, "202 User %s %i %s%s\n", - Bank_GetUserName(UserID), Bank_GetBalance(UserID), + Bank_GetAcctName(UserID), Bank_GetBalance(UserID), type, disabled ); } @@ -857,7 +857,7 @@ void Server_Cmd_USERADD(tClient *Client, char *Args) if(space) *space = '\0'; // Try to create user - if( Bank_CreateUser(username) == -1 ) { + if( Bank_CreateAcct(username) == -1 ) { sendf(Client->Socket, "404 User exists\n"); return ; } @@ -895,7 +895,7 @@ void Server_Cmd_USERFLAGS(tClient *Client, char *Args) if(space) *space = '\0'; // Get UID - uid = Bank_GetUserID(username); + uid = Bank_GetAcctByName(username); if( uid == -1 ) { sendf(Client->Socket, "404 User '%s' not found\n", username); return ; -- 2.20.1