Skip to content

Commit

Permalink
EWPP-4912: Manual roles tracking.
Browse files Browse the repository at this point in the history
  • Loading branch information
upchuk committed Nov 12, 2024
1 parent 7a39947 commit 6e40479
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 0 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
"autoload-dev": {
"psr-4": {
"Drupal\\Tests\\oe_authentication\\": "./tests/",
"Drupal\\Tests\\oe_authentication_user_fields\\": "./modules/oe_authentication_user_fields/tests/src",
"Drupal\\Tests\\oe_authentication_corporate_roles\\": "./modules/oe_authentication_corporate_roles/tests/src",
"Drupal\\Tests\\cas_mock_server\\": "./build/modules/contrib/cas_mock_server/tests/src/"
}
},
Expand Down
18 changes: 18 additions & 0 deletions modules/oe_authentication_corporate_roles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# OpenEuropa Authentication Corporate Roles

This submodule allows the configuration of mappings between user departments/LDAP groups and roles, in view of automatically assigning those roles to the users when they log in.

## Requirements

This module requires the following modules:
- [OE Authentication user fields](modules/user_authentication_user_fields)

## Installation

This module comes with a new entity reference field on the User entity called "Manual roles". The purpose of this field is to store on the user the roles which have been granted to the user "manually" (as opposed to automatically
via the logic of this module).

When installing the module, you will need to create an update path that goes through all the users on your site and sets the value of the "Manual roles" field to whatever roles the users have (apart from the default authenticated role).
Depending on the size of your site, you may want to batch this operation.

It is important to have these roles referenced so that when roles are unassigned automatically, the ones that have been assigned manually are not removed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
langcode: en
status: true
dependencies:
config:
- field.storage.user.oe_manual_roles
module:
- user
third_party_settings: { }
id: user.user.oe_manual_roles
field_name: oe_manual_roles
entity_type: user
bundle: user
label: 'Manual roles'
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:user_role'
handler_settings:
target_bundles: null
auto_create: false
field_type: entity_reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
langcode: en
status: true
dependencies:
module:
- user
id: user.oe_manual_roles
field_name: oe_manual_roles
entity_type: user
type: entity_reference
settings:
target_type: user_role
module: core
locked: false
cardinality: -1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: OE Authentication Corporate Roles
description: Automatic corporate roles assigned to users
package: OpenEuropa
type: module
core_version_requirement: ^10
dependencies:
- cas:cas
- oe_authentication:oe_authentication
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/**
* @file
* OpenEuropa Authentication Corporate Roles module.
*/

declare(strict_types=1);

use Drupal\user\UserInterface;

/**
* Implements hook_ENTITY_TYPE_presave().
*
* If we are not saving the user as part of automatic corporate role
* assignment, set the roles on the manual roles field. But only do so if there
* is a change on the roles.
*/
function oe_authentication_corporate_roles_user_presave(UserInterface $user) {
if (isset($user->automatic_corporate_roles)) {
return;
}

$original = $user->original;
if (!$original instanceof UserInterface) {
// It means the user is new so we can set the manual roles.
$user->set('oe_manual_roles', $user->getRoles(TRUE));
return;
}

// Check if there is a difference between the original roles and the new ones.
$original_roles = $original->getRoles(TRUE);
$new_roles = $user->getRoles(TRUE);

if ($original_roles !== $new_roles) {
$user->set('oe_manual_roles', $user->getRoles(TRUE));
}

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

declare(strict_types=1);

namespace Drupal\Tests\oe_authentication_corporate_roles\Kernel;

use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;

/**
* Tests the corporate roles.
*/
class CorporateRolesTest extends KernelTestBase {

/**
* {@inheritdoc}
*/
protected static $modules = [
'oe_authentication',
'oe_authentication_corporate_roles',
'system',
'user',
'field',
];

/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installConfig(['system', 'user']);
$this->installEntitySchema('user');
$this->installSchema('system', ['sequences']);
$this->installConfig(['oe_authentication_corporate_roles']);
}

/**
* Tests manual roles.
*/
public function testManualRoleAssignment(): void {
$role_one = Role::create(['id' => 'test_role_one', 'label' => 'Test role on']);
$role_one->save();

$role_two = Role::create(['id' => 'test_role_two', 'label' => 'Test role two']);
$role_two->save();

$user = User::create([
'name' => 'test_user',
'roles' => [$role_one->id()],
]);
$user->save();

$user = User::load($user->id());
$this->assertEquals(['test_role_one'], array_column($user->get('oe_manual_roles')->getValue(), 'target_id'));

// Remove the role.
$user->removeRole('test_role_one');
$user->save();
$user = User::load($user->id());
$this->assertEmpty($user->get('oe_manual_roles')->getValue());

// Assign back the role but mimic it was done automatically.
$user->addRole('test_role_one');
$user->automatic_corporate_roles = TRUE;
$user->save();
$user = User::load($user->id());
$this->assertEmpty($user->get('oe_manual_roles')->getValue());

// Save the user again, but this time don't change the roles. Assert that
// because we didn't make a change to the user roles, the existing roles
// didn't get added to the list of manual roles.
$user->save();
$user = User::load($user->id());
$this->assertEmpty($user->get('oe_manual_roles')->getValue());

// Now add another role and assert it gets added to the manual list.
$user->addRole('test_role_two');
$user->save();
$user = User::load($user->id());
// Both roles are added to the manual list, denoting that the user is aware
// of adding the roles.
$this->assertEquals(['test_role_one', 'test_role_two'], array_column($user->get('oe_manual_roles')->getValue(), 'target_id'));
}

}

0 comments on commit 6e40479

Please sign in to comment.