Banking_System_Server  1.0.0
Qt-based banking app for user/admin account management, transactions, secure server communication via PostgreSQL/Supabase.
CreateNewUserRequest.h
Go to the documentation of this file.
1 
8 #ifndef CREATENEWUSERREQUEST_H
9 #define CREATENEWUSERREQUEST_H
10 
11 #include "Request.h"
12 #include "db.h"
13 #include <QRandomGenerator>
14 
23 {
24 private:
25  DB::DatabaseManager* dbManager = nullptr;
26 
27 public:
33  CreateNewUserRequest() : dbManager(DB::DatabaseManager::createInstance())
34  {
35  // log to database log table
36  }
37 
50  QJsonObject execute(const QJsonObject& jsonObj, QMutex& m) override
51  {
52  QMutexLocker locker(&m); // Lock the mutex for the duration of this function
53 
54  QString email{};
55  QString password{};
56  QString first_name{};
57  QString last_name{};
58  QString new_email{};
59  QString new_password{};
60  QString role{};
61  double initial_balance{};
62 
63  QJsonObject response;
64  QJsonObject data;
65 
66  response.insert("Response", 8);
67 
68  // Extract the data array
69  if (jsonObj.contains("Data"))
70  {
71  QJsonObject dataObj = jsonObj["Data"].toObject();
72 
73  if (dataObj.contains("email"))
74  {
75  email = dataObj.value("email").toString();
76  }
77 
78  if (dataObj.contains("newUser"))
79  {
80  QJsonObject newUserObj = dataObj["newUser"].toObject();
81 
82  if (newUserObj.contains("first_name"))
83  {
84  first_name = newUserObj.value("first_name").toString();
85  }
86  if (newUserObj.contains("last_name"))
87  {
88  last_name = newUserObj.value("last_name").toString();
89  }
90  if (newUserObj.contains("email"))
91  {
92  new_email = newUserObj.value("email").toString();
93  }
94  if (newUserObj.contains("password"))
95  {
96  new_password = newUserObj.value("password").toString();
97  }
98  if (newUserObj.contains("role"))
99  {
100  role = newUserObj.value("role").toString();
101  }
102  if (newUserObj.contains("initial_balance"))
103  {
104  initial_balance = newUserObj.value("initial_balance").toDouble();
105  }
106  }
107  }
108  else
109  {
110  qCritical() << "Data not found";
111  }
112 
113  do
114  {
115  if (!isDBConnectionValid(dbManager))
116  {
117  return CreateDBConnectionError(response, data);
118  }
119 
120  qDebug() << "First Name: " << first_name;
121  qDebug() << "Last Name: " << last_name;
122  qDebug() << "Email: " << new_email;
123  qDebug() << "Password: " << new_password;
124  qDebug() << "Role: " << role;
125  qDebug() << "Initial Balance: " << initial_balance;
126 
127  // Check if the user is an admin
128  DB::DbResult result = dbManager->select("role")->table("users")->where("email =", email)->exec();
129 
130  if (result.isEmpty())
131  {
132  return CreateErrorResponse(response, data, "you are not registered user!");
133  }
134 
135  //QJsonObject obj = result.first();
136  QJsonObject obj = result.first();
137 
138  //if (obj.value("role").toString() != "admin")
139  if (result.first().value("role").toString() != "admin")
140  {
141  return CreateErrorResponse(response, data,
142  "Unauthorized, Cannot create new user. User is not an admin");
143  }
144 
145  if (new_email.isEmpty() || new_password.isEmpty() || first_name.isEmpty() || last_name.isEmpty() ||
146  role.isEmpty())
147  {
148  return CreateErrorResponse(response, data, "Missing required fields");
149  }
150 
151  // invalid role
152  if (role != "admin" && role != "user")
153  {
154  return CreateErrorResponse(response, data, "Invalid role");
155  }
156 
157  // admin can't have account and initial balance
158  if (role == "admin" && initial_balance != 0)
159  {
160  return CreateErrorResponse(response, data, "Admin can't have account and initial balance");
161  }
162 
163  // Check if there is a user with the same email
164  result = dbManager->select("*")->table("users")->where("email =", new_email)->exec();
165 
166  if (!result.isEmpty())
167  {
168  return CreateErrorResponse(response, data, "User already exists");
169  }
170 
171  // Create the new user
172  bool success = dbManager->insert("users", {{"email", new_email},
173  {"password", new_password},
174  {"first_name", first_name},
175  {"last_name", last_name},
176  {"role", role}});
177  if (!success)
178  {
179  return CreateErrorResponse(response, data, "Failed to create new user");
180  }
181 
182  if (role == "admin" && initial_balance == 0)
183  {
184  qDebug() << "New admin created successfully";
185 
186  data.insert("status", int(true));
187  data.insert("message", "New admin created successfully");
188 
189  response.insert("Data", data);
190 
191  break;
192  }
193 
194  // Get the user id from the last insert operation
195  result = dbManager->select("id")->table("users")->where("email =", new_email)->exec();
196  QVariant lastId = result.first().value("id");
198 
199  // Create the account for the new user and randomly generate an account number of 6 digits
200  // make sure the account number is unique
201  int account_number = 0;
202 
203  // not the best way to generate unique account number but it's ok for now
204  do
205  {
206  account_number = QRandomGenerator::global()->bounded(100000, 999999);
207  result = dbManager->select("*")->table("accounts")->where("account_number =", account_number)->exec();
208  } while (!result.isEmpty());
209 
210  success = dbManager->insert(
211  "accounts",
212  {{"account_number", account_number}, {"user_id", lastId.toInt()}, {"balance", initial_balance}});
213 
214  if (!success)
215  {
216  return CreateErrorResponse(response, data, "Failed to create account for the new user");
217  }
218 
219  data.insert("status", int(true));
220  data.insert("message", "New user created successfully");
221 
222  response.insert("Data", data);
223 
224  } while (false);
225 
226  // Convert response to JSON
227  QJsonDocument responseDoc(response);
228  QByteArray responseData = responseDoc.toJson();
229 
230  // Send response
231  qDebug().noquote() << "<-- CreateNewUser::Response :\n" << responseDoc.toJson(QJsonDocument::Indented);
232 
233  return response;
234  }
235 };
236 
237 #endif // CREATENEWUSERREQUEST_H
This file contains the declaration of the Request class, which is an abstract base class for handling...
The CreateNewUserRequest class handles the creation of new users.
Definition: CreateNewUserRequest.h:23
QJsonObject execute(const QJsonObject &jsonObj, QMutex &m) override
Executes the request to create a new user.
Definition: CreateNewUserRequest.h:50
CreateNewUserRequest()
Constructor for the CreateNewUserRequest class.
Definition: CreateNewUserRequest.h:33
Manages database connections and SQL operations.
Definition: db.h:80
DatabaseManager * table(const QString &value)
Sets the table for the query.
Definition: db.cpp:115
DatabaseManager * where(const QString &value, const QVariant &val=QVariant())
Adds a WHERE clause to the query.
Definition: db.cpp:121
DbResult exec()
Executes the built query.
Definition: db.cpp:266
DatabaseManager * select(const QString &value)
Selects columns for the query.
Definition: db.cpp:107
bool insert(const QString &table, const QVariantMap &data)
Inserts data into a specified table.
Definition: db.cpp:327
The DbResult class represents a result set returned from a database query.
Definition: dbresult.h:24
QJsonObject first() const
Retrieves the first item in the result set.
Definition: dbresult.cpp:25
bool isEmpty() const
Checks if the result set is empty.
Definition: dbresult.cpp:20
The Request class is an abstract base class for handling different types of requests.
Definition: Request.h:25
QJsonObject CreateErrorResponse(QJsonObject &response, QJsonObject &dataObj, QString message)
Creates a generic error JSON response.
Definition: Request.h:90
QJsonObject CreateDBConnectionError(QJsonObject &response, QJsonObject &dataObj)
Creates a JSON response indicating a database connection error.
Definition: Request.h:65
bool isDBConnectionValid(DB::DatabaseManager *dbManager)
Checks if the database connection is valid.
Definition: Request.h:36
Database management classes for handling database connections and operations.