184 lines
6.2 KiB
PHP
184 lines
6.2 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
class BiAnalytics
|
||
|
|
{
|
||
|
|
private $supersetDomain;
|
||
|
|
private $loginEndpoint;
|
||
|
|
private $guestTokenEndpoint;
|
||
|
|
private $adminUsername;
|
||
|
|
private $adminPassword;
|
||
|
|
|
||
|
|
public function __construct()
|
||
|
|
{
|
||
|
|
$this->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;
|
||
|
|
}
|
||
|
|
}
|