mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-20 17:15:51 +02:00
Added an option to enforce log comments for certain actions
This implements issue #220
This commit is contained in:
parent
5f2408b791
commit
29af14f588
14 changed files with 179 additions and 11 deletions
|
@ -26,7 +26,7 @@
|
|||
|
||||
# Pass the configuration from the docker env to the PHP environment (here you should list all .env options)
|
||||
PassEnv APP_ENV APP_DEBUG APP_SECRET
|
||||
PassEnv DATABASE_URL
|
||||
PassEnv DATABASE_URL ENFORCE_CHANGE_COMMENTS_FOR
|
||||
PassEnv DEFAULT_LANG DEFAULT_TIMEZONE BASE_CURRENCY INSTANCE_NAME ALLOW_ATTACHMENT_DOWNLOADS USE_GRAVATAR MAX_ATTACHMENT_FILE_SIZE DEFAULT_URI
|
||||
PassEnv MAILER_DSN ALLOW_EMAIL_PW_RESET EMAIL_SENDER_EMAIL EMAIL_SENDER_NAME
|
||||
PassEnv HISTORY_SAVE_CHANGED_FIELDS HISTORY_SAVE_CHANGED_DATA HISTORY_SAVE_REMOVED_DATA
|
||||
|
|
5
.env
5
.env
|
@ -39,6 +39,11 @@ MAX_ATTACHMENT_FILE_SIZE="100M"
|
|||
# This must end with a slash!
|
||||
DEFAULT_URI="https://partdb.changeme.invalid/"
|
||||
|
||||
# With this option you can configure, where users are enforced to give a change reason, which will be logged
|
||||
# This is a comma separated list of values, see documentation for available values
|
||||
# Leave this empty, to make all change reasons optional
|
||||
ENFORCE_CHANGE_COMMENTS_FOR=""
|
||||
|
||||
###################################################################################
|
||||
# Email settings
|
||||
###################################################################################
|
||||
|
|
|
@ -12,6 +12,7 @@ parameters:
|
|||
partdb.default_currency: '%env(string:BASE_CURRENCY)%' # The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country
|
||||
partdb.global_theme: '' # The theme to use globally (see public/build/themes/ for choices, use name without .css). Set to '' for default bootstrap theme
|
||||
partdb.locale_menu: ['en', 'de', 'fr', 'ru', 'ja'] # The languages that are shown in user drop down menu
|
||||
partdb.enforce_change_comments_for: '%env(csv:ENFORCE_CHANGE_COMMENTS_FOR)%' # The actions for which a change comment is required (e.g. "part_edit", "part_create", etc.). If this is empty, change comments are not required at all.
|
||||
|
||||
partdb.default_uri: '%env(string:DEFAULT_URI)%' # The default URI to use for the Part-DB instance (e.g. https://part-db.example.com/). This is used for generating links in emails
|
||||
|
||||
|
@ -105,6 +106,8 @@ parameters:
|
|||
env(USE_GRAVATAR): '0'
|
||||
env(MAX_ATTACHMENT_FILE_SIZE): '100M'
|
||||
|
||||
env(ENFORCE_CHANGE_COMMENTS_FOR): ''
|
||||
|
||||
env(ERROR_PAGE_ADMIN_EMAIL): ''
|
||||
env(ERROR_PAGE_SHOW_HELP): 1
|
||||
|
||||
|
|
|
@ -102,6 +102,10 @@ services:
|
|||
event: 'Symfony\Component\Security\Http\Event\LogoutEvent'
|
||||
dispatcher: security.event_dispatcher.main
|
||||
|
||||
App\Services\LogSystem\EventCommentNeededHelper:
|
||||
arguments:
|
||||
$enforce_change_comments_for: '%partdb.enforce_change_comments_for%'
|
||||
|
||||
####################################################################################################################
|
||||
# Attachment system
|
||||
####################################################################################################################
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace App\Form\AdminPages;
|
|||
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Services\Attachments\FileTypeFilterTools;
|
||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
@ -33,10 +34,10 @@ class AttachmentTypeAdminForm extends BaseEntityAdminForm
|
|||
{
|
||||
protected FileTypeFilterTools $filterTools;
|
||||
|
||||
public function __construct(Security $security, FileTypeFilterTools $filterTools)
|
||||
public function __construct(Security $security, FileTypeFilterTools $filterTools, EventCommentNeededHelper $eventCommentNeededHelper)
|
||||
{
|
||||
$this->filterTools = $filterTools;
|
||||
parent::__construct($security);
|
||||
parent::__construct($security, $eventCommentNeededHelper);
|
||||
}
|
||||
|
||||
protected function additionalFormElements(FormBuilderInterface $builder, array $options, AbstractNamedDBElement $entity): void
|
||||
|
|
|
@ -31,6 +31,7 @@ use App\Form\ParameterType;
|
|||
use App\Form\Type\MasterPictureAttachmentType;
|
||||
use App\Form\Type\RichTextEditorType;
|
||||
use App\Form\Type\StructuralEntityType;
|
||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||
use FOS\CKEditorBundle\Form\Type\CKEditorType;
|
||||
use function get_class;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
|
@ -46,10 +47,12 @@ use Symfony\Component\Security\Core\Security;
|
|||
class BaseEntityAdminForm extends AbstractType
|
||||
{
|
||||
protected Security $security;
|
||||
protected EventCommentNeededHelper $eventCommentNeededHelper;
|
||||
|
||||
public function __construct(Security $security)
|
||||
public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper)
|
||||
{
|
||||
$this->security = $security;
|
||||
$this->eventCommentNeededHelper = $eventCommentNeededHelper;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
|
@ -141,7 +144,7 @@ class BaseEntityAdminForm extends AbstractType
|
|||
$builder->add('log_comment', TextType::class, [
|
||||
'label' => 'edit.log_comment',
|
||||
'mapped' => false,
|
||||
'required' => false,
|
||||
'required' => $this->eventCommentNeededHelper->isCommentNeeded($is_new ? 'datastructure_create': 'datastructure_edit'),
|
||||
'empty_data' => null,
|
||||
]);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ use App\Form\Type\RichTextEditorType;
|
|||
use App\Form\Type\SIUnitType;
|
||||
use App\Form\Type\StructuralEntityType;
|
||||
use App\Form\WorkaroundCollectionType;
|
||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
|
@ -54,17 +55,20 @@ class PartBaseType extends AbstractType
|
|||
{
|
||||
protected Security $security;
|
||||
protected UrlGeneratorInterface $urlGenerator;
|
||||
protected EventCommentNeededHelper $event_comment_needed_helper;
|
||||
|
||||
public function __construct(Security $security, UrlGeneratorInterface $urlGenerator)
|
||||
public function __construct(Security $security, UrlGeneratorInterface $urlGenerator, EventCommentNeededHelper $event_comment_needed_helper)
|
||||
{
|
||||
$this->security = $security;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->event_comment_needed_helper = $event_comment_needed_helper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
/** @var Part $part */
|
||||
$part = $builder->getData();
|
||||
$new_part = null === $part->getID();
|
||||
|
||||
$status_choices = [
|
||||
'm_status.unknown' => '',
|
||||
|
@ -250,7 +254,7 @@ class PartBaseType extends AbstractType
|
|||
$builder->add('log_comment', TextType::class, [
|
||||
'label' => 'edit.log_comment',
|
||||
'mapped' => false,
|
||||
'required' => false,
|
||||
'required' => $this->event_comment_needed_helper->isCommentNeeded($new_part ? 'part_create' : 'part_edit'),
|
||||
'empty_data' => null,
|
||||
]);
|
||||
|
||||
|
|
60
src/Services/LogSystem/EventCommentNeededHelper.php
Normal file
60
src/Services/LogSystem/EventCommentNeededHelper.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Services\LogSystem;
|
||||
|
||||
/**
|
||||
* This service is used to check if a log change comment is needed for a given operation type.
|
||||
* It is configured using the "enforce_change_comments_for" config parameter.
|
||||
*/
|
||||
class EventCommentNeededHelper
|
||||
{
|
||||
protected array $enforce_change_comments_for;
|
||||
|
||||
public const VALID_OPERATION_TYPES = [
|
||||
'part_edit',
|
||||
'part_create',
|
||||
'part_delete',
|
||||
'part_stock_operation',
|
||||
'datastructure_edit',
|
||||
'datastructure_create',
|
||||
'datastructure_delete',
|
||||
];
|
||||
|
||||
public function __construct(array $enforce_change_comments_for)
|
||||
{
|
||||
$this->enforce_change_comments_for = $enforce_change_comments_for;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a log change comment is needed for the given operation type
|
||||
* @param string $comment_type
|
||||
* @return bool
|
||||
*/
|
||||
public function isCommentNeeded(string $comment_type): bool
|
||||
{
|
||||
//Check if the comment type is valid
|
||||
if (! in_array($comment_type, self::VALID_OPERATION_TYPES, true)) {
|
||||
throw new \InvalidArgumentException('The comment type "'.$comment_type.'" is not valid!');
|
||||
}
|
||||
|
||||
return in_array($comment_type, $this->enforce_change_comments_for, true);
|
||||
}
|
||||
}
|
43
src/Twig/MiscExtension.php
Normal file
43
src/Twig/MiscExtension.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Twig;
|
||||
|
||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
|
||||
final class MiscExtension extends AbstractExtension
|
||||
{
|
||||
private EventCommentNeededHelper $eventCommentNeededHelper;
|
||||
|
||||
public function __construct(EventCommentNeededHelper $eventCommentNeededHelper)
|
||||
{
|
||||
$this->eventCommentNeededHelper = $eventCommentNeededHelper;
|
||||
}
|
||||
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig\TwigFunction('event_comment_needed',
|
||||
fn(string $operation_type) => $this->eventCommentNeededHelper->isCommentNeeded($operation_type)
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -14,7 +14,8 @@
|
|||
</button>
|
||||
<div class="dropdown-menu p-2">
|
||||
<div class="form-group"><label for="delete_log_comment">{% trans %}edit.log_comment{% endtrans %}</label>
|
||||
<input type="text" id="delete_log_comment" name="log_comment" class="form-control">
|
||||
<input type="text" id="delete_log_comment" name="log_comment" class="form-control"
|
||||
{% if event_comment_needed('datastructure_delete') %}required{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -107,7 +107,6 @@
|
|||
{{ form_widget(form.save_and_new, {'attr': {'class': 'dropdown-item'}}) }}
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="p-2">
|
||||
|
||||
{{ form_row(form.log_comment)}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -44,7 +44,9 @@
|
|||
</button>
|
||||
<div class="dropdown-menu p-2">
|
||||
<div class="form-group"><label for="delete_log_comment">{% trans %}edit.log_comment{% endtrans %}</label>
|
||||
<input type="text" id="delete_log_comment" name="log_comment" class="form-control">
|
||||
<input type="text" id="delete_log_comment" name="log_comment" class="form-control"
|
||||
{% if event_comment_needed('part_delete') %}required{% endif %}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
{% trans %}part.info.withdraw_modal.comment{% endtrans %}
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="comment" value="">
|
||||
<input type="text" class="form-control" name="comment" value="" {% if event_comment_needed('part_stock_operation') %}required{% endif %}>
|
||||
<div id="emailHelp" class="form-text">{% trans %}part.info.withdraw_modal.comment.hint{% endtrans %}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
43
tests/Services/LogSystem/EventCommentNeededHelperTest.php
Normal file
43
tests/Services/LogSystem/EventCommentNeededHelperTest.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Services\LogSystem;
|
||||
|
||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class EventCommentNeededHelperTest extends TestCase
|
||||
{
|
||||
public function testIsCommentNeeded()
|
||||
{
|
||||
$service = new EventCommentNeededHelper(['part_edit', 'part_create']);
|
||||
$this->assertTrue($service->isCommentNeeded('part_edit'));
|
||||
$this->assertTrue($service->isCommentNeeded('part_create'));
|
||||
$this->assertFalse($service->isCommentNeeded('part_delete'));
|
||||
$this->assertFalse($service->isCommentNeeded('part_lot_operation'));
|
||||
}
|
||||
|
||||
public function testIsCommentNeededInvalidTypeException()
|
||||
{
|
||||
$service = new EventCommentNeededHelper(['part_edit', 'part_create']);
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$service->isCommentNeeded('this_is_not_valid');
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue