| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <?php
- /**
- * Authentication and Authorization Middleware
- * Handles user authentication and role-based access control
- */
- class AuthMiddleware {
- private $db;
- private $user;
-
- public function __construct($db) {
- $this->db = $db;
- require_once __DIR__ . '/../models/User.php';
- $this->user = new User($db);
- }
-
- /**
- * Authenticate user from JWT token or session
- * @return array|null User data or null if not authenticated
- */
- public function authenticate() {
- // Check for Authorization header
- $headers = getallheaders();
- $auth_header = $headers['Authorization'] ?? $headers['authorization'] ?? '';
-
- if ($auth_header) {
- // Extract token from "Bearer <token>" format
- $token = str_replace('Bearer ', '', $auth_header);
- return $this->validateToken($token);
- }
-
- // Fallback to session-based authentication
- if (session_status() === PHP_SESSION_NONE) {
- session_start();
- }
-
- if (isset($_SESSION['user_id'])) {
- $this->user->id = $_SESSION['user_id'];
- $this->user->readOne();
-
- if ($this->user->username) {
- return [
- 'id' => $this->user->id,
- 'username' => $this->user->username,
- 'email' => $this->user->email,
- 'first_name' => $this->user->first_name,
- 'last_name' => $this->user->last_name,
- 'role' => $this->user->role,
- 'is_active' => $this->user->is_active
- ];
- }
- }
-
- return null;
- }
-
- /**
- * Validate JWT token (simplified implementation)
- * @param string $token JWT token
- * @return array|null User data or null if invalid
- */
- private function validateToken($token) {
- // For now, implement a simple token validation
- // In production, use a proper JWT library
- try {
- $payload = json_decode(base64_decode($token), true);
-
- if (isset($payload['user_id']) && isset($payload['expires'])) {
- if ($payload['expires'] > time()) {
- $this->user->id = $payload['user_id'];
- $this->user->readOne();
-
- if ($this->user->username && $this->user->is_active) {
- return [
- 'id' => $this->user->id,
- 'username' => $this->user->username,
- 'email' => $this->user->email,
- 'first_name' => $this->user->first_name,
- 'last_name' => $this->user->last_name,
- 'role' => $this->user->role,
- 'is_active' => $this->user->is_active
- ];
- }
- }
- }
- } catch (Exception $e) {
- // Token is invalid
- }
-
- return null;
- }
-
- /**
- * Check if user has admin role
- * @param array $user User data
- * @return bool True if user is admin
- */
- public function isAdmin($user) {
- return $user && $user['role'] === 'admin';
- }
-
- /**
- * Check if user can access resource
- * @param array $user User data
- * @param string $required_role Required role (admin/user)
- * @param int|null $resource_owner_id Resource owner ID (for profile access)
- * @return bool True if user can access
- */
- public function canAccess($user, $required_role = null, $resource_owner_id = null) {
- if (!$user || !$user['is_active']) {
- return false;
- }
-
- // Admin can access everything
- if ($user['role'] === 'admin') {
- return true;
- }
-
- // Check if specific role is required
- if ($required_role && $user['role'] !== $required_role) {
- return false;
- }
-
- // Check if user is accessing their own resource (profile management)
- if ($resource_owner_id && $user['id'] == $resource_owner_id) {
- return true;
- }
-
- // Default: allow access for regular users to their own resources
- return !$resource_owner_id;
- }
-
- /**
- * Generate simple JWT token
- * @param array $user User data
- * @return string JWT token
- */
- public function generateToken($user) {
- $payload = [
- 'user_id' => $user['id'],
- 'username' => $user['username'],
- 'role' => $user['role'],
- 'expires' => time() + (24 * 60 * 60) // 24 hours
- ];
-
- return base64_encode(json_encode($payload));
- }
-
- /**
- * Send unauthorized response
- */
- public function sendUnauthorizedResponse() {
- http_response_code(401);
- echo json_encode([
- 'success' => false,
- 'message' => 'Unauthorized access. Please login.'
- ]);
- exit;
- }
-
- /**
- * Send forbidden response
- */
- public function sendForbiddenResponse() {
- http_response_code(403);
- echo json_encode([
- 'success' => false,
- 'message' => 'Access denied. Insufficient permissions.'
- ]);
- exit;
- }
- }
- ?>
|