supersetDomain = trim('http://10.91.76.110'); $this->loginEndpoint = $this->supersetDomain . '/api/v1/security/login'; $this->guestTokenEndpoint = $this->supersetDomain . '/api/v1/security/guest_token/'; $this->adminUsername = 'admin'; $this->adminPassword = '6a6a78543e215c5adce1b828c9a30ef5'; } public static function getAvailableUserIds($userId, $role) { if ($role === 'company_head') { return null; } if ($role === 'agent') { return array($userId); } if ($role === 'manager') { $subordinates = self::getAllSubordinateIds($userId); $subordinates[] = $userId; return array_unique($subordinates); } return array($userId); } private static function getAllSubordinateIds($managerId) { $sql = "SELECT id FROM users WHERE id_manager = " . intval($managerId) . " AND blocked = 0"; $result = mysql_query($sql); if (!$result) { return array(); } $subIds = array(); while ($row = mysql_fetch_assoc($result)) { $subId = (int)$row['id']; $subIds[] = $subId; $subSubIds = self::getAllSubordinateIds($subId); $subIds = array_merge($subIds, $subSubIds); } return $subIds; } public static function buildRlsRules($companyId, $userId, $role) { $tables = array( 'cur.clients_base', 'bi.client_kpi_daily', 'logs.client_events', 'cur.requisitions_base', 'bi.requisition_kpi_daily', 'logs.requisition_events' ); $availableUserIds = self::getAvailableUserIds($userId, $role); $rules = array(); // Одно правило company_id на все таблицы (без dataset_name — Superset применит ко всем) $rules[] = array( 'clause' => "company_id = {$companyId}" ); // Если не company_head — добавляем фильтр по who_work if ($availableUserIds !== null) { $userIdsString = implode(',', $availableUserIds); $rules[] = array( 'clause' => "(who_work IN ({$userIdsString}) OR who_work = 0)" ); } return $rules; } public function getGuestToken($dashboardUuid, $companyId, $userId, $userRole, $userInfo = array()) { try { $accessToken = $this->getAdminAccessToken(); if (!$accessToken) { return array('error' => 'Failed to obtain admin access token'); } $rlsRules = self::buildRlsRules($companyId, $userId, $userRole); $guestTokenData = array( 'resources' => array( array( 'type' => 'dashboard', 'id' => $dashboardUuid ) ), 'rls' => $rlsRules, 'ui_config' => array( 'show_sql' => in_array($userRole, array('manager', 'company_head', 'admin', 'agent')), 'url_params' => array( 'filter_company_id' => (string)$companyId ) ), 'user' => array( 'username' => 'joywork_user_' . $userId, 'first_name' => isset($userInfo['first_name']) ? $userInfo['first_name'] : 'User', 'last_name' => isset($userInfo['last_name']) ? $userInfo['last_name'] : (string)$userId, 'email' => isset($userInfo['email']) ? $userInfo['email'] : null, ), 'attributes' => array( 'company_id' => $companyId, 'available_user_ids' => self::getAvailableUserIds($userId, $userRole), ), ); $response = $this->makeRequest($this->guestTokenEndpoint, $guestTokenData, $accessToken); if (isset($response['token'])) { return array('token' => $response['token']); } else { return array('error' => 'Guest token not returned', 'details' => $response); } } catch (Exception $e) { return array('error' => $e->getMessage()); } } private function getAdminAccessToken() { $loginData = array( 'username' => $this->adminUsername, 'password' => $this->adminPassword, 'provider' => 'db', 'refresh' => true, ); $response = $this->makeRequest($this->loginEndpoint, $loginData); if (isset($response['access_token'])) { return $response['access_token']; } return null; } private function makeRequest($url, $postData, $accessToken = null) { $ch = curl_init(); curl_setopt_array($ch, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($postData), CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', 'Accept: application/json', ), CURLOPT_SSL_VERIFYPEER => false, )); if ($accessToken) { $headers = array( 'Content-Type: application/json', 'Accept: application/json', 'Authorization: Bearer ' . $accessToken, ); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } $responseBody = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { throw new Exception("API request failed. HTTP code: $httpCode. Response: $responseBody"); } $decoded = json_decode($responseBody, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception("Invalid JSON response: " . json_last_error_msg()); } return $decoded; } }