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

Feature/os2form audit #126

Closed
wants to merge 8 commits into from
Closed
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ before starting to add changes. Use example [placed in the end of the page](#exa

## [Unreleased]

- Added new audit logging module (os2form_audit).

## [3.15.7] 2024-08-15

- [#123](https://github.com/OS2Forms/os2forms/pull/123)
Expand Down Expand Up @@ -69,6 +71,7 @@ before starting to add changes. Use example [placed in the end of the page](#exa
Fix coding standards.
- [#102](https://github.com/OS2Forms/os2forms/pull/102)
Fix array access with `purge_days` configuration.
- Added digital post test command.

## [3.14.1] 2024-01-16

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
},
"require": {
"php": "^8.1",
"ext-curl": "*",
"ext-dom": "*",
"ext-soap": "*",
"cweagans/composer-patches": "^1.6.5",
Expand Down
42 changes: 42 additions & 0 deletions modules/os2forms_audit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# OS2Form Audit Module

OS2Form Audit is a Drupal module that helps track changes and perform audit on
OS2Form events.

## Requirements
-
- PHP 8.1 or higher
- Drupal 8 or 9
- Composer for managing PHP dependencies

## Features
-
- Detailed audit log entries.
- Support for all OS2Form entity types.
- Easily extendable for custom use case.

## Installation

### Composer

### Drush

### Admin UI

Alternatively, you can enable this module via Drupal admin UI by visiting the
extent page (`/admin/modules`).

## Configuration

Navigate to `/admin/config/os2form/audit` to configure the module.

Some additional (brief) information on Usage, Extending/Overriding, and
Maintainers could go here.

## Usage

Describe how to use this module after installation.

## Extending and Overriding

Describe how to extend or override this module's functionality.
4 changes: 4 additions & 0 deletions modules/os2forms_audit/os2forms_audit.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: OS2Forms Audit
type: module
description: 'OS2Forms Audit Module (log all events to external service)'
core_version_requirement: ^8 || ^9 || ^10
5 changes: 5 additions & 0 deletions modules/os2forms_audit/os2forms_audit.links.menu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
os2forms_audit.admin_settings:
title: 'OS2Forms Audit settings'
parent: system.admin_config_system
description: 'Settings for the OS2Forms Audit module'
route_name: os2forms_audit.plugin_settings_local_tasks
5 changes: 5 additions & 0 deletions modules/os2forms_audit/os2forms_audit.links.task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
os2forms_audit.plugin_settings_tasks:
title: 'Dynamic tasks'
route_name: os2forms_audit.plugin_settings_local_tasks
base_route: os2forms_audit.plugin_settings_local_tasks
deriver: Drupal\os2forms_audit\Plugin\Derivative\LocalTask
6 changes: 6 additions & 0 deletions modules/os2forms_audit/os2forms_audit.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php

/**
* @file
* The module file required by all modules.
*/
8 changes: 8 additions & 0 deletions modules/os2forms_audit/os2forms_audit.routing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
os2forms_audit.plugin_settings_local_tasks:
path: '/admin/config/os2forms_audit/settings/{type}'
defaults:
_controller: '\Drupal\os2forms_audit\Controller\LocalTasksController::dynamicTasks'
_title: 'Dynamic tasks'
type: ''
requirements:
_permission: 'administer site'
14 changes: 14 additions & 0 deletions modules/os2forms_audit/os2forms_audit.services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
services:
plugin.manager.os2forms_audit_logger:
class: Drupal\os2forms_audit\Plugin\LoggerManager
parent: default_plugin_manager

os2forms_audit.logger:
class: Drupal\os2forms_audit\Service\Logger
arguments: ['@plugin.manager.os2forms_audit_logger', '@config.factory']

os2forms_audit.commands:
class: Drupal\os2forms_audit\Commands\AuditLogDrushCommands
arguments: ['@os2forms_audit.logger']
tags:
- { name: drush.command }
44 changes: 44 additions & 0 deletions modules/os2forms_audit/src/Annotation/AuditLoggerProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Drupal\os2forms_audit\Annotation;

use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;

/**
* Defines a AuditLoggerProvider annotation object.
*
* @see plugin_api
*
* @Annotation
*/
class AuditLoggerProvider extends Plugin {

/**
* The plugin ID.
*
* @var string
*/
public string $id;

/**
* The human-readable name of the consent storage.
*
* @var \Drupal\Core\Annotation\Translation
*
* @ingroup plugin_translatable
*/
public Translation $title;

/**
* A brief description of the consent storage.
*
* This will be shown when adding or configuring this consent storage.
*
* @var \Drupal\Core\Annotation\Translation|string
*
* @ingroup plugin_translatable
*/
public Translation|string $description = '';

}
44 changes: 44 additions & 0 deletions modules/os2forms_audit/src/Commands/AuditLogDrushCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Drupal\os2forms_audit\Commands;

use Drupal\os2forms_audit\Service\Logger;
use Drush\Commands\DrushCommands;

/**
* Simple command to send log message into audit log.
*/
class AuditLogDrushCommands extends DrushCommands {

/**
* Os2FormsAuditDrushCommands constructor.
*
* @param \Drupal\os2forms_audit\Service\Logger $auditLogger
* Audit logger service.
*/
public function __construct(
protected readonly Logger $auditLogger,
) {
parent::__construct();
}

/**
* Log a test message to the os2forms_audit logger.
*
* @param string $log_message
* Message to be logged.
*
* @command os2forms_audit:log
* @usage os2forms_audit:log 'This is a test message.'
* Logs 'This is a test message.' to the os2forms_audit logger.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
public function logMessage(string $log_message = ''): void {
if (empty($log_message)) {
throw new \Exception('Log message cannot be empty.');
}
$this->auditLogger->log('test', time(), $log_message, ['from' => 'drush']);
}

}
58 changes: 58 additions & 0 deletions modules/os2forms_audit/src/Controller/LocalTasksController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Drupal\os2forms_audit\Controller;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormBuilderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Class to handle local taks tabs callbacks.
*/
class LocalTasksController extends ControllerBase {

/**
* Default constructor.
*
* @param \Drupal\Core\Form\FormBuilderInterface $formBuilder
* Form builder object.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* CConfiguration factory.
*/
public function __construct(
FormBuilderInterface $formBuilder,
ConfigFactoryInterface $configFactory,
) {
$this->formBuilder = $formBuilder;
$this->configFactory = $configFactory;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): LocalTasksController|static {
return new static(
$container->get('form_builder'),
$container->get('config.factory'),
);
}

/**
* Get dynamic tasks.
*
* @param string|null $type
* The type of form to retrieve. Defaults to NULL.
*
* @return array
* An array containing the form definition.
*/
public function dynamicTasks(string $type = NULL): array {
if (empty($type)) {
return $this->formBuilder->getForm('\Drupal\os2forms_audit\Form\SettingsForm');
}

return $this->formBuilder->getForm('\Drupal\os2forms_audit\Form\PluginSettingsForm', $type);
}

}
123 changes: 123 additions & 0 deletions modules/os2forms_audit/src/Form/PluginSettingsForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

namespace Drupal\os2forms_audit\Form;

/**
* @file
* Abstract class for PluginSettingsForm implementation.
*/

use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\os2web_datalookup\Form\PluginSettingsFormInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Class for PluginSettingsForm implementation.
*/
class PluginSettingsForm extends ConfigFormBase implements PluginSettingsFormInterface {

/**
* The manager to be used for instantiating plugins.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected PluginManagerInterface $manager;

/**
* {@inheritdoc}
*/
public function __construct(
ConfigFactoryInterface $config_factory,
PluginManagerInterface $manager,
) {
parent::__construct($config_factory);
$this->manager = $manager;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): static {
return new static(
$container->get('config.factory'),
$container->get('plugin.manager.os2forms_audit_logger')
);
}

/**
* {@inheritdoc}
*/
public static function getConfigName(): string {
return 'os2forms_audit.plugin_settings';
}

/**
* {@inheritdoc}
*/
protected function getEditableConfigNames(): array {
return [$this->getConfigName()];
}

/**
* {@inheritdoc}
*/
public function getFormId(): string {
return $this->getConfigName() . '_settings_form';
}

/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$plugin_id = $form_state->getBuildInfo()['args'][0];
$instance = $this->getPluginInstance($plugin_id);
$form = $instance->buildConfigurationForm($form, $form_state);

return parent::buildForm($form, $form_state);
}

/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
$plugin_id = $form_state->getBuildInfo()['args'][0];
$instance = $this->getPluginInstance($plugin_id);
$instance->validateConfigurationForm($form, $form_state);
}

/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$plugin_id = $form_state->getBuildInfo()['args'][0];
$instance = $this->getPluginInstance($plugin_id);
$instance->submitConfigurationForm($form, $form_state);

$config = $this->config($this->getConfigName());
$config->set($plugin_id, $instance->getConfiguration());
$config->save();

parent::submitForm($form, $form_state);
}

/**
* Returns plugin instance for a given plugin id.
*
* @param string $plugin_id
* The plugin_id for the plugin instance.
*
* @return object
* Plugin instance.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
public function getPluginInstance(string $plugin_id): object {
$configuration = $this->config($this->getConfigName())->get($plugin_id);

return $this->manager->createInstance($plugin_id, $configuration ?? []);
}

}
Loading
Loading