Skip to content

Commit a70353b

Browse files
committed
Adding options for tracking NemID fields access
1 parent 0a364ba commit a70353b

9 files changed

+116
-33
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
## Module purpose
44

5-
The aim of this module is to provide logging of node access.
5+
The aim of this module is to provide logging of node access and NemID webform fields.
66

77
## How does it work
88

9-
When node is access this is logged by the module.
9+
When node or NemID webform field is access this is logged by the module.
1010

1111
Logs are stored in two places: database + files.
1212

@@ -18,9 +18,12 @@ It is **required** that this directory exists and is writable.
1818

1919
## Additional settings
2020
Settings are available under `admin/config/content/os2web-borgerdk`
21-
* **Node types to keep log of** - Select node type to keep logs of.
21+
* **Node types access to keep log of** - Select node type to keep logs of.
22+
* **Webform fields access to keep log of** - Select webform fields type to keep logs of.
23+
* **Log anonymous user actions** - If anonymous user actions are being logged
2224
* **Store database logs for this period** - Database logs will be stored for the selected number of days, after that they will be automatically deleted (cleanup is done daily).
2325
* **Store log files for this period** - Log file will be stored for the selected number of days, after that they will be automatically deleted
26+
* **Store log files directory** - Logs will be saved in this path.
2427

2528
## Install
2629

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "os2web/os2web_logging",
33
"type": "drupal-module",
4-
"description": "Logs node access for selected content type access",
4+
"description": "Logs access selected content type or webform elements",
55
"minimum-stability": "dev",
66
"prefer-stable": true,
77
"license": "EUPL-1.2",

os2web_logging.info.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: 'OS2Web logging'
2-
description: 'Logs node access for selected content type access.'
2+
description: 'Logs access selected content type or webform elements.'
33
type: module
44
package: 'OS2Web'
55
core: 8.x

os2web_logging.module

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
*/
77

88
use Drupal\Component\Datetime\DateTimePlus;
9+
use Drupal\Core\Access\AccessResult;
910
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
1011
use Drupal\Core\Entity\EntityInterface;
1112
use Drupal\Core\Form\FormStateInterface;
13+
use Drupal\Core\Session\AccountInterface;
1214
use Drupal\os2web_logging\Controller\LoggingController;
1315
use Drupal\os2web_logging\Form\SettingsForm;
1416

@@ -34,12 +36,47 @@ function os2web_logging_node_view(array &$build, EntityInterface $entity, Entity
3436
if (in_array($entity->getType(), $node_types, TRUE)) {
3537

3638
// Log entry.
37-
$logger = \Drupal::logger('os2web_logging.node_access');
39+
$logger = \Drupal::logger('os2web_logging.access_log');
3840
$logger->info('Node loaded', ['sid' => $entity->id()]);
3941
}
4042
}
4143
}
4244

45+
/**
46+
* Implements hook_webform_element_access().
47+
*/
48+
function os2web_logging_webform_element_access($operation, array &$element, AccountInterface $account = NULL, array $context = []) {
49+
// Ignoring requests from CLI.
50+
if (PHP_SAPI === 'cli') {
51+
return AccessResult::neutral();
52+
}
53+
54+
// Ignoring if operation is not view or update.
55+
if ($operation != 'view' && $operation != 'update') {
56+
return AccessResult::neutral();
57+
}
58+
59+
$config = \Drupal::config(SettingsForm::$configName);
60+
61+
// Ignore anonymous user.
62+
$logAnonymUser = $config->get('log_anonymous_user');
63+
if (!$logAnonymUser && \Drupal::currentUser()->isAnonymous()) {
64+
return AccessResult::neutral();
65+
}
66+
67+
// Filter on element type.
68+
if ($webform_elements = $config->get('logged_webform_elements')) {
69+
if (in_array($element['#type'], $webform_elements, TRUE)) {
70+
// Log entry.
71+
$logger = \Drupal::logger('os2web_logging.access_log');
72+
$logger->info('CPR accessed');
73+
}
74+
}
75+
76+
// As we are hooking into access, we make sure the return value is not altered.
77+
return AccessResult::neutral();
78+
}
79+
4380
/**
4481
* Implements hook_form_FORM_ID_alter().
4582
*/

os2web_logging.services.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ parameters:
44
default: ['os2web_logging_watchdog']
55
# Log php channel to web server's error log.
66
php: ['error_log']
7-
os2web_logging.node_access:
8-
handlers: ['os2web_logging_node_access_file', 'drupal.os2web_logging_node_access_dblog']
7+
os2web_logging.access_log:
8+
handlers: ['os2web_logging_access_log_file', 'drupal.os2web_logging_access_log_dblog']
99
formatter: 'json'
1010

1111
services:
1212
monolog.handler.os2web_logging_watchdog:
1313
class: Monolog\Handler\RotatingFileHandler
1414
arguments: ['../logs/os2web_logging_watchdog.log', 60, 'monolog.level.debug']
15-
monolog.handler.os2web_logging_node_access_file:
15+
monolog.handler.os2web_logging_access_log_file:
1616
class: Monolog\Handler\RotatingFileHandler
17-
arguments: ['../logs/os2web_logging_node_access.log', 60, 'monolog.level.debug']
18-
logger.os2web_logging_node_access_dblog:
19-
class: Drupal\os2web_logging\Logger\NodeAccessDbLog
17+
arguments: ['../logs/os2web_logging_access_log.log', 60, 'monolog.level.debug']
18+
logger.os2web_logging_access_log_dblog:
19+
class: Drupal\os2web_logging\Logger\AccessLogsDbLog
2020
tags:
2121
- { name: logger }

src/Controller/LoggingController.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,29 @@ public static function getCheckedRequirements() {
125125
$requirements['error'][] = $req;
126126
}
127127

128-
// 3. Number of days to store DB logs:
128+
// 3. NemID fields.
129+
$moduleHandler = \Drupal::service('module_handler');
130+
if ($moduleHandler->moduleExists('os2forms_nemid')) {
131+
$webform_elements = $config->get('logged_webform_elements');
132+
$webform_elements = array_filter($webform_elements);
133+
134+
$webform_elements_build = [
135+
'#theme' => 'item_list',
136+
'#title' => t('NemID fields type'),
137+
'#items' => $webform_elements,
138+
];
139+
$webform_elements_rendered = \Drupal::service('renderer')->renderPlain($webform_elements_build);
140+
141+
$req = [
142+
'title' => t('Selected NemID fields'),
143+
'description' => t('These NemID fields access will be logged'),
144+
];
145+
146+
$req['value'] = !empty($webform_elements) ? $webform_elements_rendered : t('Empty');
147+
$requirements['checked'][] = $req;
148+
}
149+
150+
// 4. Number of days to store DB logs:
129151
$dblogStorePeriod = $config->get('dblogs_store_period');
130152

131153
$req = [
@@ -142,7 +164,7 @@ public static function getCheckedRequirements() {
142164
$requirements['error'][] = $req;
143165
}
144166

145-
// 3. Number of days to store file logs.
167+
// 5. Number of days to store file logs.
146168
$fileLogsStorePeriod = $config->get('files_store_period');
147169

148170
$req = [
@@ -159,8 +181,8 @@ public static function getCheckedRequirements() {
159181
$requirements['error'][] = $req;
160182
}
161183

162-
// 4. File directory is writable.
163-
$logger = \Drupal::service('monolog.handler.os2web_logging_node_access_file');
184+
// 6. File directory is writable.
185+
$logger = \Drupal::service('monolog.handler.os2web_logging_access_log_file');
164186
$logsDir = dirname($logger->getUrl());
165187
$exists = \Drupal::service('file_system')->prepareDirectory($logsDir, FileSystemInterface::MODIFY_PERMISSIONS);
166188

src/Form/SettingsForm.php

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,41 @@ public function buildForm(array $form, FormStateInterface $form_state) {
5454
$node_types = NodeType::loadMultiple();
5555

5656
// Node types.
57-
$options = [];
57+
$nodeTypeOptions = [];
5858
foreach ($node_types as $node_type) {
59-
$options[$node_type->id()] = $node_type->label();
59+
$nodeTypeOptions[$node_type->id()] = $node_type->label();
6060
}
61-
62-
asort($options);
61+
asort($nodeTypeOptions);
6362

6463
$form['logged_node_types'] = [
6564
'#type' => 'checkboxes',
66-
'#title' => $this->t('Node types to keep log of:'),
67-
'#options' => $options,
65+
'#title' => $this->t('Node types access to keep log of:'),
66+
'#options' => $nodeTypeOptions,
6867
'#default_value' => $config->get('logged_node_types') ? $config->get('logged_node_types') : [],
6968
];
7069

70+
// Webform elements.
71+
$moduleHandler = \Drupal::service('module_handler');
72+
if ($moduleHandler->moduleExists('os2forms_nemid')) {
73+
$webformElementOptions = [];
74+
/** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
75+
$element_manager = \Drupal::service('plugin.manager.webform.element');
76+
$webformElements = $element_manager->getDefinitions();
77+
foreach ($webformElements as $el) {
78+
if ($el['provider'] == 'os2forms_nemid') {
79+
$webformElementOptions[$el['id']] = $el['label'];
80+
}
81+
}
82+
asort($webformElementOptions);
83+
84+
$form['logged_webform_elements'] = [
85+
'#type' => 'checkboxes',
86+
'#title' => $this->t('Webform fields access to keep log of:'),
87+
'#options' => $webformElementOptions,
88+
'#default_value' => $config->get('logged_webform_elements') ? $config->get('logged_webform_elements') : [],
89+
];
90+
}
91+
7192
$form['log_anonymous_user'] = [
7293
'#type' => 'checkbox',
7394
'#title' => $this->t('Log anonymous user actions'),
@@ -111,7 +132,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
111132
$form['file_logs_detail']['files_log_path'] = [
112133
'#type' => 'textfield',
113134
'#title' => $this->t('Store log files directory'),
114-
'#description' => $this->t('Log file will be stored for the selected number of days, after that they will be automatically deleted'),
135+
'#description' => $this->t('Logs will be saved in this path'),
115136
'#default_value' => $config->get('files_log_path') ? $config->get('files_log_path') : '../logs',
116137
];
117138

@@ -121,19 +142,19 @@ public function buildForm(array $form, FormStateInterface $form_state) {
121142
->t('Logs import'),
122143
];
123144

124-
$options = [];
145+
$nodeTypeOptions = [];
125146
if ($config->get('files_log_path')) {
126-
$storedLogFiles = \Drupal::service('file_system')->scanDirectory($config->get('files_log_path'), '/os2web_logging_node_access-\d{4}-\d{2}-\d{2}\.(log|gz)/');
147+
$storedLogFiles = \Drupal::service('file_system')->scanDirectory($config->get('files_log_path'), '/os2web_logging_access_log-\d{4}-\d{2}-\d{2}\.(log|gz)/');
127148

128149
foreach ($storedLogFiles as $file) {
129-
$options[$file->uri] = $file->filename;
150+
$nodeTypeOptions[$file->uri] = $file->filename;
130151
}
131-
arsort($options);
152+
arsort($nodeTypeOptions);
132153
}
133154

134155
$form['logs_import_file_detail']['logs_import_files_select'] = [
135156
'#type' => 'checkboxes',
136-
'#options' => $options,
157+
'#options' => $nodeTypeOptions,
137158
'#title' => $this->t('Import from existing files'),
138159
'#description' => $this->t('Archived log files will be automatically extracted'),
139160
];

src/Logger/NodeAccessDbLog.php renamed to src/Logger/AccessLogsDbLog.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
use Psr\Log\LoggerInterface;
88

99
/**
10-
* Logs events in the watchdog database table.
10+
* Logs events in the database table.
1111
*/
12-
class NodeAccessDbLog implements LoggerInterface {
12+
class AccessLogsDbLog implements LoggerInterface {
1313
use RfcLoggerTrait;
1414

1515
/**

src/Os2webLoggingServiceProvider.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Drupal\os2web_logging\Form\SettingsForm;
88

99
/**
10-
* Overrides the monolog.handler.os2web_logging_node_access_file service.
10+
* Overrides the monolog.handler.os2web_logging_access_log_file service.
1111
*/
1212
class Os2webLoggingServiceProvider extends ServiceProviderBase {
1313

@@ -24,12 +24,12 @@ public function alter(ContainerBuilder $container) {
2424

2525
$config = \Drupal::config(SettingsForm::$configName);
2626

27-
$logger = $container->getDefinition('monolog.handler.os2web_logging_node_access_file');
27+
$logger = $container->getDefinition('monolog.handler.os2web_logging_access_log_file');
2828

2929
// Updating store path for logger.
3030
$logs_path = $config->get('files_log_path');
3131
if (!empty($logs_path)) {
32-
$logs_path .= '/os2web_logging_node_access.log';
32+
$logs_path .= '/os2web_logging_access_log.log';
3333
$logger->replaceArgument(0, $logs_path);
3434
}
3535

0 commit comments

Comments
 (0)