From 5f68d7fe5b5827b7ddc74146bce0624e03292318 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 5 Nov 2025 22:26:48 +0000 Subject: [PATCH] App creation completed --- add-asset.php | 96 +++++------ add-user.php | 89 +++++----- auth-helpers.php | 30 ++++ db/config.php | 43 ++++- .../003_create_permissions_table.sql | 40 +++++ delete-asset.php | 6 +- delete-user.php | 30 ++-- edit-asset.php | 95 +++++------ edit-user.php | 153 ++++++++--------- index.php | 126 +++++--------- settings.php | 160 ++++++++++++++++++ templates/sidebar.php | 45 +++++ users.php | 138 +++++++-------- 13 files changed, 621 insertions(+), 430 deletions(-) create mode 100644 auth-helpers.php create mode 100644 db/migrations/003_create_permissions_table.sql create mode 100644 settings.php create mode 100644 templates/sidebar.php diff --git a/add-asset.php b/add-asset.php index 0e8f787..cdc5e1b 100644 --- a/add-asset.php +++ b/add-asset.php @@ -1,27 +1,40 @@ prepare($sql); - $stmt->execute([$name, $asset_tag, $status, $location, $manufacturer, $model, $purchase_date]); + $stmt->execute($data); header("Location: index.php?success=asset_added"); exit; @@ -49,48 +62,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- +
@@ -107,16 +79,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+
+ +
+
+
+ +
+
+
+ +
+
+
+ Cancel @@ -158,4 +144,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { feather.replace(); - + \ No newline at end of file diff --git a/add-user.php b/add-user.php index 418eea4..d0e1365 100644 --- a/add-user.php +++ b/add-user.php @@ -1,10 +1,12 @@ prepare("SELECT id FROM users WHERE email = ?"); + $stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?'); $stmt->execute([$email]); if ($stmt->fetch()) { - $error_message = 'Email already exists.'; + $error_message = 'A user with this email address already exists.'; } else { $hashed_password = password_hash($password, PASSWORD_DEFAULT); - $sql = "INSERT INTO users (name, email, password, role) VALUES (?, ?, ?, ?)"; $stmt = $pdo->prepare($sql); $stmt->execute([$name, $email, $hashed_password, $role]); @@ -49,6 +50,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { Add New User - IC-Inventory + @@ -59,33 +61,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- +

Add New User

-
+
+ +
@@ -94,26 +77,30 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { -
- - +
+
+ + +
+
+ + +
-
- - -
-
- - -
-
- - +
+
+ + +
+
+ + +
@@ -125,6 +112,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { - + - + \ No newline at end of file diff --git a/auth-helpers.php b/auth-helpers.php new file mode 100644 index 0000000..45e2bd4 --- /dev/null +++ b/auth-helpers.php @@ -0,0 +1,30 @@ +query('SELECT * FROM role_permissions'); + $all_permissions = $stmt->fetchAll(PDO::FETCH_ASSOC); + $permissions = []; + foreach ($all_permissions as $p) { + $permissions[$p['role']][$p['resource']][$p['action']] = $p['fields'] ?? '*'; + } + } catch (PDOException $e) { + // Handle database errors, maybe return false or log the error + return false; + } + } + + if (isset($permissions[$role][$resource][$action])) { + if (in_array($action, ['read', 'update'])) { + return $permissions[$role][$resource][$action]; + } + return true; + } + + return false; +} diff --git a/db/config.php b/db/config.php index f12ebaf..2714b40 100644 --- a/db/config.php +++ b/db/config.php @@ -6,12 +6,39 @@ define('DB_USER', 'app_31009'); define('DB_PASS', '2c66b530-2a65-423a-a106-6760b49ad1a2'); function db() { - static $pdo; - if (!$pdo) { - $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ]); - } - return $pdo; + static $pdo; + if ($pdo) { + return $pdo; + } + + try { + $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ]); + } catch (PDOException $e) { + // If the database doesn't exist, we can't run migrations. + // The error will be caught and displayed on the page. + throw $e; + } + + + // Migration logic + $pdo->exec('CREATE TABLE IF NOT EXISTS migrations (migration VARCHAR(255) PRIMARY KEY)'); + $ran_migrations = $pdo->query('SELECT migration FROM migrations')->fetchAll(PDO::FETCH_COLUMN); + + $migration_files = glob(__DIR__ . '/migrations/*.sql'); + sort($migration_files); + + foreach ($migration_files as $file) { + $migration_name = basename($file); + if (!in_array($migration_name, $ran_migrations)) { + $sql = file_get_contents($file); + $pdo->exec($sql); + $stmt = $pdo->prepare('INSERT INTO migrations (migration) VALUES (?)'); + $stmt->execute([$migration_name]); + } + } + + return $pdo; } diff --git a/db/migrations/003_create_permissions_table.sql b/db/migrations/003_create_permissions_table.sql new file mode 100644 index 0000000..99ec3f2 --- /dev/null +++ b/db/migrations/003_create_permissions_table.sql @@ -0,0 +1,40 @@ +CREATE TABLE IF NOT EXISTS `role_permissions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `role` varchar(255) NOT NULL, + `resource` varchar(255) NOT NULL, + `action` varchar(255) NOT NULL, + `fields` text DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `role_resource_action` (`role`,`resource`,`action`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- Default Permissions + +-- Admin: Can do everything +INSERT INTO `role_permissions` (`role`, `resource`, `action`, `fields`) VALUES +('Admin', 'asset', 'create', '*'), +('Admin', 'asset', 'read', '*'), +('Admin', 'asset', 'update', '*'), +('Admin', 'asset', 'delete', '*'), +('Admin', 'user', 'create', '*'), +('Admin', 'user', 'read', '*'), +('Admin', 'user', 'update', '*'), +('Admin', 'user', 'delete', '*'); + +-- Asset Manager: Can manage assets +INSERT INTO `role_permissions` (`role`, `resource`, `action`, `fields`) VALUES +('Asset Manager', 'asset', 'create', '*'), +('Asset Manager', 'asset', 'read', '*'), +('Asset Manager', 'asset', 'update', '*'), +('Asset Manager', 'asset', 'delete', '*'); + +-- IT Technician: Can manage assets +INSERT INTO `role_permissions` (`role`, `resource`, `action`, `fields`) VALUES +('IT Technician', 'asset', 'create', '*'), +('IT Technician', 'asset', 'read', '*'), +('IT Technician', 'asset', 'update', '*'), +('IT Technician', 'asset', 'delete', '*'); + +-- Employee: Can only read some asset fields +INSERT INTO `role_permissions` (`role`, `resource`, `action`, `fields`) VALUES +('Employee', 'asset', 'read', 'name,asset_tag,status,location,manufacturer,model'); diff --git a/delete-asset.php b/delete-asset.php index eb49404..11fc3d2 100644 --- a/delete-asset.php +++ b/delete-asset.php @@ -1,10 +1,6 @@ prepare("DELETE FROM users WHERE id = ?"); + $stmt = $pdo->prepare('DELETE FROM users WHERE id = ?'); $stmt->execute([$user_id]); header("Location: users.php?success=user_deleted"); exit; } catch (PDOException $e) { + // In a real app, log this error. header("Location: users.php?error=db_error"); exit; -} -?> +} \ No newline at end of file diff --git a/edit-asset.php b/edit-asset.php index 049744e..3da9aff 100644 --- a/edit-asset.php +++ b/edit-asset.php @@ -1,6 +1,15 @@ prepare($sql); - $stmt->execute([$name, $asset_tag, $status, $location, $manufacturer, $model, $purchase_date, $asset_id]); + $stmt->execute($data); header("Location: index.php?success=asset_updated"); exit; @@ -71,48 +83,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- +
@@ -130,16 +101,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+
+ +
+
+
+ +
+
+
+ +
+
+
+ Cancel @@ -182,4 +167,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { feather.replace(); - + \ No newline at end of file diff --git a/edit-user.php b/edit-user.php index f53d2b4..37c1946 100644 --- a/edit-user.php +++ b/edit-user.php @@ -1,29 +1,32 @@ prepare("SELECT id, name, email, role FROM users WHERE id = ?"); + $stmt = $pdo->prepare('SELECT id, name, email, role FROM users WHERE id = ?'); $stmt->execute([$user_id]); - $user = $stmt->fetch(PDO::FETCH_ASSOC); + $user = $stmt->fetch(); if (!$user) { - header("Location: users.php?error=not_found"); + header('Location: users.php'); exit; } } catch (PDOException $e) { @@ -31,35 +34,36 @@ try { } if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $name = $_POST['name'] ?? ''; - $email = $_POST['email'] ?? ''; - $role = $_POST['role'] ?? 'Employee'; - $password = $_POST['password'] ?? ''; + $data = []; + $set_parts = []; - if (empty($name) || empty($email)) { - $error_message = 'Name and Email are required.'; - } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { - $error_message = 'Invalid email format.'; + foreach ($allowed_fields as $field) { + if (isset($_POST[$field])) { + $data[] = $_POST[$field]; + $set_parts[] = "$field = ?"; + } + } + $data[] = $user_id; + + if (empty($set_parts)) { + $error_message = 'No data submitted.'; } else { try { $pdo = db(); - + // Check if email already exists for another user - $stmt = $pdo->prepare("SELECT id FROM users WHERE email = ? AND id != ?"); - $stmt->execute([$email, $user_id]); - if ($stmt->fetch()) { - $error_message = 'Email already exists for another user.'; - } else { - if (!empty($password)) { - $hashed_password = password_hash($password, PASSWORD_DEFAULT); - $sql = "UPDATE users SET name = ?, email = ?, role = ?, password = ? WHERE id = ?"; - $stmt = $pdo->prepare($sql); - $stmt->execute([$name, $email, $role, $hashed_password, $user_id]); - } else { - $sql = "UPDATE users SET name = ?, email = ?, role = ? WHERE id = ?"; - $stmt = $pdo->prepare($sql); - $stmt->execute([$name, $email, $role, $user_id]); + if (in_array('email', $allowed_fields)) { + $stmt = $pdo->prepare('SELECT id FROM users WHERE email = ? AND id != ?'); + $stmt->execute([$_POST['email'], $user_id]); + if ($stmt->fetch()) { + $error_message = 'A user with this email address already exists.'; } + } + + if (!$error_message) { + $sql = sprintf("UPDATE users SET %s WHERE id = ?", implode(', ', $set_parts)); + $stmt = $pdo->prepare($sql); + $stmt->execute($data); header("Location: users.php?success=user_updated"); exit; @@ -76,6 +80,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { Edit User - IC-Inventory + @@ -86,33 +91,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- +

Edit User

-
+
+ +
@@ -121,28 +107,33 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { - -
- - + +
+ +
+ + +
+ + +
+ + +
+
-
- - -
-
- - -
Leave blank to keep the current password.
-
-
- - +
+ +
+ + +
+
@@ -155,6 +146,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { - + - + \ No newline at end of file diff --git a/index.php b/index.php index 3780a84..d43345b 100644 --- a/index.php +++ b/index.php @@ -1,28 +1,34 @@ query("SHOW TABLES LIKE 'assets'"); - if ($result->rowCount() == 0) { - $sql = file_get_contents('db/migrations/001_create_assets_table.sql'); - $pdo->exec($sql); - } - - $stmt = $pdo->query('SELECT * FROM assets ORDER BY created_at DESC'); + $stmt = $pdo->query("SELECT $select_fields FROM assets ORDER BY created_at DESC"); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { - // In a real app, you'd log this error and show a user-friendly message. - // For this initial setup, we'll just display the error. return ['error' => 'Database error: ' . $e->getMessage()]; } } -$assets = get_assets(); +$assets = get_assets($allowed_fields); function getStatusClass($status) { switch (strtolower($status)) { @@ -44,13 +50,6 @@ function getStatusClass($status) { IC-Inventory - - - - - - - @@ -61,54 +60,15 @@ function getStatusClass($status) {
- +

Asset Dashboard

- Add New Asset + + Add New Asset +
@@ -133,38 +93,40 @@ function getStatusClass($status) {

No assets found.

-

Get started by adding your first company asset.

- Add Asset + +

Get started by adding your first company asset.

+ Add Asset +
- - - - - - - + + + - - - - - - - + + + diff --git a/settings.php b/settings.php new file mode 100644 index 0000000..48ac6ab --- /dev/null +++ b/settings.php @@ -0,0 +1,160 @@ +beginTransaction(); + + // Clear existing permissions + $pdo->exec('TRUNCATE TABLE role_permissions'); + + $stmt = $pdo->prepare('INSERT INTO role_permissions (role, resource, action, fields) VALUES (?, ?, ?, ?)'); + + $permissions = $_POST['permissions'] ?? []; + + foreach ($roles as $role) { + foreach ($resources as $resource) { + foreach ($actions as $action) { + if (!empty($permissions[$role][$resource][$action]['enabled'])) { + $fields = $permissions[$role][$resource][$action]['fields'] ?? null; + if (in_array($action, ['read', 'update']) && empty($fields)) { + $fields = '*'; // Default to all fields if not specified + } + $stmt->execute([$role, $resource, $action, $fields]); + } + } + } + } + + $pdo->commit(); + $success_message = 'Permissions updated successfully!'; + + } catch (PDOException $e) { + if ($pdo->inTransaction()) { + $pdo->rollBack(); + } + $error_message = 'Database error: ' . $e->getMessage(); + } +} + + +function get_permissions() { + try { + $pdo = db(); + $stmt = $pdo->query('SELECT * FROM role_permissions ORDER BY role, resource, action'); + return $stmt->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + return ['error' => 'Database error: ' . $e->getMessage()]; + } +} + +$permissions_from_db = get_permissions(); + +// Group permissions by role and resource for easier display +$grouped_permissions = []; +foreach ($permissions_from_db as $p) { + $grouped_permissions[$p['role']][$p['resource']][$p['action']] = $p['fields']; +} + +?> + + + + + + Settings - Role Permissions - IC-Inventory + + + + + + + + + + +
+ + +
+
+

Settings - Role Permissions

+
+ +
+
+ +
+ +
+ + +
+ + + +
+
NameAsset TagStatusLocationManufacturerModelPurchase Date Actions
+ + + + + + - Edit - - Delete + + Edit + + + Delete
+ + + + + + + + + + + + + $resource): ?> + + + + + + + + + + + + + +
RoleResourceCreateRead (Fields)Update (Fields)Delete
+
+ > +
+ + + +
+
+ + +
+
+
+ + + + + + \ No newline at end of file diff --git a/templates/sidebar.php b/templates/sidebar.php new file mode 100644 index 0000000..acc665e --- /dev/null +++ b/templates/sidebar.php @@ -0,0 +1,45 @@ + + \ No newline at end of file diff --git a/users.php b/users.php index 1162c03..1dc0d4b 100644 --- a/users.php +++ b/users.php @@ -1,30 +1,40 @@ query("SHOW TABLES LIKE 'users'"); - if ($result->rowCount() == 0) { - $sql = file_get_contents('db/migrations/002_create_users_table.sql'); - $pdo->exec($sql); - } - - $stmt = $pdo->query('SELECT id, name, email, role, created_at FROM users ORDER BY created_at DESC'); + $stmt = $pdo->query("SELECT $select_fields FROM users ORDER BY created_at DESC"); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { return ['error' => 'Database error: ' . $e->getMessage()]; } } -$users = get_users(); +$users = get_users($allowed_fields); + ?> @@ -32,7 +42,7 @@ $users = get_users(); User Management - IC-Inventory - + @@ -43,70 +53,32 @@ $users = get_users();
- +

User Management

+ +
User successfully added!
+ +
User successfully updated!
+ +
User successfully deleted!
+ +
You cannot delete your own account.
+ +
- -
User successfully added!
- -
User successfully updated!
- -
User successfully deleted!
- -
The default admin user cannot be deleted.
-
@@ -114,31 +86,35 @@ $users = get_users();

No users found.

-

Get started by adding your first user.

- Add User + +

Get started by adding your first user.

+ Add User +
- +
- - - - + + + - - - - + + + @@ -156,4 +132,4 @@ $users = get_users(); feather.replace(); - + \ No newline at end of file
NameEmailRoleCreated At Actions
- Edit - Delete + + Edit + + + Delete +