-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SHS-5811: Add "logout" button to sites (#21)
- Loading branch information
1 parent
a22df73
commit 3c0a690
Showing
3 changed files
with
226 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
<?php | ||
|
||
namespace Drupal\stanford_samlauth\Plugin\Block; | ||
|
||
use Drupal\Core\Access\AccessResult; | ||
use Drupal\Core\Block\BlockBase; | ||
use Drupal\Core\Cache\Cache; | ||
use Drupal\Core\Form\FormStateInterface; | ||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; | ||
use Drupal\Core\Session\AccountInterface; | ||
use Drupal\Core\Url; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
|
||
/** | ||
* Provides a 'Saml Logout Block' block. | ||
* | ||
* @Block( | ||
* id = "stanford_samlauth_logout_block", | ||
* admin_label = @Translation("SAML SUNetID Logout Block") | ||
* ) | ||
*/ | ||
class SamlLogoutBlock extends BlockBase implements ContainerFactoryPluginInterface { | ||
|
||
/** | ||
* Current uri the block is displayed on. | ||
* | ||
* @var string | ||
*/ | ||
protected $currentUri; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { | ||
return new static( | ||
$configuration, | ||
$plugin_id, | ||
$plugin_definition, | ||
$container->get('request_stack') | ||
); | ||
} | ||
|
||
/** | ||
* Block constructor. | ||
* | ||
* @param array $configuration | ||
* Configuration settings. | ||
* @param string $plugin_id | ||
* Block machine name. | ||
* @param array $plugin_definition | ||
* Plugin definition. | ||
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack | ||
* Current request stack object. | ||
*/ | ||
public function __construct(array $configuration, string $plugin_id, array $plugin_definition, RequestStack $requestStack) { | ||
parent::__construct($configuration, $plugin_id, $plugin_definition); | ||
$this->currentUri = $requestStack->getCurrentRequest() ?->getPathInfo(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function defaultConfiguration() { | ||
return ['link_text' => 'SUNetID Logout'] + parent::defaultConfiguration(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function blockForm($form, FormStateInterface $form_state) { | ||
$form['link_text'] = [ | ||
'#type' => 'textfield', | ||
'#title' => $this->t('SUNetID log-out link text'), | ||
'#description' => $this->t('Add text to show a link for authenticated users.'), | ||
'#default_value' => $this->configuration['link_text'], | ||
'#required' => TRUE, | ||
]; | ||
return $form; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getCacheContexts() { | ||
$context = parent::getCacheContexts(); | ||
// Make the block cache different for each page since the login link has a | ||
// destination parameter. | ||
return Cache::mergeContexts($context, ['url.path']); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function access(AccountInterface $account, $return_as_object = FALSE) { | ||
$access = AccessResult::allowedIf($account->isAuthenticated()); | ||
return $return_as_object ? $access : $access->isAllowed(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function blockSubmit($form, FormStateInterface $form_state) { | ||
$this->configuration['link_text'] = $form_state->getValue('link_text'); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function build() { | ||
$url = Url::fromRoute('user.logout', ['destination' => $this->currentUri]); | ||
$build = []; | ||
$build['logout'] = [ | ||
'#type' => 'html_tag', | ||
'#tag' => 'a', | ||
'#value' => $this->configuration['link_text'], | ||
'#attributes' => [ | ||
'rel' => 'nofollow', | ||
'href' => $url->toString(), | ||
'class' => [ | ||
'su-button', | ||
'decanter-button', | ||
], | ||
], | ||
]; | ||
return $build; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
|
||
namespace Drupal\Tests\stanford_samlauth\Unit\Plugin\Block; | ||
|
||
use Drupal\Core\Cache\Context\CacheContextsManager; | ||
use Drupal\Core\DependencyInjection\ContainerBuilder; | ||
use Drupal\Core\Form\FormState; | ||
use Drupal\Core\Routing\UrlGeneratorInterface; | ||
use Drupal\Core\Session\AccountInterface; | ||
use Drupal\stanford_samlauth\Plugin\Block\SamlLogoutBlock; | ||
use Drupal\Tests\UnitTestCase; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
|
||
/** | ||
* Class SamlLogoutBlockTest | ||
* | ||
* @package Drupal\Tests\stanford_samlauth\Unit\Plugin\Block | ||
* @covers \Drupal\stanford_samlauth\Plugin\Block\SamlLoginBlock | ||
*/ | ||
class SamlLogoutBlockTest extends UnitTestCase { | ||
|
||
/** | ||
* The block plugin. | ||
* | ||
* @var \Drupal\stanford_samlauth\Plugin\Block\SamlLogoutBlock | ||
*/ | ||
protected $block; | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function setup(): void { | ||
parent::setUp(); | ||
|
||
$url_generator = $this->createMock(UrlGeneratorInterface::class); | ||
$url_generator->method('generateFromRoute')->willReturn('/foo-bar'); | ||
|
||
$request_stack = new RequestStack(); | ||
|
||
$context_manager = $this->createMock(CacheContextsManager::class); | ||
$context_manager->method('assertValidTokens')->willReturn(TRUE); | ||
|
||
$container = new ContainerBuilder(); | ||
$container->set('string_translation', $this->getStringTranslationStub()); | ||
$container->set('url_generator', $url_generator); | ||
$container->set('request_stack', $request_stack); | ||
$container->set('cache_contexts_manager', $context_manager); | ||
\Drupal::setContainer($container); | ||
|
||
$this->block = SamlLogoutBlock::create($container, [], 'saml_logout', ['provider' => 'stanford_samlauth']); | ||
} | ||
|
||
/** | ||
* Test configuration and form methods. | ||
*/ | ||
public function testBlock() { | ||
$this->assertEquals(['link_text' => 'SUNetID Logout'], $this->block->defaultConfiguration()); | ||
$form_state = new FormState(); | ||
$form = $this->block->blockForm([], $form_state); | ||
$this->assertCount(1, $form); | ||
$this->assertArrayHasKey('link_text', $form); | ||
|
||
$link_text = $this->getRandomGenerator()->string(); | ||
$form_state->setValue('link_text', $link_text); | ||
$this->block->blockSubmit($form, $form_state); | ||
$new_config = $this->block->getConfiguration(); | ||
$this->assertEquals($link_text, $new_config['link_text']); | ||
} | ||
|
||
/** | ||
* Test anonymous users would access the block, authenticated would not. | ||
*/ | ||
public function testAccess() { | ||
$this->assertContains('url.path', $this->block->getCacheContexts()); | ||
|
||
$account = $this->createMock(AccountInterface::class); | ||
$account->method('isAuthenticated')->willReturn(TRUE); | ||
$this->assertTrue($this->block->access($account)); | ||
|
||
$account = $this->createMock(AccountInterface::class); | ||
$account->method('isAuthenticated')->willReturn(FALSE); | ||
$this->assertFALSE($this->block->access($account)); | ||
} | ||
|
||
/** | ||
* Test build render array is structured correctly. | ||
*/ | ||
public function testBuild() { | ||
$build = $this->block->build(); | ||
$this->assertCount(1, $build); | ||
$this->assertArrayHasKey('logout', $build); | ||
$this->assertEquals('html_tag', $build['logout']['#type']); | ||
$this->assertEquals('/foo-bar', $build['logout']['#attributes']['href']); | ||
} | ||
|
||
} |