Skip to content

Commit 17bd289

Browse files
committedJan 22, 2025·
Entitlements finalization.
1 parent c394af5 commit 17bd289

File tree

8 files changed

+173
-20
lines changed

8 files changed

+173
-20
lines changed
 

Diff for: ‎modules/quanthub_chat_overlay/quanthub_chat_overlay.module

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,8 @@
99
* Implements hook_page_attachments().
1010
*/
1111
function quanthub_chat_overlay_page_attachments(array &$attachments) {
12-
$attachments['#attached']['library'][] = 'quanthub_chat_overlay/chat-overlay';
12+
if (\Drupal::currentUser()->hasPermission('access ai')) {
13+
$attachments['#attached']['library'][] = 'quanthub_chat_overlay/chat-overlay';
14+
}
15+
$attachments['#cache']['contexts'][] = 'user.permissions';
1316
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
access ai:
2+
title: 'Access AI tools'
3+
description: 'Access AI chat overlay and features.'

Diff for: ‎modules/quanthub_core/quanthub_core.module

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ function quanthub_core_node_access(NodeInterface $node, $operation, AccountInter
3333

3434
$cacheable_metadata = (new CacheableMetadata())
3535
->addCacheContexts(['user.roles:anonymous', 'user.permissions'])
36-
->addCacheContexts($account->isAuthenticated() ? ['user'] : [])
37-
->addCacheTags(['allowed_content_tag:' . $account->id()]);
36+
->addCacheContexts($account->isAuthenticated() ? ['user.datasets'] : []);
3837
$allowed_datasets = \Drupal::service('allowed_content_manager')
3938
->getAllowedDatasetList();
4039
$node_datasets = [];

Diff for: ‎modules/quanthub_core/quanthub_core.services.yml

+12
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ services:
4949
class: Drupal\quanthub_core\PowerBIEmbedConfigs
5050
arguments: ['@config.factory', '@key.repository', '@logger.factory', '@http_client']
5151

52+
cache_context.user.datasets:
53+
class: Drupal\quanthub_core\Cache\AllowedDatasetsCacheContext
54+
arguments: ['@current_user', '@allowed_content_manager']
55+
tags:
56+
- { name: cache.context }
57+
5258
# Client for calls to SDMX API.
5359
logger.channel.sdmx_api:
5460
parent: logger.channel_base
@@ -61,3 +67,9 @@ services:
6167
class: Drupal\quanthub_core\EventSubscriber\KernelEventsSubscriber
6268
arguments: [ '@current_route_match', '@entity_type.manager' ]
6369
tags: [ 'event_subscriber' ]
70+
71+
quanthub_core.oidc_subscriber:
72+
class: Drupal\quanthub_core\EventSubscriber\OidcEventsSubscriber
73+
arguments: [ '@oidc.openid_connect_session' ]
74+
tags:
75+
- { name: event_subscriber }

Diff for: ‎modules/quanthub_core/src/AllowedContentManager.php

-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Drupal\Component\Datetime\Time;
66
use Drupal\Component\DependencyInjection\ContainerInterface;
7-
use Drupal\Core\Cache\Cache;
87
use Drupal\Core\Cache\CacheBackendInterface;
98
use Drupal\Core\Language\LanguageManager;
109
use Drupal\Core\Session\AccountProxy;
@@ -121,10 +120,6 @@ public function getAllowedDatasetList() {
121120
$this->datasets,
122121
$this->time->getCurrentTime() + $this::CACHE_TIME
123122
);
124-
125-
// Invalidating cache tags for updating views
126-
// with datasets and publications.
127-
Cache::invalidateTags(['allowed_content_tag:' . $this->currentUser->id()]);
128123
}
129124

130125
return $this->datasets;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Drupal\quanthub_core\Cache;
4+
5+
use Drupal\Core\Cache\CacheableMetadata;
6+
use Drupal\Core\Cache\Context\CacheContextInterface;
7+
use Drupal\Core\Cache\Context\UserCacheContextBase;
8+
use Drupal\Core\Session\AccountInterface;
9+
use Drupal\quanthub_core\AllowedContentManager;
10+
11+
/**
12+
* Defines the User Allowed Datasets cache context service.
13+
*
14+
* Cache context ID: 'user.datasets'.
15+
*/
16+
class AllowedDatasetsCacheContext extends UserCacheContextBase implements CacheContextInterface {
17+
18+
/**
19+
* The Allowed Content Manager service.
20+
*
21+
* @var \Drupal\quanthub_core\AllowedContentManager
22+
*/
23+
protected $allowedContentManager;
24+
25+
/**
26+
* {@inheritdoc}
27+
*/
28+
public function __construct(AccountInterface $user, AllowedContentManager $allowed_content_manager) {
29+
parent::__construct($user);
30+
31+
$this->allowedContentManager = $allowed_content_manager;
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public static function getLabel() {
38+
return t('Allowed Datasets');
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function getContext() {
45+
$datasets = NULL;
46+
if (getenv('WSO_IGNORE') !== 'TRUE') {
47+
$datasets = $this->allowedContentManager->getAllowedDatasetList();
48+
sort($datasets);
49+
}
50+
// We don't need to secure this information, crc32 is enough.
51+
return hash('crc32', serialize($datasets));
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function getCacheableMetadata() {
58+
return (new CacheableMetadata())->setCacheTags(['user:' . $this->user->id()]);
59+
}
60+
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace Drupal\quanthub_core\EventSubscriber;
4+
5+
use Drupal\externalauth\Event\ExternalAuthEvents;
6+
use Drupal\externalauth\Event\ExternalAuthLoginEvent;
7+
use Drupal\oidc\OpenidConnectSessionInterface;
8+
use Drupal\oidc\Plugin\OpenidConnectRealm\GenericOpenidConnectRealm;
9+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10+
11+
/**
12+
* Event subscriber to assign user roles.
13+
*/
14+
class OidcEventsSubscriber implements EventSubscriberInterface {
15+
16+
/**
17+
* Roles mapping.
18+
*
19+
* @todo make configurable.
20+
*/
21+
const ROLES = [
22+
'DataPlatformBasic' => '',
23+
'DataPlatformEnhanced' => '',
24+
'DataPlatformMedia' => 'media',
25+
'PortalContentEditor' => 'content_editor',
26+
'AiAssistant' => 'ai',
27+
];
28+
29+
/**
30+
* The OpenID Connect session service.
31+
*
32+
* @var \Drupal\oidc\OpenidConnectSessionInterface
33+
*/
34+
protected $session;
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function __construct(OpenidConnectSessionInterface $session) {
40+
$this->session = $session;
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public static function getSubscribedEvents() {
47+
$events[ExternalAuthEvents::LOGIN][] = 'onLogin';
48+
49+
return $events;
50+
}
51+
52+
/**
53+
* Updates the synced user roles on login.
54+
*
55+
* @param \Drupal\externalauth\Event\ExternalAuthLoginEvent $event
56+
* The login event.
57+
*
58+
* @throws \Drupal\Core\Entity\EntityStorageException
59+
*/
60+
public function onLogin(ExternalAuthLoginEvent $event) {
61+
$plugin_id = $this->session->getRealmPluginId();
62+
$provider = 'oidc:' . $this->session->getRealmPluginId();
63+
$roles_claim = $this->session->getJsonWebTokens()->getClaim('roles');
64+
65+
// The provider must match the realm and provide the claim.
66+
if (!$plugin_id || $provider !== $event->getProvider() || $roles_claim === NULL) {
67+
return;
68+
}
69+
70+
$roles = [];
71+
if (is_array($roles_claim)) {
72+
foreach ($roles_claim as $role) {
73+
if (empty(self::ROLES[$role])) {
74+
continue;
75+
}
76+
$roles[] = self::ROLES[$role];
77+
}
78+
}
79+
80+
// Only generic realms support this.
81+
$plugin = $this->session->getRealmPlugin();
82+
if ($plugin instanceof GenericOpenidConnectRealm && $plugin->getDefaultRoleId()) {
83+
$roles[] = $plugin->getDefaultRoleId();
84+
}
85+
86+
$event->getAccount()
87+
->set('roles', array_unique($roles))
88+
->save();
89+
}
90+
91+
}

Diff for: ‎modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilter.php

+1-12
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,6 @@ public function query() {
8787
$this->query->addWhere($this->options['group'], $conditions);
8888
}
8989

90-
/**
91-
* {@inheritdoc}
92-
*/
93-
public function getCacheTags() {
94-
$account = $this->view->getUser();
95-
return Cache::mergeTags(
96-
parent::getCacheTags(),
97-
['allowed_content_tag:' . $account->id()]
98-
);
99-
}
100-
10190
/**
10291
* {@inheritdoc}
10392
*/
@@ -106,7 +95,7 @@ public function getCacheContexts() {
10695
$contexts = ['user.permissions', 'user.roles:anonymous'];
10796
// Cache per user if we filter by individual user's datasets.
10897
if (!$account->hasPermission('bypass dataset access') && $account->isAuthenticated()) {
109-
$contexts[] = 'user';
98+
$contexts[] = 'user.datasets';
11099
}
111100
return Cache::mergeContexts(
112101
parent::getCacheContexts(),

0 commit comments

Comments
 (0)
Please sign in to comment.