ashallendesign/redactable-models

一个用于轻松编辑模型数据的 Laravel 扩展包。

v0.1.0 2024-07-27 15:16 UTC

This package is auto-updated.

Last update: 2024-08-27 16:03:35 UTC


README

Redactable Models for Laravel

Latest Version on Packagist Total Downloads PHP from Packagist GitHub license

目录

概述

重要

该包仍在开发中。在第一个稳定版本发布之前,可能存在一些错误和 API 变更。

一个 Laravel 扩展包,您可以使用它以一致且简单的方式编辑、混淆或隐藏模型字段。

在构建 Web 应用程序时,您通常会保留旧数据以供审计或报告。但出于数据隐私和安全原因,您可能希望从存储的数据中删除敏感信息。这样,您可以在数据库中保留行,但不会包含敏感信息。

该包允许您定义哪些模型和字段应该被编辑,以及如何编辑。

安装

需求

该包已开发和测试,以满足以下最低要求

  • PHP 8.2
  • Laravel 10

安装包

您可以通过 Composer 安装该包

composer require ashallendesign/redactable-models

使用方法

定义可编辑模型

为了使模型可编辑,您需要将 AshAllenDesign\RedactableModels\Interfaces\Redactable 接口添加到模型中。这将强制执行两个新方法(redactableredactionStrategy),您需要实现。

您的模型可能看起来像这样

use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use Illuminate\Contracts\Database\Eloquent\Builder

class User extends Model implements Redactable
{
    // ...
    
    public function redactable(): Builder
    {
        // ...
    }

    public function redactionStrategy(): RedactionStrategy
    {
        // ...
    }
}

redactable 方法允许您返回一个 Illuminate\Contracts\Database\Eloquent\Builder 的实例,该实例定义了可编辑的模型。

redactionStrategy 方法允许您返回一个 AshAllenDesign\RedactableModels\Interfaces\RedactionStrategy 的实例,该实例定义了字段应该如何编辑。我们将在下面进一步介绍可用的策略。

例如,如果我们想编辑所有超过 30 天的 App\Models\User 模型的 emailname 字段,我们可以这样做

use AshAllenDesign\RedactableModels\Support\Strategies\ReplaceContents;
use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use Illuminate\Contracts\Database\Eloquent\Builder

class User extends Model implements Redactable
{
    // ...
    
    public function redactable(): Builder
    {
        return static::query()->where('created_at', '<', now()->subDays(30));
    }

    public function redactionStrategy(): RedactionStrategy
    {
        return app(ReplaceContents::class)->replaceWith([
            'name' => 'REDACTED',
            'email' => 'redacted@redacted.com',
        ]);
    }
}

model:redact 命令

要自动在模型上编辑字段,您可以使用包的 model:redact 命令,如下所示

php artisan model:redact

这将找到您的应用程序 app/Models 目录中实现 AshAllenDesign\RedactableModels\Interfaces\Redactable 接口的所有模型,并根据定义的编辑策略和查询编辑字段。

您可能想将其设置为在 Laravel 应用程序的计划任务中运行(例如每天运行一次)。

编辑策略

该包提供了一些策略,您可以使用它们编辑字段

ReplaceContents

ReplaceContents 策略允许您用指定的值替换字段的 内容。

例如,如果我们想替换 nameemail 字段,我们可以这样做

use AshAllenDesign\RedactableModels\Support\Strategies\ReplaceContents;
use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements Redactable
{
    // ...

    public function redactionStrategy(): RedactionStrategy
    {
        return app(ReplaceContents::class)->replaceWith([
            'name' => 'REDACTED',
            'email' => 'redacted@redacted.com',
        ]);
    }
}

运行此操作会对模型进行操作,将 name 字段替换为 REDACTED,将 email 字段替换为 redacted@redacted.com

ReplaceContents 策略还允许您使用闭包来定义替换值。如果您想要在红action过程中有更多的控制,这可能会很有用。闭包应该接受模型作为参数,并具有 void 返回类型。

例如,假设您想将 name 字段替换为以 name_ 开头并跟随着其 ID 的格式。您可以这样做

use AshAllenDesign\RedactableModels\Support\Strategies\ReplaceContents;
use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements Redactable
{
    // ...

    public function redactionStrategy(): RedactionStrategy
    {
        return app(ReplaceContents::class)->replaceWith(function (User $user): void {
            $user->name = 'name_'.$user->id;
        });
    }
}

假设我们有一个用户,其 ID 为 123,名字为 John Doe。运行上面的代码会将 name 字段替换为 name_123

HashContents

HashContents 策略允许您对字段的内 容进行 MD5 哈希。

当您仍然想要能够比较被红action的字段,但又不想暴露原始数据时,这可能会很有用。

例如,假设您有一个包含 email 字段的 invitations 表。您可能想知道有多少唯一的电子邮件地址被邀请过,但又不想暴露电子邮件地址本身。您可以这样做

use AshAllenDesign\RedactableModels\Support\Strategies\HashContents;
use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use Illuminate\Database\Eloquent\Model;

class Invitation extends Model implements Redactable
{
    // ...

    public function redactionStrategy(): RedactionStrategy
    {
        return app(HashContents::class))->fields([
            'email',
        ]);
    }
}

MaskContents

MaskContents 策略允许您使用指定的字符来遮罩字段的内 容。

您可以定义用于遮罩的字符,以及要留出的字段起始和结束部分的不遮罩字符数量,如下所示

use AshAllenDesign\RedactableModels\Support\Strategies\MaskContents;
use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements Redactable
{
    // ...

    public function redactionStrategy(): RedactionStrategy
    {
        return app(MaskContents::class)
            ->mask(field: 'name', character: '*', index: 0, length: 4)
            ->mask(field: 'email', character: '-', index: 2, length: 3);
    }
}

在上面的例子中,name 字段将使用 * 遮罩,并且前4个字符将保持未遮罩。email 字段将使用 - 遮罩,并且前2个和最后的3个字符将保持未遮罩。

这意味着如果用户的名字是 "Ash Allen",他们的电子邮件是 "ash@example.com",那么在红action之后,他们的名字将是 "****Allen",他们的电子邮件将是 "as---xample.com"。

自定义编辑策略

尽管该软件包默认包含几个红action策略,但您也可以创建自己的自定义红action策略。

您只需创建一个实现了 AshAllenDesign\RedactableModels\Interfaces\RedactionStrategy 接口的类。此方法强制执行一个接受模型并定义红action逻辑的 apply 方法。

一个自定义红action策略的例子可能如下所示

use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use AshAllenDesign\RedactableModels\Interfaces\RedactionStrategy;
use Illuminate\Database\Eloquent\Model;

class CustomStrategy implements RedactionStrategy
{
    public function apply(Redactable&Model $model): void
    {
        // Redaction logic goes here
    }
}

手动编辑模型

有时您可能想手动红action模型,而不是使用 model:redact 命令。为此,您可以使用通过 AshAllenDesign\RedactableModels\Traits\HasRedactableFields 特性提供的 redactFields 方法。

您可以将特性应用到模型上,如下所示

use AshAllenDesign\RedactableModels\Interfaces\Redactable;
use AshAllenDesign\RedactableModels\Traits\HasRedactableFields;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements Redactable
{
    use HasRedactableFields;
    
    // ...
}

现在您可以使用 redactFields 方法来红action模型上的字段,如下所示

$user = User::find(1);

$user->redactFields();

默认情况下,这将使用模型中定义的 redactionStrategy 方法中定义的策略来红action字段。

您可以通过将自定义红action策略传递给 redactFields 方法来覆盖此行为,如下所示

use App\Models\User;
use AshAllenDesign\RedactableModels\Support\Strategies\ReplaceContents;

$user = User::find(1);

$user->redactFields(
    strategy: app(ReplaceContents::class)->replaceWith(['name' => 'REDACTED'])
);

事件

ModelRedacted

当一个模型被红action时,会触发一个 AshAllenDesign\RedactableModels\Events\ModelRedacted 事件,该事件可以被监听。

测试

要运行软件包的单元测试,请运行以下命令

vendor/bin/phpunit

安全

如果您发现任何安全相关的问题,请直接通过 mail@ashallendesign.co.uk 联系我报告。

贡献

如果您想对软件包进行任何更改或改进,请随时提出 pull request。

注意:将很快添加贡献指南。

鸣谢

更新日志

查看 CHANGELOG 了解有关最新更改的更多信息。

许可

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件

支持我

如果您觉得这个软件包很有用,请考虑购买一份 Battle Ready Laravel 以支持我和我的工作。

每一次销售对我来说都意义重大,让我有更多时间投入开源项目和教程的制作。

为了表达深深的感谢,您可以使用代码 BATTLE20 获得本书20%的折扣。

👉 购买您的副本!

Battle Ready Laravel