users.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <?php
  2. header("Access-Control-Allow-Origin: *");
  3. header("Content-Type: application/json; charset=UTF-8");
  4. header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
  5. header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
  6. if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  7. exit(0);
  8. }
  9. require_once __DIR__ . '/../config/database.php';
  10. require_once __DIR__ . '/../models/User.php';
  11. require_once __DIR__ . '/../middleware/auth.php';
  12. // Start session for authentication
  13. session_start();
  14. $database = new Database();
  15. $db = $database->getConnection();
  16. $user = new User($db);
  17. $auth = new AuthMiddleware($db);
  18. // Authenticate user
  19. $current_user = $auth->authenticate();
  20. if (!$current_user) {
  21. $auth->sendUnauthorizedResponse();
  22. }
  23. $request_method = $_SERVER['REQUEST_METHOD'];
  24. switch($request_method) {
  25. case 'GET':
  26. if(isset($_GET['id'])) {
  27. $user_id = $_GET['id'];
  28. // Check authorization: Admin can access any user, users can only access their own profile
  29. if (!$auth->canAccess($current_user, null, $user_id)) {
  30. $auth->sendForbiddenResponse();
  31. }
  32. $user->id = $user_id;
  33. $user->readOne();
  34. if($user->username != null) {
  35. // Remove sensitive data for non-admin users accessing their own profile
  36. $user_arr = array(
  37. "id" => $user->id,
  38. "username" => $user->username,
  39. "email" => $user->email,
  40. "first_name" => $user->first_name,
  41. "last_name" => $user->last_name,
  42. "role" => $user->role,
  43. "is_active" => $user->is_active,
  44. "last_login" => $user->last_login,
  45. "created_at" => $user->created_at,
  46. "updated_at" => $user->updated_at
  47. );
  48. // Add admin-only data if current user is admin
  49. if ($auth->isAdmin($current_user)) {
  50. $user_arr["role_badge"] = $user->getRoleBadge();
  51. $user_arr["status_badge"] = $user->getStatusBadge();
  52. }
  53. http_response_code(200);
  54. echo json_encode($user_arr);
  55. } else {
  56. http_response_code(404);
  57. echo json_encode(array("message" => "User not found."));
  58. }
  59. } else {
  60. // List all users - admin only
  61. if (!$auth->isAdmin($current_user)) {
  62. $auth->sendForbiddenResponse();
  63. }
  64. $stmt = $user->read();
  65. $num = $stmt->rowCount();
  66. if($num > 0) {
  67. $users_arr = array();
  68. $users_arr["records"] = array();
  69. while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  70. extract($row);
  71. $user_item = array(
  72. "id" => $id,
  73. "username" => $username,
  74. "email" => $email,
  75. "first_name" => $first_name,
  76. "last_name" => $last_name,
  77. "role" => $role,
  78. "is_active" => $is_active,
  79. "last_login" => $last_login,
  80. "created_at" => $created_at,
  81. "updated_at" => $updated_at,
  82. "role_badge" => getRoleBadge($role),
  83. "status_badge" => getStatusBadge($is_active)
  84. );
  85. array_push($users_arr["records"], $user_item);
  86. }
  87. http_response_code(200);
  88. echo json_encode($users_arr);
  89. } else {
  90. http_response_code(200);
  91. echo json_encode(array("records" => array()));
  92. }
  93. }
  94. break;
  95. case 'POST':
  96. // Only admins can create users
  97. if (!$auth->isAdmin($current_user)) {
  98. $auth->sendForbiddenResponse();
  99. }
  100. $data = json_decode(file_get_contents("php://input"));
  101. if(!empty($data->username) && !empty($data->email) && !empty($data->first_name) && !empty($data->last_name) && !empty($data->password)) {
  102. // Check if username or email already exists
  103. $existing_user = $user->findByEmail($data->email);
  104. if($existing_user) {
  105. http_response_code(409);
  106. echo json_encode(array("message" => "Email already exists"));
  107. break;
  108. }
  109. $existing_user = $user->findByUsername($data->username);
  110. if($existing_user) {
  111. http_response_code(409);
  112. echo json_encode(array("message" => "Username already exists"));
  113. break;
  114. }
  115. $user->username = $data->username;
  116. $user->email = $data->email;
  117. $user->password_hash = $data->password;
  118. $user->first_name = $data->first_name;
  119. $user->last_name = $data->last_name;
  120. $user->role = $data->role ?? 'user';
  121. $user->is_active = $data->is_active ?? true;
  122. if($user->create()) {
  123. http_response_code(201);
  124. echo json_encode(array("message" => "User was created."));
  125. } else {
  126. http_response_code(503);
  127. echo json_encode(array("message" => "Unable to create user."));
  128. }
  129. } else {
  130. http_response_code(400);
  131. echo json_encode(array("message" => "Unable to create user. Data is incomplete."));
  132. }
  133. break;
  134. case 'PUT':
  135. $data = json_decode(file_get_contents("php://input"));
  136. if(!empty($data->id) && !empty($data->username) && !empty($data->email) && !empty($data->first_name) && !empty($data->last_name)) {
  137. $user_id = $data->id;
  138. // Check authorization: Admin can update any user, users can only update their own profile
  139. if (!$auth->canAccess($current_user, null, $user_id)) {
  140. $auth->sendForbiddenResponse();
  141. }
  142. $user->id = $user_id;
  143. $user->username = $data->username;
  144. $user->email = $data->email;
  145. $user->first_name = $data->first_name;
  146. $user->last_name = $data->last_name;
  147. // Only admins can change role and is_active status
  148. if ($auth->isAdmin($current_user)) {
  149. $user->role = $data->role ?? 'user';
  150. $user->is_active = $data->is_active ?? true;
  151. } else {
  152. // For regular users, preserve existing role and active status
  153. $existing_user = new User($db);
  154. $existing_user->id = $user_id;
  155. $existing_user->readOne();
  156. $user->role = $existing_user->role;
  157. $user->is_active = $existing_user->is_active;
  158. }
  159. // Update password if provided
  160. $update_password = !empty($data->password);
  161. if($update_password) {
  162. $user->password_hash = $data->password;
  163. }
  164. if($user->update($update_password)) {
  165. http_response_code(200);
  166. echo json_encode(array("message" => "User was updated."));
  167. } else {
  168. http_response_code(503);
  169. echo json_encode(array("message" => "Unable to update user."));
  170. }
  171. } else {
  172. http_response_code(400);
  173. echo json_encode(array("message" => "Unable to update user. Data is incomplete."));
  174. }
  175. break;
  176. case 'DELETE':
  177. // Only admins can delete users
  178. if (!$auth->isAdmin($current_user)) {
  179. $auth->sendForbiddenResponse();
  180. }
  181. if(isset($_GET['id'])) {
  182. $user_id = $_GET['id'];
  183. // Prevent admin from deleting themselves
  184. if ($user_id == $current_user['id']) {
  185. http_response_code(400);
  186. echo json_encode(array("message" => "Cannot delete your own account."));
  187. break;
  188. }
  189. $user->id = $user_id;
  190. if($user->delete()) {
  191. http_response_code(200);
  192. echo json_encode(array("message" => "User was deleted."));
  193. } else {
  194. http_response_code(503);
  195. echo json_encode(array("message" => "Unable to delete user."));
  196. }
  197. } else {
  198. http_response_code(400);
  199. echo json_encode(array("message" => "Unable to delete user. ID is missing."));
  200. }
  201. break;
  202. default:
  203. http_response_code(405);
  204. echo json_encode(array("message" => "Method not allowed."));
  205. break;
  206. }
  207. // Helper functions
  208. function getRoleBadge($role) {
  209. $badges = array(
  210. 'admin' => '<span style="background-color: #dc3545; color: white; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500;">Admin</span>',
  211. 'manager' => '<span style="background-color: #28a745; color: white; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500;">Manager</span>',
  212. 'user' => '<span style="background-color: #6c757d; color: white; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500;">User</span>'
  213. );
  214. return $badges[$role] ?? $badges['user'];
  215. }
  216. function getStatusBadge($is_active) {
  217. if($is_active) {
  218. return '<span style="background-color: #28a745; color: white; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500;">Active</span>';
  219. } else {
  220. return '<span style="background-color: #6c757d; color: white; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500;">Inactive</span>';
  221. }
  222. }
  223. ?>