Sindbad~EG File Manager
<?php
/**
* Authentication Class
* Handles user authentication and authorization
*/
class Auth {
private $db;
private $auditLog;
public function __construct() {
$this->db = Database::getInstance()->getConnection();
$this->auditLog = new AuditLog();
}
/**
* Login user
*/
public function login($username, $password) {
try {
$stmt = $this->db->prepare("
SELECT id, username, email, password_hash, full_name, phone,
profile_photo, is_superuser, access_level, area_id,
district_id, assembly_id, is_active
FROM users
WHERE (username = :username OR email = :email) AND is_active = 1
");
$stmt->execute(['username' => $username, 'email' => $username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password_hash'])) {
// Update last login
$updateStmt = $this->db->prepare("UPDATE users SET last_login = NOW() WHERE id = :id");
$updateStmt->execute(['id' => $user['id']]);
// Set session variables
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['email'] = $user['email'];
$_SESSION['full_name'] = $user['full_name'];
$_SESSION['is_superuser'] = (bool)$user['is_superuser'];
$_SESSION['access_level'] = $user['access_level'];
$_SESSION['area_id'] = $user['area_id'];
$_SESSION['district_id'] = $user['district_id'];
$_SESSION['assembly_id'] = $user['assembly_id'];
$_SESSION['profile_photo'] = $user['profile_photo'];
// Log the login
$this->auditLog->log($user['id'], 'login', 'users', $user['id']);
return ['success' => true, 'user' => $user];
}
return ['success' => false, 'message' => 'Invalid credentials'];
} catch (PDOException $e) {
return ['success' => false, 'message' => 'Login error: ' . $e->getMessage()];
}
}
/**
* Logout user
*/
public function logout() {
if (isset($_SESSION['user_id'])) {
$this->auditLog->log($_SESSION['user_id'], 'logout', 'users', $_SESSION['user_id']);
}
session_unset();
session_destroy();
return true;
}
/**
* Register new user
*/
public function register($data) {
try {
// Check if username or email already exists
$stmt = $this->db->prepare("SELECT id FROM users WHERE username = :username OR email = :email");
$stmt->execute([
'username' => $data['username'],
'email' => $data['email']
]);
if ($stmt->fetch()) {
return ['success' => false, 'message' => 'Username or email already exists'];
}
// Hash password
$passwordHash = password_hash($data['password'], HASH_ALGO);
// Insert user
$stmt = $this->db->prepare("
INSERT INTO users (username, email, password_hash, full_name, phone,
access_level, area_id, district_id, assembly_id, is_active)
VALUES (:username, :email, :password_hash, :full_name, :phone,
:access_level, :area_id, :district_id, :assembly_id, 1)
");
$stmt->execute([
'username' => $data['username'],
'email' => $data['email'],
'password_hash' => $passwordHash,
'full_name' => $data['full_name'],
'phone' => $data['phone'] ?? null,
'access_level' => $data['access_level'],
'area_id' => $data['area_id'] ?? null,
'district_id' => $data['district_id'] ?? null,
'assembly_id' => $data['assembly_id'] ?? null
]);
$userId = $this->db->lastInsertId();
// Log the registration
$this->auditLog->log($_SESSION['user_id'] ?? null, 'create', 'users', $userId);
return ['success' => true, 'message' => 'User registered successfully', 'user_id' => $userId];
} catch (PDOException $e) {
return ['success' => false, 'message' => 'Registration error: ' . $e->getMessage()];
}
}
/**
* Change password
*/
public function changePassword($userId, $oldPassword, $newPassword) {
try {
// Verify old password
$stmt = $this->db->prepare("SELECT password_hash FROM users WHERE id = :id");
$stmt->execute(['id' => $userId]);
$user = $stmt->fetch();
if (!$user || !password_verify($oldPassword, $user['password_hash'])) {
return ['success' => false, 'message' => 'Current password is incorrect'];
}
// Update password
$newHash = password_hash($newPassword, HASH_ALGO);
$stmt = $this->db->prepare("UPDATE users SET password_hash = :password_hash WHERE id = :id");
$stmt->execute(['password_hash' => $newHash, 'id' => $userId]);
// Log the change
$this->auditLog->log($userId, 'password_change', 'users', $userId);
return ['success' => true, 'message' => 'Password changed successfully'];
} catch (PDOException $e) {
return ['success' => false, 'message' => 'Error changing password: ' . $e->getMessage()];
}
}
/**
* Update user profile
*/
public function updateProfile($userId, $data) {
try {
$stmt = $this->db->prepare("
UPDATE users
SET full_name = :full_name,
email = :email,
phone = :phone,
profile_photo = :profile_photo
WHERE id = :id
");
$stmt->execute([
'full_name' => $data['full_name'],
'email' => $data['email'],
'phone' => $data['phone'] ?? null,
'profile_photo' => $data['profile_photo'] ?? null,
'id' => $userId
]);
// Update session
$_SESSION['full_name'] = $data['full_name'];
$_SESSION['email'] = $data['email'];
if (isset($data['profile_photo'])) {
$_SESSION['profile_photo'] = $data['profile_photo'];
}
// Log the update
$this->auditLog->log($userId, 'update', 'users', $userId);
return ['success' => true, 'message' => 'Profile updated successfully'];
} catch (PDOException $e) {
return ['success' => false, 'message' => 'Error updating profile: ' . $e->getMessage()];
}
}
/**
* Check if user has permission
*/
public function hasPermission($userId, $permission) {
try {
$stmt = $this->db->prepare("
SELECT ar.permissions
FROM user_roles ur
JOIN access_roles ar ON ur.role_id = ar.id
WHERE ur.user_id = :user_id
");
$stmt->execute(['user_id' => $userId]);
$roles = $stmt->fetchAll();
foreach ($roles as $role) {
$permissions = json_decode($role['permissions'], true);
if (isset($permissions[$permission]) && $permissions[$permission]) {
return true;
}
}
// Superusers have all permissions
if (isSuperuser()) {
return true;
}
return false;
} catch (PDOException $e) {
return false;
}
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists