Skip to content

Commit

Permalink
Merge pull request #1813 from danskernesdigitalebibliotek/DDFHER-150_…
Browse files Browse the repository at this point in the history
…user-logging

Logging custom DDF events, such as updates to users. DDFHER-150
  • Loading branch information
rasben authored Dec 3, 2024
2 parents c1d8920 + ccd67c1 commit 48ab941
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/sync/core.extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ module:
dpl_library_token: 0
dpl_link: 0
dpl_loans: 0
dpl_logging: 0
dpl_login: 0
dpl_mail: 0
dpl_mapp: 0
Expand Down
6 changes: 6 additions & 0 deletions web/modules/custom/dpl_logging/dpl_logging.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
name: DPL logging
description: Logging custom DDF events, such as updates to users.
package: DPL
type: module
core_version_requirement: ^10 || ^11
112 changes: 112 additions & 0 deletions web/modules/custom/dpl_logging/dpl_logging.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

use Drupal\Component\Utility\DiffArray;
use Drupal\user\Entity\User;

/**
* Implements hook_ENTITY_TYPE_presave().
*
* When updating a user, we want to log the changes done - this is part of
* a security policy by DDF.
* For most fields, the old and new value gets logged, but others may be
* ignored, or declared on a meta-level (such as password).
*/
function dpl_logging_user_presave(User $user): void {
$original_user = $user->original;

if (!($original_user instanceof User)) {
return;
}

$original_values = $original_user->toArray();
$values = $user->toArray();
$updates = DiffArray::diffAssocRecursive($values, $original_values);

// Some fields are so meta that we do not need to log their changes.
$ignored_updates = ['changed', 'metatag', 'field_password_expiration'];
$diffs = [];

foreach ($updates as $key => $value) {
if (in_array($key, $ignored_updates)) {
continue;
}

if ($key === 'roles') {
$original_roles = $original_user->getRoles();
$new_roles = $user->getRoles();

// This results in the machine names of the roles.
// We could also do a look up, to find the translated labels also,
// but it is probably overkill for what this log will be used for.
$added_roles = array_diff($new_roles, $original_roles);
$removed_roles = array_diff($original_roles, $new_roles);

if (!empty($added_roles)) {
$diffs['roles_added'] = t(
'New roles added to user: @roles',
['@roles' => implode(', ', $added_roles)],
['context' => 'DPL logging']
)->render();
}

if (!empty($removed_roles)) {
$diffs['roles_removed'] = t(
'Old roles removed from user: @roles',
['@roles' => implode(', ', $removed_roles)],
['context' => 'DPL logging']
)->render();
}

continue;
}

if ($key === 'pass') {
// The password always shows up, but it does not always have an actual
// value inserted - in that case, we'll filter it out.
if (!empty(array_filter($value[0]))) {
// We don't want to log the actual password change. It is useless as
// it is hashed regardless.
$diffs[$key] = t(
'Password was updated',
[],
['context' => 'DPL logging']
)->render();
}

continue;
}

// Getting human-readable label, with machine name as fallback.
$label = $user->getFieldDefinition($key)?->getLabel() ?? $key;

// Make sure the label is a string. Sometimes getLabel returns translation.
$label = (string) $label;

$original_value = $original_values[$key] ?? NULL;

$diffs[$key] = t(
'@label (@key): @original_value changed to @value',
[
'@label' => $label,
'@key' => $key,
'@original_value' => $original_value[0]['value'],
'@value' => $value[0]['value'] ?? NULL,
],
['context' => 'DPL logging']
)->render();
}

if (empty($diffs)) {
return;
}

$values_string = implode("\r\n | ", $diffs);

$logger = \Drupal::logger('dpl_logging');

$logger->notice('User @name (@id) has been updated with the following values: @values', [
'@name' => $user->getAccountName(),
'@id' => $user->id(),
'@values' => $values_string,
]);
}
7 changes: 7 additions & 0 deletions web/modules/custom/dpl_update/dpl_update.install
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,10 @@ function dpl_update_update_10027(): string {
function dpl_update_update_10028(): string {
return _dpl_update_uninstall_modules(['config_filter']);
}

/**
* Installing dpl_logging.
*/
function dpl_update_update_10029(): string {
return _dpl_update_install_modules(['dpl_logging']);
}

0 comments on commit 48ab941

Please sign in to comment.