Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.0.x' into accordion-power-bi
Browse files Browse the repository at this point in the history
  • Loading branch information
illya-havsiyevych committed Sep 6, 2023
2 parents e52a173 + 73cfe20 commit be4e406
Show file tree
Hide file tree
Showing 23 changed files with 810 additions and 257 deletions.
42 changes: 28 additions & 14 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
{
"name": "epam/quanthub-portal",
"description": "Quanthub Portal Drupal Profile",
"type": "drupal-profile",
"require": {
"php": ">=8.0",
"jumbojett/openid-connect-php": "^0.9.6"
},
"license": "GPL-3.0-or-later",
"authors": [
{
"name": "Artem Boyko",
"email": "[email protected]"
"name": "epam/quanthub-portal",
"description": "Quanthub Portal Drupal Profile",
"type": "drupal-profile",
"require": {
"php": ">=8.0",
"jumbojett/openid-connect-php": "^0.9.10",
"cweagans/composer-patches": "1.7.3"
},
"license": "GPL-3.0-or-later",
"authors": [
{
"name": "Artem Boyko",
"email": "[email protected]"
}
],
"minimum-stability": "dev",
"config": {
"allow-plugins": {
"cweagans/composer-patches": true
}
},
"extra": {
"composer-exit-on-patch-failure": true,
"patches": {
"jumbojett/openid-connect-php": {
"Update minimum versions according to security check": "https://patch-diff.githubusercontent.com/raw/jumbojett/OpenID-Connect-PHP/pull/385.patch"
}
}
}
],
"minimum-stability": "dev"
}
58 changes: 53 additions & 5 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions modules/quanthub_core/js/qh_core-power-bi-customizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function powerbi_embed_customizeReport($, context, width = 0, height = 0, title
iframes[i].height = ih + 'px';
}

checkTokenAndUpdate($, context);
setInterval(() => {
checkTokenAndUpdate($, context);
},
Expand Down
6 changes: 3 additions & 3 deletions modules/quanthub_core/quanthub_core.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ services:
class: '\Drupal\quanthub_core\AnonymousUserInfoTokenSubscriber'
tags:
- { name: event_subscriber }
arguments: ['@cache.default', '@current_user', '@logger.channel.quanthub_core', '@config.factory', '@http_client']
arguments: ['@user_info']

# Event subscriber for getting and storing user info attributes for authenticated user.
user_info_attributes_subscriber:
Expand All @@ -43,11 +43,11 @@ services:
# Get user info token for any user.
user_info:
class: '\Drupal\quanthub_core\UserInfo'
arguments: ['@current_user', '@cache.default', '@oidc.openid_connect_session', '@user.data', '@http_client']
arguments: ['@current_user', '@cache.default', '@oidc.openid_connect_session', '@user.data', '@http_client', '@logger.channel.quanthub_core', '@config.factory']

powerbi_embed_configs:
class: Drupal\quanthub_core\PowerBIEmbedConfigs
arguments: ['@config.factory', '@key.repository', '@logger.factory']
arguments: ['@config.factory', '@key.repository', '@logger.factory', '@http_client']

# User Info Cache Context based on User Info Role for anonymous and User Id for others.
cache_context.user_info_attributes:
Expand Down
112 changes: 7 additions & 105 deletions modules/quanthub_core/src/AnonymousUserInfoTokenSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@

namespace Drupal\quanthub_core;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Session\AccountInterface;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
Expand All @@ -20,115 +14,23 @@ class AnonymousUserInfoTokenSubscriber implements EventSubscriberInterface, User
/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
* @var \Drupal\quanthub_core\UserInfo
*/
protected $configFactory;

/**
* The logger service.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;

/**
* The cache default service.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;

/**
* The current user service.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;

/**
* The http client service.
*
* @var \GuzzleHttp\ClientInterface
*/
protected $httpClient;
protected $userInfo;

/**
* Constructs an AnonymousUserInfoTokenSubscriber object.
*/
public function __construct(CacheBackendInterface $cache, AccountInterface $current_user, LoggerInterface $logger, ConfigFactoryInterface $configFactory, ClientInterface $http_client) {
$this->cache = $cache;
$this->currentUser = $current_user;
$this->logger = $logger;
$this->configFactory = $configFactory;
$this->httpClient = $http_client;
public function __construct(UserInfo $user_info) {
$this->userInfo = $user_info;
}

/**
* Get anonymous user info token and save to cache.
*
* As this token for anonymous user no sense to store this more secure.
* Check that token is existed.
*/
public function onRequest(RequestEvent $event) {
if ($this->currentUser->isAnonymous() || $this->currentUser->id() == 1) {
if (!$this->cache->get(self::ANONYMOUS_TOKEN_CID)) {
// Oidc plugin id is dynamic hash, we firstly get id from oidc settings.
$generic_realms = $this->configFactory->get('oidc.settings')->get('generic_realms');
if (count($generic_realms) == 0) {
return;
}

$oidc_plugin_id = array_shift($generic_realms);
$oidc_plugin = $this->configFactory->get('oidc.realm.quanthub_b2c_realm.' . $oidc_plugin_id);
if (!isset($oidc_plugin)) {
return;
}
$anonymous_endpoint = $oidc_plugin->get(self::ANONYMOUS_TOKEN_ENDPOINT);

if ($anonymous_endpoint) {
try {
$response = $this->httpClient->get($anonymous_endpoint, [
'headers' => [
'Content-Type' => 'application/json',
],
]);

$user_info_data = json_decode($response->getBody(), TRUE);
$this->cache->set(self::ANONYMOUS_TOKEN_CID, $user_info_data['token'], strtotime($user_info_data['expiresOn']));
}
catch (RequestException $e) {
$this->logger->error('Failed to retrieve tokens for anonymous user: @error.', [
'@error' => $e->getMessage(),
]);

throw new \RuntimeException('Failed to retrieve the user info anonymous token', 0, $e);
}
}
else {
$this->logger->error('Failed to retrieve tokens for anonymous user: Anonymous token is not set');
}

$user_attributes_endpoint = $oidc_plugin->get(self::USER_ATTRIBUTES_ENDPOINT);
if (!$this->cache->get(self::ANONYMOUS_QUANTHUB_USER_ID)) {
try {
$response = $this->httpClient->get($user_attributes_endpoint, [
'headers' => [
'Authorization' => 'Bearer ' . $user_info_data['token'],
'Content-Type' => 'application/json',
],
]);

$user_attributes_data = json_decode($response->getBody(), TRUE);
$this->cache->set(self::ANONYMOUS_QUANTHUB_USER_ID, $user_attributes_data['userAttributes']['USER_ID'], strtotime($user_info_data['expiresOn']));
}
catch (RequestException $e) {
$this->logger->error('Failed to retrieve quanthub user id for anonymous user: @error.', [
'@error' => $e->getMessage(),
]);

throw new \RuntimeException('Failed to retrieve quanthub user id for anonymous token', 0, $e);
}
}
}
if (getenv('WSO_IGNORE') !== 'TRUE') {
$this->userInfo->getToken();
}
}

Expand Down
45 changes: 40 additions & 5 deletions modules/quanthub_core/src/Controller/PowerBIEmbedController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace Drupal\quanthub_core\Controller;

use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\quanthub_core\PowerBIEmbedConfigs;
use GuzzleHttp\Psr7\Response;
use Laminas\Diactoros\Response\JsonResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
Expand All @@ -20,6 +23,13 @@ class PowerBIEmbedController extends ControllerBase {
*/
protected $powerBIEmbedConfigs;

/**
* The EntityTypeManager service.
*
* @var \Drupal\Core\Entity\EntityTypeManager
*/
protected $entityTypeManager;

/**
* Create a PowerBIEmbedController instance.
*
Expand All @@ -28,7 +38,8 @@ class PowerBIEmbedController extends ControllerBase {
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('powerbi_embed_configs')
$container->get('powerbi_embed_configs'),
$container->get('entity_type.manager')
);
}

Expand All @@ -37,17 +48,41 @@ public static function create(ContainerInterface $container) {
*
* @param \Drupal\quanthub_core\PowerBIEmbedConfigs $powerBIEmbedConfigs
* The PowerBIEmbedConfigs object.
* @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
* The EntityTypeManager service.
*/
public function __construct(PowerBIEmbedConfigs $powerBIEmbedConfigs) {
public function __construct(PowerBIEmbedConfigs $powerBIEmbedConfigs, EntityTypeManager $entityTypeManager) {
$this->powerBIEmbedConfigs = $powerBIEmbedConfigs;
$this->entityTypeManager = $entityTypeManager;
}

/**
* Return Power BI embed configs in the json format.
*/
public function postData($reportId, Request $request): JsonResponse {
$content = json_decode($request->getContent(), TRUE);
return new JsonResponse($this->powerBIEmbedConfigs->getPowerEmbedConfig($reportId, $content["extraDatasets"]));
public function postData($reportId, Request $request): JsonResponse | Response {
if (!Uuid::isValid($reportId)) {
return new Response(400);
}

$media_storage = $this->entityTypeManager->getStorage('media');
$media_ids = $media_storage->getQuery()
->condition('bundle', 'power_bi')
->condition('field_media_power_bi.report_id', $reportId)
->execute();
if (empty($media_ids)) {
return new Response(400);
}

try {
$content = json_decode($request->getContent(), TRUE, 3, JSON_THROW_ON_ERROR);
return new JsonResponse($this->powerBIEmbedConfigs->getPowerEmbedConfig(
$reportId,
!empty($content['extraDatasets']) ? $content['extraDatasets'] : ''
));
}
catch (\Exception) {
return new Response(400);
}
}

}
Loading

0 comments on commit be4e406

Please sign in to comment.