Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Tweak Entra ID labels and add a handler that allows editors to add login links. #899

Merged
merged 15 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/core.extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module:
reliefweb_disaster_map: 0
reliefweb_dsr: 0
reliefweb_entities: 0
reliefweb_entraid: 0
reliefweb_fields: 0
reliefweb_files: 0
reliefweb_form: 0
Expand Down
2 changes: 1 addition & 1 deletion config/openid_connect.client.entraid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dependencies:
module:
- openid_connect_windows_aad
id: entraid
label: 'Entra ID (UNITE ID)'
label: 'Unite ID'
plugin: windows_aad
settings:
client_id: entraid_client_id
Expand Down
6 changes: 6 additions & 0 deletions html/modules/custom/reliefweb_entraid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Reliefweb Entra ID
============

This module provides user authentication tweaks for Entra ID

* Provide a `/user/login/entraid` callback to redirect to the Entra ID login workflow.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: 'Relieweb Entra ID'
description: Tweaks for Entra ID and/or Azure B2C.
type: module
core_version_requirement: ^9 || ^10
package: reliefweb
dependencies:
- openid_connect_windows_aad:openid_connect_windows_aad
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php

/**
* @file
* Reliefweb Entra ID.
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
reliefweb_entraid.login:
path: '/user/login/entraid'
defaults:
_controller: '\Drupal\reliefweb_entraid\Controller\AuthController::redirectLogin'
_title: 'Login with Unite ID'
requirements:
_user_is_logged_in: 'FALSE'
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace Drupal\reliefweb_entraid\Controller;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Http\Exception\CacheableNotFoundHttpException;
use Drupal\openid_connect\OpenIDConnectClaims;
use Drupal\openid_connect\OpenIDConnectSessionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Returns responses for OpenID Connect Windows AAD module routes.
*/
class AuthController extends ControllerBase implements ContainerInjectionInterface {

/**
* The OpenID Connect claims.
*
* @var \Drupal\openid_connect\OpenIDConnectClaims
*/
protected $openIdConnectClaims;

/**
* The OpenID Connect session service.
*
* @var \Drupal\openid_connect\OpenIDConnectSessionInterface
*/
protected $openIdConnectSession;

/**
* Constructs a new AuthController object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\openid_connect\OpenIDConnectClaims $open_id_connect_claims
* The OpenID Connect claims.
* @param \Drupal\openid_connect\OpenIDConnectSessionInterface $open_id_connect_session
* The OpenID Connect session service.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
OpenIDConnectClaims $open_id_connect_claims,
OpenIDConnectSessionInterface $open_id_connect_session,
) {
$this->entityTypeManager = $entity_type_manager;
$this->openIdConnectClaims = $open_id_connect_claims;
$this->openIdConnectSession = $open_id_connect_session;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('openid_connect.claims'),
$container->get('openid_connect.session')
);
}

/**
* Redirect to the user login callback.
*/
public function redirectLogin() {
try {
$client_entities = $this->entityTypeManager()
->getStorage('openid_connect_client')
->loadByProperties(['id' => 'entraid']);

if (!isset($client_entities['entraid'])) {
throw new \Exception();
}

$client = $client_entities['entraid'];
$plugin = $client->getPlugin();
$scopes = $this->openIdConnectClaims->getScopes($plugin);
$this->openIdConnectSession->saveOp('login');
$response = $plugin->authorize($scopes);

return $response->send();
}
catch (\Exception $exception) {
$config = $this->config('openid_connect.client.entraid');
$cacheable_metadata = new CacheableMetadata();
$cacheable_metadata->addCacheableDependency($config);
throw new CacheableNotFoundHttpException($cacheable_metadata);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace Drupal\Tests\reliefweb_entraid\ExistingSite;

use weitzman\DrupalTestTraits\ExistingSiteBase;

/**
* Tests entraid login widgets.
*
* @covers \Drupal\reliefweb_entraid\Controller\AuthController
* @coversDefaultClass \Drupal\reliefweb_entraid\Controller\AuthController
*/
class ReliefwebEntraidLoginTest extends ExistingSiteBase {

/**
* Store the original EntraID config data.
*
* @var array
*/
protected array $entraIdConfigData;

/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();

$this->entraIdConfigData = $this->container
->get('config.factory')
->getEditable('openid_connect.client.entraid')
->get();
}

/**
* {@inheritdoc}
*/
protected function tearDown(): void {
// Restore the original config data.
$this->container
->get('config.factory')
->getEditable('openid_connect.client.entraid')
->setData($this->entraIdConfigData)
->save();

parent::tearDown();
}

/**
* @covers ::redirectLogin()
*/
public function testRedirectLogin() {
// Get the EntraID configuration.
$entraid_config = $this->container
->get('config.factory')
->getEditable('openid_connect.client.entraid');

// Empty the enpoints to test the redirection when the config is not set.
$data = $entraid_config->get();
$data['settings']['authorization_endpoint_wa'] = '';
$data['settings']['token_endpoint_wa'] = '';
$data['settings']['iss_allowed_domains'] = '';
$entraid_config->setData($data)->save();

// The incomplete config will results in an exception and 404 response
// will be returned.
$this->drupalGet('/user/login/entraid');
$this->assertSession()->statusCodeEquals(404);

// Set the endpoints. We just point at the robots.txt as we know it exists
// and so, if the reponse status code in 200, then the redirection worked.
$data = $entraid_config->get();
$data['settings']['authorization_endpoint_wa'] = 'http://localhost/robots.txt';
$data['settings']['token_endpoint_wa'] = 'http://localhost/robots.txt';
$data['settings']['iss_allowed_domains'] = 'http://localhost/robots.txt';
$entraid_config->setData($data)->save();

// If the redirection works, a 200 will be returned.
$this->drupalGet('/user/login/entraid');
$this->assertSession()->statusCodeEquals(200);
$this->assertStringContainsString('Disallow:', $this->getSession()->getPage()->getContent());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@

/* RW-599: Style direct links to log in with HID on book pages to look like
* a button like it was on the RW7 site. */
.rw-document.rw-article--book .rw-article__content a[href*="/user/login/hid"] {
.rw-document.rw-article--book .rw-article__content a[href^="/user/login/"] {
display: inline-block;
margin: 1rem 0 0 0;
padding: 12px 18px;
Expand All @@ -136,8 +136,8 @@
background: var(--cd-reliefweb-brand-blue--dark);
font-weight: bold;
}
.rw-document.rw-article--book .rw-article__content a[href*="/user/login/hid"]:hover,
.rw-document.rw-article--book .rw-article__content a[href*="/user/login/hid"]:focus,
.rw-document.rw-article--book .rw-article__content a[href*="/user/login/hid"]:active {
.rw-document.rw-article--book .rw-article__content a[href^="/user/login/"]:hover,
.rw-document.rw-article--book .rw-article__content a[href^="/user/login/"]:focus,
.rw-document.rw-article--book .rw-article__content a[href^="/user/login/"]:active {
background: var(--cd-reliefweb-brand-red--dark);
}