From 249777a991a936fcc51676725fb9a93118be18c2 Mon Sep 17 00:00:00 2001 From: hieu 79115 Date: Wed, 29 Nov 2023 22:36:05 +0700 Subject: [PATCH] ae tao da hoan thanh xong 20% --- LinkedList.cpp | 2 +- LinkedList.h | 2 +- UserAction.cpp | 73 +++++++------- UserAction.h | 44 ++++++--- UserData.cpp | 17 +++- UserData.h | 7 ++ Users.cpp | 6 +- Users.h | 4 +- main.cpp | 252 +++++++++++++++++++++++++++++++++++++++---------- 9 files changed, 304 insertions(+), 103 deletions(-) diff --git a/LinkedList.cpp b/LinkedList.cpp index 6bf086b..294a0e3 100644 --- a/LinkedList.cpp +++ b/LinkedList.cpp @@ -164,7 +164,7 @@ void LinkedList::selectionSort() { } template -DataType LinkedList::operator[](int index) const { +DataType& LinkedList::operator[](int index) const { Node* _p = _pHead; for (int i = 0; i < index; i++) _p = _p->_pNext; diff --git a/LinkedList.h b/LinkedList.h index d4f682c..86b136b 100644 --- a/LinkedList.h +++ b/LinkedList.h @@ -138,7 +138,7 @@ class LinkedList { * @details Overload operator [] * @return DataType */ - DataType operator[](int index) const; + DataType& operator[](int index) const; }; #endif // CTDL_GK_LINKEDLIST_CPP diff --git a/UserAction.cpp b/UserAction.cpp index bc6ab9e..2961325 100644 --- a/UserAction.cpp +++ b/UserAction.cpp @@ -3,10 +3,9 @@ #include "Users.h" #include "UserData.h" - UserAction::UserAction(std::string role) { _strRole = std::move(role); - _usersList.importUserData(); + _usersList.importUserData(); } UserAction::UserAction() { @@ -14,6 +13,12 @@ UserAction::UserAction() { _usersList.importUserData(); } +void UserAction::setRole(std::string role) { + _strRole = role; + _usersList.~Users(); + _usersList.importUserData(); +} + bool UserAction::addUser(const UserData& user) { if (!(_strRole == "Admin" && _usersList.addUser(user))) return false; CsvFile csvFileEmployee("Employees.txt"); @@ -35,9 +40,8 @@ bool UserAction::addUser(const UserData& user) { return true; } - bool UserAction::deleteUser(const std::string& userName) { - if (_strRole == "Admin") { + if (_strRole == "Admin" && _usersList.removeUser(userName)) { CsvFile csvFileEmployee("Employees.txt"); std::vector> vtEmployeeAccounts = csvFileEmployee.read(); int iLine = -1; @@ -51,50 +55,50 @@ bool UserAction::deleteUser(const std::string& userName) { csvFileEmployee.remove(iLine); CsvFile csvFileDelete(userName + ".txt"); csvFileDelete.del(); - _usersList.removeUser(findUser(userName)); return true; } } return false; } - UserData UserAction::findUser(const std::string& userName) { - if (!(_strRole == "Admin")) return {}; + if (!( _usersList.searchUser(userName)!=-1)) return {}; std::vector vtUsersDataList = _usersList.listUsers(); int userNum = _usersList.searchUser(userName); return vtUsersDataList[userNum]; } -void UserAction::updateUserInformation(const std::string& userName, const UserData& user) { - _usersList.editUser(userName, user); - CsvFile csvFileUser(userName + ".txt"); - csvFileUser.write( - { - {user.getName()}, - {user.getDateOfBirth()}, - {user.getAddress()}, - {user.getPhoneNumber()}, - {user.getEmail()} - } - ); +bool UserAction::updateUserInformation(const std::string& userName, const UserData& user) { + if(!(_usersList.editUser(userName,user))) return false; CsvFile csvFileEmployee("Employees.txt"); std::vector> vtEmployeeAccounts = csvFileEmployee.read(); int iLine = -1; - for (int i = 0; i < vtEmployeeAccounts.size(); i++) { - if (vtEmployeeAccounts[i][0] == user.getName()) { + for (int i = 1; i <= vtEmployeeAccounts.size(); i++) { + if (vtEmployeeAccounts[i][0] == userName) { iLine = i; break; } } - if (iLine != 1) { + if (iLine != -1) { csvFileEmployee.remove(iLine); csvFileEmployee.append( { - {user.getUserName(), ",", user.getPassword()} + {user.getUserName() + "," + user.getPassword()} + } + ); + CsvFile csvFileUser(userName + ".txt"); + csvFileUser.write( + { + {user.getName()}, + {user.getDateOfBirth()}, + {user.getAddress()}, + {user.getPhoneNumber()}, + {user.getEmail()} } ); + return true; } + return false; } std::string UserAction::getUserInformation(const std::string& userName) { @@ -125,19 +129,20 @@ std::vector UserAction::getAllUsersInformation() { } bool UserAction::authenticateUser(const std::string& userName, const std::string& password) { - std::vector> vtUserAccounts; + std::vector> vtAccountsUser; if (_strRole == "Admin") { - CsvFile csvFileUsers("Administrators.txt"); - vtUserAccounts = csvFileUsers.read(); - } else { - CsvFile csvFileUsers("Employees.txt"); - vtUserAccounts = csvFileUsers.read(); + CsvFile csvFileAdmin("Administrators.txt"); + vtAccountsUser = csvFileAdmin.read(); + for (int i = 1; i < vtAccountsUser.size(); i++) { + if (vtAccountsUser[i][0] == userName && vtAccountsUser[i][1] == password) return true; + } } - if (vtUserAccounts.size() != 0) { - for (auto row: vtUserAccounts) { - if (row[0] == userName && row[1] == password) return true; + else { + CsvFile csvFileEmployee("Employees.txt"); + vtAccountsUser = csvFileEmployee.read(); + for (int i = 1; i < vtAccountsUser.size(); i++) { + if (vtAccountsUser[i][0] == userName && vtAccountsUser[i][1] == password) return true; } } return false; -} - +} \ No newline at end of file diff --git a/UserAction.h b/UserAction.h index d41c26d..6c2b3d8 100644 --- a/UserAction.h +++ b/UserAction.h @@ -6,9 +6,16 @@ /** * @class UserAction - * @brief Class for user actions - * @details This class provides functionality for performing various user-related actions, - * such as adding, deleting, finding, editing, and displaying user information. + * @brief Manages actions related to user data and authentication + * + * This class allows creating, reading, updating, and deleting user records + * from a user list. It also handles user authentication. Methods are + * provided for adding new users, finding existing users, updating user + * information, displaying user data, and validating username/password. + * + * Access to full user data is restricted based on the user role set for + * the class instance. The default role has read-only access. The "admin" + * role allows full access to all methods. */ class UserAction { private: @@ -16,10 +23,12 @@ class UserAction { std::string _strRole; public: + /** - * @brief Constructor with role parameter - * @param role User role (default is empty) - */ + * @brief Constructor + * Creates an empty UserAction instance with default empty role. + * @param role User role to assign ("employee" or "admin") + */ explicit UserAction(std::string role = ""); /** @@ -28,15 +37,25 @@ class UserAction { UserAction(); /** - * @brief Add a new user - * @param user UserData object representing the user + * @brief Set user role + * @param role User role to assign ("employee" or "admin") + */ + void setRole(std::string role); + + /** + * @brief Add new user record + * Adds a provided UserData object as a new user record in the user list. + * Accessible only if the instance role is "admin". + * @param user UserData object with new user data + * @return true if the user was added successfully, false otherwise */ bool addUser(const UserData& user); /** - * @brief Delete a user. - * @param user UserData object representing the user to be deleted. - */ + * @brief Delete a user + * @param userName Username of the user to be deleted + * @return true if the user was deleted successfully, false otherwise + */ bool deleteUser(const std::string& userName); /** @@ -50,8 +69,9 @@ class UserAction { * @brief Edit user information * @param userName Username of the user to edit * @param editedUser UserData object representing the edited user information + * @return true if the user information was edited successfully, false otherwise */ - void updateUserInformation(const std::string& userName,const UserData& user); + bool updateUserInformation(const std::string& userName, const UserData& user); /** * @brief Display user information diff --git a/UserData.cpp b/UserData.cpp index 46d81c9..cbd8526 100644 --- a/UserData.cpp +++ b/UserData.cpp @@ -108,4 +108,19 @@ std::string UserData::getRole() const { return _strRole; } bool UserData::operator!=(const UserData& user) const { return _strUserName != user._strUserName || _strPassword != user._strPassword || _strRole != user._strRole || _strName != user._strName || _strDateOfBirth != user._strDateOfBirth || _iAge != user._iAge || _strAddress != user._strAddress || _strPhoneNumber != user._strPhoneNumber || _strEmail != user._strEmail; -} \ No newline at end of file +} + +UserData& UserData::operator=(const UserData& user) { + if (this != &user) { + _strName = user._strName; + _strDateOfBirth = user._strDateOfBirth; + _iAge = user._iAge; + _strAddress = user._strAddress; + _strPhoneNumber = user._strPhoneNumber; + _strEmail = user._strEmail; + _strUserName = user._strUserName; + _strPassword = user._strPassword; + _strRole = user._strRole; + } + return *this; +} diff --git a/UserData.h b/UserData.h index 5a462fc..07192f8 100644 --- a/UserData.h +++ b/UserData.h @@ -96,6 +96,13 @@ class UserData { * @return True if the two users are not equal, false otherwise */ bool operator!=(const UserData& user) const; + + /** + * @brief Overloads the = operator + * @details This function overloads the = operator to assign the value of a user to another. + * @return The user with the new value + */ + UserData& operator=(const UserData& user); }; #endif // CTDL_GK_USERDATA_CPP diff --git a/Users.cpp b/Users.cpp index 4afc841..3d69ee2 100644 --- a/Users.cpp +++ b/Users.cpp @@ -19,10 +19,10 @@ bool Users::addUser(const UserData& user) { return true; } -bool Users::removeUser(const UserData& user) { +bool Users::removeUser(const std::string& userName) { for (int i = 0; i < _list.getSize(); i++) { - if (_list[i].getUserName() == user.getUserName()) { - _list.remove(user); + if (_list[i].getUserName() == userName) { + _list.remove(_list[i]); return true; } } diff --git a/Users.h b/Users.h index 21ca319..38512ff 100644 --- a/Users.h +++ b/Users.h @@ -31,10 +31,10 @@ class Users { /** * @brief Remove user from list - * @param user User to remove + * @param userName Username of user to remove * @return True if success, false if failed */ - bool removeUser(const UserData& user); + bool removeUser(const std::string& userName); /** * @brief Edit user in list diff --git a/main.cpp b/main.cpp index f5ec1b9..5f4367f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -11,6 +12,7 @@ int g_maxLoginAttempts = 0; std::string g_userAccont; std::string g_userPassword; +UserAction g_user("Admin"); UserInterface g_ui; @@ -21,19 +23,25 @@ void loginAdmin(); void loginEmployee(); void adminMenuProcessing(char cOption); void employeeMenuProcessing(char cOption); +UserData updateMenu(std::string userName); UserData inputInformation(); +void displayUserInformation(const UserData user); +void displayAllUserInformation(const std::vector user); +bool isValidDateFormat(const std::string& date); +void changePassword(); + void adminMenu() { g_ui.cBorder = '*'; g_ui.printCentered("MENU", LIGHT_YELLOW, true, '-'); g_ui.print( { - "1. Them Employee", - "2. Xoa Employee", - "3. Tim Employee", - "4. Cap nhat Employee", - "5. Hien thi thong tin Employee", - "6. Tro ve" + "1. Add Employee", + "2. Delete Employee", + "3. Find Employee", + "4. Update Employee", + "5. Display Employee Information", + "6. Exit" }, LIGHT_YELLOW ); @@ -45,12 +53,12 @@ void adminMenu() { void employeeMenu() { g_ui.cBorder = '*'; - g_ui.printCentered("MENU EMPLOYEE", LIGHT_YELLOW, true, '-'); + g_ui.printCentered("EMPLOYEE MENU", LIGHT_YELLOW, true, '-'); g_ui.print( { - "1. Xem thong tin tai khoan", - "2. Doi password", - "3. Tro ve" + "1. View Account Information", + "2. Change Password", + "3. Exit" }, LIGHT_YELLOW ); @@ -62,14 +70,14 @@ void employeeMenu() { void loginMenu() { g_ui.cBorder = '*'; - g_ui.printTitle("DANG NHAP", LIGHT_GREEN, BRIGHT_WHITE, true); + g_ui.printTitle("LOGIN", LIGHT_GREEN, BRIGHT_WHITE, true); g_ui.printLineBreak(); g_ui.print( { - "CHON LOAI TAI KHOAN:", - "1. Admin", - "2. Employee", - "3. Thoat" + "SELECT ACCOUNT TYPE:", + "1. ADMIN", + "2. EMPLOYEE", + "3. EXIT" }, LIGHT_GREEN ); @@ -77,14 +85,16 @@ void loginMenu() { std::string StrOption = g_ui.input(">", BRIGHT_WHITE, false); g_ui.clearScreen(); if (StrOption == "1") { + g_user.setRole("Admin"); loginAdmin(); } else if (StrOption == "2") { + g_user.setRole("Employee"); loginEmployee(); } else if (StrOption == "3") { exit(0); } else { - g_ui.printTitle("KHONG HOP LE", LIGHT_YELLOW, LIGHT_RED, true); - g_ui.printCentered("Quay lai", LIGHT_PURPLE, false); + g_ui.printTitle("INVALID CHOICE", LIGHT_YELLOW, LIGHT_RED, true); + g_ui.printCentered("Return", LIGHT_PURPLE, false); g_ui.input(); g_ui.clearScreen(); loginMenu(); @@ -94,12 +104,12 @@ void loginMenu() { void loginAdmin() { g_ui.clearScreen(); g_ui.cBorder = '*'; - g_ui.printTitle("DANG NHAP ADMIN", LIGHT_YELLOW, LIGHT_CYAN, true); + g_ui.printTitle("ADMIN LOGIN", LIGHT_YELLOW, LIGHT_CYAN, true); g_ui.printLineBreak(); g_userAccont = g_ui.input("Username: ", LIGHT_PURPLE, false); g_userPassword = g_ui.input("Password (default: 123): ", LIGHT_PURPLE, true); - UserAction user("Admin"); - if (user.authenticateUser(g_userAccont, g_userPassword)) { + if (g_user.authenticateUser(g_userAccont, g_userPassword)) { + g_maxLoginAttempts = 0; g_ui.clearScreen(); adminMenu(); } else { @@ -121,12 +131,11 @@ void loginAdmin() { void loginEmployee() { g_ui.clearScreen(); g_ui.cBorder = '*'; - g_ui.printTitle("DANG NHAP EMPLOYEE", LIGHT_YELLOW, LIGHT_CYAN, true); + g_ui.printTitle("EMPLOYEE LOGIN", LIGHT_YELLOW, LIGHT_CYAN, true); g_ui.printLineBreak(); g_userAccont = g_ui.input("Username: ", LIGHT_PURPLE, false); g_userPassword = g_ui.input("Password (default: 123): ", LIGHT_PURPLE, true); - UserAction user("Employee"); - if (user.authenticateUser(g_userAccont, g_userPassword)) { + if (g_user.authenticateUser(g_userAccont, g_userPassword)) { g_ui.clearScreen(); employeeMenu(); } else { @@ -146,86 +155,231 @@ void loginEmployee() { } void adminMenuProcessing(char cOption) { - UserAction user("Admin"); g_ui.clearScreen(); + std::string username; switch (cOption) { case '1': - if(user.addUser(inputInformation())) - g_ui.printTitle("Thanh cong", LIGHT_GREEN, GREEN); + if(g_user.addUser(inputInformation())){ + g_ui.clearScreen(); + g_ui.printTitle("Successful", LIGHT_GREEN, GREEN); + } else - g_ui.printTitle("Khong thanh cong", LIGHT_YELLOW, YELLOW); + g_ui.printTitle("Unsuccessful", LIGHT_YELLOW, YELLOW); break; case '2': - if(user.deleteUser(g_ui.input("Nhap username:", LIGHT_CYAN, false))) - g_ui.printTitle("Thanh cong", LIGHT_GREEN, GREEN); + if(g_user.deleteUser(g_ui.input("Enter username:", LIGHT_CYAN, false))){ + g_ui.clearScreen(); + g_ui.printTitle("Successful", LIGHT_GREEN, GREEN); + } else - g_ui.printTitle("Khong thanh cong", LIGHT_YELLOW, YELLOW); + g_ui.printTitle("Unsuccessful", LIGHT_YELLOW, YELLOW); break; case '3': - user.findUser(g_ui.input("Nhap username:", LIGHT_CYAN, false)); // retrun userdata + displayUserInformation(g_user.findUser(g_ui.input("Enter username:", LIGHT_CYAN, false))); break; case '4': - // user.updateUserInformation(); + username = g_ui.input("Enter username:", LIGHT_CYAN, false); + if(g_user.updateUserInformation(username ,updateMenu(username))){ + g_ui.clearScreen(); + g_ui.printTitle("Successful", LIGHT_GREEN, GREEN); + } + else + g_ui.printTitle("Unsuccessful", LIGHT_YELLOW, YELLOW); break; case '5': - user.getAllUsersInformation(); // return vector + displayAllUserInformation(g_user.getAllUsersInformation()); break; case '6': loginMenu(); break; default: - g_ui.printTitle("KHONG HOP LE", LIGHT_YELLOW, LIGHT_RED, true); - g_ui.printCentered("Quay lai", LIGHT_PURPLE, false); + g_ui.printTitle("INVALID CHOICE", LIGHT_YELLOW, LIGHT_RED, true); break; } - g_ui.input(); + g_ui.input("Return"); g_ui.clearScreen(); adminMenu(); } void employeeMenuProcessing(char cOption) { - UserAction user("Employee"); g_ui.clearScreen(); switch (cOption) { case '1': g_ui.print( { - user.getUserInformation(g_userAccont) + g_user.getUserInformation(g_userAccont) }, LIGHT_YELLOW ); - g_ui.input(); break; case '2': - // user.updateUserInformation(g_userAccont, user.findUser(g_userAccont)); + changePassword(); break; case '3': loginMenu(); break; default: - g_ui.printTitle("KHONG HOP LE", LIGHT_YELLOW, LIGHT_RED, true); - g_ui.printCentered("Quay lai", LIGHT_PURPLE, false); - g_ui.input(); + g_ui.printTitle("INVALID CHOICE", LIGHT_YELLOW, LIGHT_RED, true); break; } + g_ui.input("Return"); g_ui.clearScreen(); employeeMenu(); } +UserData updateMenu(std::string userName){ + g_ui.print( + { + "1. Update Name", + "2. Update Date of Birth", + "3. Update Address", + "4. Update Phone Number", + "5. Update Email", + }, + LIGHT_YELLOW + ); + std::string strChange = g_ui.input("Enter number to change: "); + std::string strChangeStuff = g_ui.input("Enter new value: "); + UserData user = g_user.findUser(userName); + if (strChange == "1") { + user.setName(strChangeStuff); + return user; + } + else if (strChange == "2") { + user.setDateOfBirth(strChangeStuff); + return user; + } + else if (strChange == "3") { + user.setAddress(strChangeStuff); + return user; + } + else if(strChange == "4"){ + user.setPhoneNumber(strChangeStuff); + return user; + } + else if (strChange == "5") { + user.setEmail(strChangeStuff); + return user; + } + else{ + updateMenu(userName); + } + return user; +} + UserData inputInformation(){ + std::string strName; + std::string strBirth; - std::string strName = g_ui.input("name: "); - std::string strBirth = g_ui.input("birth: "); - std::string strAddress = g_ui.input("address: "); - std::string strPhoneNumber = g_ui.input("phone: "); - std::string strEmail = g_ui.input("email: "); - std::string strUsername = g_ui.input("UserName: "); + do { + strName = g_ui.input("Enter name: "); + strBirth = g_ui.input("Enter Date of birth(dd/mm/yy): "); + if (!isValidDateFormat(strBirth)) { + g_ui.clearScreen(); + g_ui.printTitle("Invalid date of birth!", LIGHT_YELLOW, LIGHT_RED, true); + g_ui.input("Retry"); + g_ui.clearScreen(); + } + } while (!isValidDateFormat(strBirth)); + + std::string strAddress = g_ui.input("Enter Address: "); + std::string strPhoneNumber = g_ui.input("Enter phone: "); + std::string strEmail = g_ui.input("Enter email: "); + std::string strUsername = g_ui.input("Enter UserName: "); std::string strPass = "111111"; return UserData(strName, strBirth, strAddress, strPhoneNumber, strEmail, strUsername, strPass, "Employee"); } +void displayUserInformation(const UserData user){ + g_ui.print( + { + user.getName(), + user.getDateOfBirth(), + user.getPassword(), + user.getPhoneNumber(), + user.getEmail() + }, + LIGHT_PURPLE + ); +} + +void displayAllUserInformation(const std::vector user){ + //g_ui.print(user, LIGHT_CYAN, true, '\n'); + for(auto& row : user){ + g_ui.printCentered(row , BLUE); + g_ui.printLineBreak(); + } +} + +void changePassword(){ + std::string strNewPass1 = g_ui.input("Enter a new password: ",LIGHT_PURPLE, true); + std::string strNewPass2 = g_ui.input("Confirm the new password again: ",LIGHT_PURPLE, true); + + if (g_user.authenticateUser(g_userAccont, g_ui.input("Enter current password: ",LIGHT_CYAN, true))) { + g_maxLoginAttempts = 0; + g_ui.clearScreen(); + if(strNewPass1 == strNewPass2) { + g_user.setRole("Admin"); + UserData user = g_user.findUser(g_userAccont); + user.setPassword(strNewPass1); + if(g_user.updateUserInformation(g_userAccont,user)){ + g_ui.printTitle("Successful", LIGHT_GREEN, GREEN); + g_ui.clearScreen(); + loginMenu(); + } + else { + g_ui.printTitle("Unsuccessful", RED, RED); + employeeMenu(); + + } + } + else{ + g_ui.clearScreen(); + g_ui.printTitle("The new passwords do not match. Please try again.", LIGHT_CYAN, LIGHT_RED); + } + } else { + if (g_maxLoginAttempts == 2) { + g_maxLoginAttempts = 0; + g_ui.clearScreen(); + g_ui.printTitle("Access is blocked!", LIGHT_RED, LIGHT_RED); + g_ui.input(); + exit(0); + } + g_ui.clearScreen(); + g_ui.printTitle("Incorrect curent password", LIGHT_CYAN, LIGHT_RED); + g_maxLoginAttempts++; + g_ui.input(); + } +} + +bool isValidDateFormat(const std::string& date) { + if (date.length() != 10) return false; + + if (date[2] != '/' || date[5] != '/') return false; + + int iDay, iMonth, iYear; + sscanf(date.c_str(), "%d/%d/%d", &iDay, &iMonth, &iYear); + + if (iYear < 1900 || iYear > 2100) return false; + + if (iMonth < 1 || iMonth > 12) return false; + + if (iMonth == 2) { + if (iYear % 4 == 0 && (iYear % 100 != 0 || iYear % 400 == 0)) { + if (iDay < 1 || iDay > 29) return false; + } else { + if (iDay < 1 || iDay > 28) return false; + } + } else if (iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11) { + if (iDay < 1 || iDay > 30) return false; + } else { + if (iDay < 1 || iDay > 31) return false; + } + return true; +} + void processing() { g_ui.cBorder = '*'; loginMenu();