diff --git a/environment_indicator.install b/environment_indicator.install index 3da415da48bd7c1f5ae1a4ffb93181fd81c8681e..183f49cb4885d723f5efabc72095f6899030f18b 100644 --- a/environment_indicator.install +++ b/environment_indicator.install @@ -5,6 +5,8 @@ * Install, update and uninstall functions for the Environment Indicator module. */ +use Drupal\user\Entity\Role; + /** * Initialize the version_identifier and version_identifier_fallback settings. */ @@ -25,3 +27,31 @@ function environment_indicator_update_8101() { $settings->save(); } + +/** + * Grant 'view environment indicator current release' to roles. + * + * This function updates all roles to include the + * 'view environment indicator current release' permission if they + * already have the 'access environment indicator' permission. + * This is necessary to ensure that users who can access the + * environment indicator can also view the current release information. + * + * @see https://www.drupal.org/project/environment_indicator/issues/3310409 + */ +function environment_indicator_update_8102() { + $permission_to_find = 'access environment indicator'; + $permission_to_add = 'view environment indicator current release'; + + // Load all roles. + $roles = Role::loadMultiple(); + + foreach ($roles as $role) { + $permissions = $role->getPermissions(); + if (in_array($permission_to_find, $permissions, TRUE) && !in_array($permission_to_add, $permissions, TRUE)) { + $permissions[] = $permission_to_add; + $role->set('permissions', $permissions); + $role->save(); + } + } +} diff --git a/environment_indicator.module b/environment_indicator.module index b3fa7f07116caa8f61bb204cbefd139671129a96..dcb7458fa9c126d04f68887cd4f654b546056053 100644 --- a/environment_indicator.module +++ b/environment_indicator.module @@ -170,8 +170,11 @@ function environment_indicator_page_top(array &$page_top) { } $environment_indicator = \Drupal::service('environment_indicator.indicator'); $active_environment = $environment_indicator->getActiveEnvironment(); - $entityTypeManager = \Drupal::entityTypeManager(); + if (empty($active_environment->get('name'))) { + return; + } $name = $active_environment->get('name'); + $entityTypeManager = \Drupal::entityTypeManager(); $page_top['indicator'] = [ '#type' => 'environment_indicator', '#title' => $name, diff --git a/environment_indicator.permissions.yml b/environment_indicator.permissions.yml index 6b07d287932b52776e6c7bf1dd0df9bcab52aef9..0e54a0fef55bff3f83c135a2801e84e1b8d61a9e 100644 --- a/environment_indicator.permissions.yml +++ b/environment_indicator.permissions.yml @@ -6,5 +6,9 @@ access environment indicator: title: 'See all environment indicators' description: 'See all the environment indicators in the site.' +view environment indicator current release: + title: 'View environment indicator current release' + description: 'View the configured environment indicator current release information.' + permission_callbacks: - Drupal\environment_indicator\EnvironmentIndicatorPermissions::permissions diff --git a/environment_indicator.services.yml b/environment_indicator.services.yml index eeeca3ceb310b42efde0662c388575bfa05320e6..63893cf17029eb4bd49bb64430d45ba4198ce7e0 100644 --- a/environment_indicator.services.yml +++ b/environment_indicator.services.yml @@ -16,3 +16,4 @@ services: - '@entity_type.manager' - '@state' - '@settings' + - '@current_user' diff --git a/modules/environment_indicator_toolbar/tests/src/Functional/ToolbarIntegrationTest.php b/modules/environment_indicator_toolbar/tests/src/Functional/ToolbarIntegrationTest.php index 6e104898c229835e09025343a7f3737fab0d5e1e..235685f0be6b42576221985cd4234069440103ae 100644 --- a/modules/environment_indicator_toolbar/tests/src/Functional/ToolbarIntegrationTest.php +++ b/modules/environment_indicator_toolbar/tests/src/Functional/ToolbarIntegrationTest.php @@ -44,6 +44,13 @@ class ToolbarIntegrationTest extends BrowserTestBase { */ protected $unprivilegedUser; + /** + * A user with permission to see the current release. + * + * @var \Drupal\user\UserInterface + */ + protected $currentReleaseUser; + /** * The path to the environment_indicator module. * @@ -83,6 +90,11 @@ protected function setUp(): void { // Create users. $this->privilegedUser = $this->drupalCreateUser(['access environment indicator', 'access toolbar']); $this->unprivilegedUser = $this->drupalCreateUser(); + $this->currentReleaseUser = $this->drupalCreateUser([ + 'access toolbar', + 'access environment indicator', + 'view environment indicator current release', + ]); } /** @@ -191,7 +203,27 @@ public function testIndicatorDefaultConfiguration(): void { ->save(); $this->container->get('cache_tags.invalidator')->invalidateTags(['config:environment_indicator.indicator']); $this->drupalGet(''); + $this->assertSession()->pageTextNotContains('v1.2.44'); + $this->assertSession()->elementNotExists('css', "link[href*='{$this->environmentIndicatorModulePath}/css/environment_indicator.css']"); + $this->assertSession()->elementNotExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/environment_indicator.js']"); + $this->assertSession()->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/tinycon.min.js']"); + $this->assertSession()->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/favicon.js']"); + $this->assertSession()->elementExists('css', "link[href*='{$this->environmentIndicatorToolbarModulePath}/css/toolbar.css']"); + $this->assertSession()->pageTextContains('Indicator Environment'); + $page = $this->getSession()->getPage()->getContent(); + $this->assertStringContainsString('environmentIndicator', $page); + $this->assertStringContainsString('', $page); + $this->drupalLogin($this->currentReleaseUser); $this->assertSession()->pageTextContains('v1.2.44'); + $this->assertSession()->elementNotExists('css', "link[href*='{$this->environmentIndicatorModulePath}/css/environment_indicator.css']"); + $this->assertSession()->elementNotExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/environment_indicator.js']"); + $this->assertSession()->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/tinycon.min.js']"); + $this->assertSession()->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/favicon.js']"); + $this->assertSession()->elementExists('css', "link[href*='{$this->environmentIndicatorToolbarModulePath}/css/toolbar.css']"); + } /** diff --git a/src/Service/EnvironmentIndicator.php b/src/Service/EnvironmentIndicator.php index 525d52fa562dda75b9ee21f5a00fef4f8cdfd32e..cef2f0bb5a3e0a40f57af71c4017075dbd8065a8 100644 --- a/src/Service/EnvironmentIndicator.php +++ b/src/Service/EnvironmentIndicator.php @@ -9,6 +9,7 @@ use Drupal\Core\Site\Settings; use Drupal\Core\State\StateInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Session\AccountProxyInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; @@ -67,6 +68,13 @@ class EnvironmentIndicator { */ protected $switcherLinkStyles = []; + /** + * The current user. + * + * @var \Drupal\Core\Session\AccountProxyInterface + */ + protected AccountProxyInterface $account; + /** * Indicator constructor. * @@ -78,17 +86,21 @@ class EnvironmentIndicator { * The state service. * @param \Drupal\Core\Site\Settings $settings * The settings service. + * @param \Drupal\Core\Session\AccountProxyInterface $account + * The current user. */ public function __construct( ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, StateInterface $state, Settings $settings, + AccountProxyInterface $account, ) { $this->configFactory = $config_factory; $this->entityTypeManager = $entity_type_manager; $this->state = $state; $this->settings = $settings; + $this->account = $account; $this->activeEnvironment = $this->configFactory->get('environment_indicator.indicator'); $this->activeConfig = $this->configFactory->get('environment_indicator.settings'); } @@ -120,10 +132,12 @@ public function getActiveConfig(): ImmutableConfig { * The current release identifier, or NULL if not set. */ public function getCurrentRelease(): ?string { + if (!$this->account->hasPermission('view environment indicator current release')) { + return NULL; + } $config = $this->getActiveConfig(); $primary = $config->get('version_identifier') ?? 'environment_indicator_current_release'; $fallback = $config->get('version_identifier_fallback') ?? 'deployment_identifier'; - return $this->getVersionIdentifier($primary) ?? ($primary !== $fallback ? $this->getVersionIdentifier($fallback) : NULL); } diff --git a/src/ToolbarHandler.php b/src/ToolbarHandler.php index 23b3cd8298ff8e583f60d17b80fb13df08f28796..068f8f1e0920918bda199ba9af5a9e12cf5276ff 100644 --- a/src/ToolbarHandler.php +++ b/src/ToolbarHandler.php @@ -251,6 +251,9 @@ public function toolbar(): array { * @see https://www.drupal.org/node/3526812 */ public function getCurrentRelease(): ?string { + if (!$this->account->hasPermission('view environment indicator current release')) { + return NULL; + } $version_identifier = $this->config->get('version_identifier') ?? 'environment_indicator_current_release'; $version_identifier_fallback = $this->config->get('version_identifier_fallback') ?? 'deployment_identifier'; diff --git a/tests/src/Functional/EnvironmentIndicatorTest.php b/tests/src/Functional/EnvironmentIndicatorTest.php index afe6dea0cbfe6204aa4fe30dfa2ed9020992003f..00835ebe0c105db3580b959c9072f46d7ded661e 100644 --- a/tests/src/Functional/EnvironmentIndicatorTest.php +++ b/tests/src/Functional/EnvironmentIndicatorTest.php @@ -43,6 +43,13 @@ class EnvironmentIndicatorTest extends BrowserTestBase { */ protected $unprivilegedUser; + /** + * A user with permission to see the current release. + * + * @var \Drupal\user\UserInterface + */ + protected $currentReleaseUser; + /** * A user with permission to create environment switchers. * @@ -78,6 +85,10 @@ protected function setUp(): void { $this->resetAll(); // Create users. $this->privilegedUser = $this->drupalCreateUser(['access environment indicator']); + $this->currentReleaseUser = $this->drupalCreateUser([ + 'access environment indicator', + 'view environment indicator current release', + ]); $this->unprivilegedUser = $this->drupalCreateUser(); } @@ -196,10 +207,15 @@ public function testIndicatorDefaultConfiguration(): void { $this->assertNotEmpty($element->getAttribute('style'), 'Style attribute should not be empty.'); $this->assertStringContainsString('background-color: #ffffff', $element->getAttribute('style')); $this->assertStringContainsString('color: #000000', $element->getAttribute('style')); - $assert_session->elementExists('css', 'div#environment-indicator span.description'); - $assert_session->pageTextContains('v1.2.44'); + $assert_session->elementNotExists('css', 'div#environment-indicator span.description'); + $assert_session->pageTextNotContains('v1.2.44'); $assert_session->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/tinycon.min.js']"); $assert_session->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/favicon.js']"); + $this->drupalLogin($this->currentReleaseUser); + $this->drupalGet(''); + $assert_session = $this->assertSession(); + $assert_session->elementExists('css', 'div#environment-indicator span.description'); + $assert_session->pageTextContains('v1.2.44'); } /** @@ -212,7 +228,6 @@ public function testNoIndicatorWhenNameIsEmpty(): void { ->set('bg_color', '#ffffff') ->save(); $this->container->get('cache_tags.invalidator')->invalidateTags(['config:environment_indicator.indicator']); - $this->drupalLogin($this->privilegedUser); $this->drupalGet(''); $assert_session = $this->assertSession(); @@ -245,11 +260,34 @@ public function testIntegerInState(): void { $this->assertNotNull($element, 'Environment indicator element not found.'); $this->assertStringContainsString('background-color: #abcdef', $element->getAttribute('style')); $this->assertStringContainsString('color: #123456', $element->getAttribute('style')); - + $this->assertSession()->pageTextNotContains('12345'); + $this->drupalLogin($this->currentReleaseUser); + $this->drupalGet(''); // The integer should be rendered as text in the indicator output. $assert_session->pageTextContains('12345'); $assert_session->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/tinycon.min.js']"); $assert_session->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/favicon.js']"); } + /** + * Tests the current release visibility based on permissions. + */ + public function testCurrentReleasePermission(): void { + // Set environment name and current release. + $config = $this->config('environment_indicator.indicator'); + $config->set('name', 'Permission Test Environment') + ->set('fg_color', '#111111') + ->set('bg_color', '#eeeeee') + ->save(); + $this->state->set('environment_indicator.current_release', 'v9.9.9'); + $this->container->get('cache_tags.invalidator')->invalidateTags(['config:environment_indicator.indicator']); + $this->drupalLogin($this->currentReleaseUser); + $this->drupalGet(''); + $this->assertSession()->pageTextContains('v9.9.9'); + // User with only 'access environment indicator': should not see release. + $this->drupalLogin($this->privilegedUser); + $this->drupalGet(''); + $this->assertSession()->pageTextNotContains('v9.9.9'); + } + } diff --git a/tests/src/Functional/ToolbarIntegrationTest.php b/tests/src/Functional/ToolbarIntegrationTest.php index 8d34fbaf610ea1e4d5ba3859ee446815359c7921..ab2b14ce0674c4f771c8acb8980e418c1f5b82fd 100644 --- a/tests/src/Functional/ToolbarIntegrationTest.php +++ b/tests/src/Functional/ToolbarIntegrationTest.php @@ -44,6 +44,13 @@ class ToolbarIntegrationTest extends BrowserTestBase { */ protected $unprivilegedUser; + /** + * A user with permission to see the current release. + * + * @var \Drupal\user\UserInterface + */ + protected $currentReleaseUser; + /** * The path to the environment_indicator module. * @@ -73,6 +80,11 @@ protected function setUp(): void { $config->set('css.preprocess', FALSE)->save(); // Create users. + $this->currentReleaseUser = $this->drupalCreateUser([ + 'access toolbar', + 'access environment indicator', + 'view environment indicator current release', + ]); $this->privilegedUser = $this->drupalCreateUser(['access environment indicator', 'access toolbar']); $this->unprivilegedUser = $this->drupalCreateUser(); } @@ -170,7 +182,6 @@ public function testEnvironmentIndicatorToolbarIntegration(): void { * Tests the indicator with the default configuration. */ public function testIndicatorDefaultConfiguration(): void { - $this->drupalLogin($this->privilegedUser); $this->state->set('environment_indicator.current_release', 'v1.2.44'); $config = $this->config('environment_indicator.indicator'); $config->set('name', 'Indicator Environment') @@ -178,12 +189,13 @@ public function testIndicatorDefaultConfiguration(): void { ->set('bg_color', '#ffffff') ->save(); $this->container->get('cache_tags.invalidator')->invalidateTags(['config:environment_indicator.indicator']); + $this->drupalLogin($this->currentReleaseUser); $this->drupalGet(''); - $this->assertSession()->pageTextContains('v1.2.44'); $this->assertSession()->elementExists('css', "link[href*='{$this->environmentIndicatorModulePath}/css/environment_indicator.css']"); $this->assertSession()->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/environment_indicator.js']"); $this->assertSession()->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/tinycon.min.js']"); $this->assertSession()->elementExists('css', "script[src*='{$this->environmentIndicatorModulePath}/js/favicon.js']"); + $this->assertSession()->pageTextContains('v1.2.44'); } }