我们开发nl/audit-scaffold

Symfony 和 Doctrine 中创建审计日志的脚手架

dev-main 2024-09-09 11:00 UTC

This package is auto-updated.

Last update: 2024-09-09 11:00:21 UTC


README

为您的 Symfony 应用程序中的审计日志提供样板/脚手架库,可持久化到您的数据库层。

动机

审计日志是记录应用程序中活动的过程,包括额外的上下文,例如:负责的用户/参与者、应用程序的入口点、被操作的主题以及该活动的任何其他相关领域逻辑。一系列的审计日志称为审计跟踪,因为它显示了应用程序中活动的连续、按时间顺序的记录。

审计日志回答了一个简单的问题:谁做了什么,对什么,何时何地?

如果您项目更关注数据变化的历史记录,而不是动作或活动,或许可以尝试使用 可记录的行为,这是通过 Doctrine 扩展 为您的实体和/或文档提供的。

入门指南

需求

  • Symfony 7
  • Doctrine 持久层:ORM 或 Mongo ODM。

安装

此项目通过 Composer 安装

composer require "wedevelopnl/audit-scaffold"

限制

此库尽可能为您做很多事情,而无需了解您的应用程序的领域或实现逻辑。

此库可以将其自身连接到 Symfony 的捆绑系统,但它对 Symfony 的配置和容器的任何修改都纯粹是关于您的应用程序可能或可能不工作的假设。

虽然此库提供了可从中扩展的基本实体/文档,以及各种 DTO、枚举和值对象,但您的应用程序必须实现以下内容

  • 单个 实体或文档(包括对您的用户实现的引用、如表/集合名称和索引之类的元数据,以及如果适用则迁移)实现 AuditEntityInterface
  • 服务 容器配置
  • Doctrine 映射配置
  • 为应用程序支持的任何语言提供的 翻译
  • 当然,还有您想在应用程序中审计的 审计类(实现 AuditLogInterface)。

建议您从 AbstractAuditEntityAbstractAuditLog 扩展,这些是为您的方便提供的。

示例用法

有关如何使用此库与 Doctrine ORM 或 Mongo ODM 一起设置的详细说明,请参阅 教程

示例审计日志
<?php declare(strict_types=1);

namespace App\Audit\Account;

use App\Entity\AuditLog as AuditLogEntity;
use App\Entity\User;
use Symfony\Component\Security\Core\User\UserInterface;
use WeDevelop\Audit\AbstractAuditLog;
use WeDevelop\Audit\Entity\AuditEntityInterface;
use WeDevelop\Audit\Entity\Subject;
use WeDevelop\Audit\ValueObject\Context;

final readonly class UserBanned extends AbstractAuditLog
{
    public static function create(
        Context $context,
        User $bannedUser,
        ?\DateTimeInterface $bannedUntil = null,
    ): self {
        return new self($context, Subject::fromObject($bannedUser), new \DateTimeImmutable, [
            'bannedUntil' => $bannedUntil?->format(\DateTimeInterface::RFC3339),
        ]);
    }

    public function createEntity(): AuditEntityInterface
    {
        return AuditLogEntity::fromAuditLog($this);
    }

    public function getMessage(): string
    {
        return 'user.banned';
    }

    public function getParameters(): array
    {
        return [];
    }

    public function getAdditionalInfo(): iterable
    {
        if (is_string($this->data['bannedUntil'] ?? null)) {
            yield 'until' => ['datetime' => $this->data['bannedUntil']];
        } else {
            yield 'indefinitely' => [];
        }
    }
}
示例审计日志
<?php declare(strict_types=1);

use App\Audit\Account\UserBanned;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use WeDevelop\Audit\ValueObject\Context;

class AdminController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $em,
        private readonly TokenStorageInterface $tokenStorage,
    ) {}

    #[Route('/users/{user}/ban', name: 'admin_user_ban')]
    public function banUserAction(Request $request, User $user): Response
    {
        $form = $this->createForm(BanConfirmationForm::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $user->setActive(false);

            $auditLog = UserBanned::create(
                Context::ui($request, $this->tokenStorage->getToken()),
                $user,
            );

            $this->em->persist($user);
            $this->em->persist($auditLog->createEntity());
            $this->em->flush();

            return $this->redirectToRoute('admin_user_view', ['user' => $user->getId()]);
        }

        return $this->render('admin/users/confirm-ban.twig.html', [
            'form' => $form,
        ]);
    }
}

元数据

行为准则

本项目包含并遵守 贡献者公约 作为行为准则。

许可

请参阅此存储库中包含的单独的 许可文件,其中包含完整的 MIT 许可证副本,该项目据此许可。