conn = $conn; $this->apiKeyModel = new ApiKeyModel($conn); $this->userModel = new UserModel($conn); } /** * Authenticate using API key from Authorization header * * @return array User data for system user * @throws Exception if authentication fails */ public function authenticate() { // Get Authorization header $authHeader = $this->getAuthorizationHeader(); if (empty($authHeader)) { $this->sendUnauthorized('Missing Authorization header'); exit; } // Check if it's a Bearer token if (!preg_match('/^Bearer\s+(.+)$/i', $authHeader, $matches)) { $this->sendUnauthorized('Invalid Authorization header format. Expected: Bearer '); exit; } $apiKey = $matches[1]; // Validate API key $keyData = $this->apiKeyModel->validateKey($apiKey); if (!$keyData) { $this->sendUnauthorized('Invalid or expired API key'); exit; } // Get system user (or the user who created the key) $user = $this->userModel->getSystemUser(); if (!$user) { $this->sendUnauthorized('System user not found'); exit; } // Add API key info to user data for logging $user['api_key_id'] = $keyData['api_key_id']; $user['api_key_name'] = $keyData['key_name']; return $user; } /** * Get Authorization header from various sources * * @return string|null Authorization header value */ private function getAuthorizationHeader() { // Try different header formats if (isset($_SERVER['HTTP_AUTHORIZATION'])) { return $_SERVER['HTTP_AUTHORIZATION']; } if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { return $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; } // Check for Authorization in getallheaders if available if (function_exists('getallheaders')) { $headers = getallheaders(); if (isset($headers['Authorization'])) { return $headers['Authorization']; } if (isset($headers['authorization'])) { return $headers['authorization']; } } return null; } /** * Send 401 Unauthorized response * * @param string $message Error message */ private function sendUnauthorized($message) { header('HTTP/1.1 401 Unauthorized'); header('Content-Type: application/json'); echo json_encode([ 'success' => false, 'error' => 'Unauthorized', 'message' => $message ]); } /** * Verify API key without throwing errors (for optional auth) * * @return array|null User data or null if not authenticated */ public function verifyOptional() { $authHeader = $this->getAuthorizationHeader(); if (empty($authHeader)) { return null; } if (!preg_match('/^Bearer\s+(.+)$/i', $authHeader, $matches)) { return null; } $apiKey = $matches[1]; $keyData = $this->apiKeyModel->validateKey($apiKey); if (!$keyData) { return null; } $user = $this->userModel->getSystemUser(); if ($user) { $user['api_key_id'] = $keyData['api_key_id']; $user['api_key_name'] = $keyData['key_name']; } return $user; } }