定制 demos-europe/edt-access-definitions 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

demos-europe/edt-access-definitions

Composer 安装命令:

composer require demos-europe/edt-access-definitions

包简介

Tools to regulate access to entities and their properties.

README 文档

README

Allows fine-grained definitions how entities and their properties are allowed to be accessed in CRUD applications.

Provides PHP classes that build upon the query component to provide the means to enforce access limitation and simple aliasing from the wrapper schema to the schema of your backing object. The path-building component can optionally be used to ease the usage depending on the use case.

Overview

This component provides the means to define so called Types for corresponding objects in your application. Your Types will limit the access to the schema and instances of your objects depending on the authorization of the accessing user or other states in your application. It shows its main advantages in CRUD applications but can be applied to other types of applications as well.

As an example lets assume a very simple CMS software. It has an Article class which is connected to its author in a bidirectional many-to-one relationship.

Querying

Suppose for your business layer you need to distinguish between articles which are in their draft state and thus only visible to their authors and finished articles visible to everyone. Instead of sprinkling your business layer with potentially duplicated checks which user is allowed to access which articles you can centralize your authorisations in an ArticleType class.

After the initial setup you can use it with conditions to query instances from your data source, similar to the Query Component:

use EDT\Wrapping\Contracts\Types\TransferableTypeInterface;
use EDT\ConditionFactory\ConditionFactoryInterface;

function getArticleType(): ArticleType {
    // returns the Type defining access limitations to your Article objects
}
function getEntityProvider(): EntityProviderInterface {
    // returns the instance to access your data source
}
function getConditionFactory(): ConditionFactoryInterface {
    // returns a factory for conditions adjusted to your data source
}

// initializations
$articleType = getArticleType();
$conditionFactory = getConditionFactory();
$typeProvider = new PrefilledTypeProvider([$articleType]);
$pathProcessor = new SchemaPathProcessor(new PropertyPathProcessorFactory(), $typeProvider);

// create a condition for your business logic
$nameCondition = $conditionFactory->propertyHasValue('jacob', 'author', 'accountName');

// check if the path used in the condition is allowed to be accessed
// and resolve aliases if used in the path
$pathProcessor->mapFilterConditions($articleType, [$nameCondition]);
// add the access condition defined by the type itself
$conditions[] = $pathProcessor->processAccessCondition($articleType);

// get the entities matching not only the name condition
// but also all conditions defined by the article type itself
$filteredEntities = $entityFetcher->getEntities($conditions);

The three helper function are left empty because their implementation depends on your actual use case:

  1. getArticleType returns your ArticleType which you can implement by extending TransferableTypeInterface and instantiate in your favorite style (manually, as Symfony Service, loaded by configuration, …​). An overview for the different interfaces available and how to implement them is shown in How to implement types.

  2. The instances returned by getEntityProvider and getConditionFactory depend on your data source. For possible classes see Providers and Factories setup.

As you can see in this example we explicitly specified a condition to only get articles written by jacob. However, if the ArticleType was configured correctly we will actually get a subset of the result with only those articles that the current user is allowed to access. E.g. if the user currently logged in is not jacob she or he will only receive articles that are not in their draft state anymore. jacob on the other hand well get all his articles. This implicit condition will be executed automatically and only needs to be set once in the ArticleType, where it will be applied every time the ArticleType is used to access Article objects.

Wrapping

If the object class you’ve written your Type for doesn’t contain any relationships but primitive types only then accessing your actual object instances may be fine. However, in the case of the Article objects we need to prevent users from simply getting an arbitrary article available to them via the ArticleType and then accessing its actual author instance. This would enable unlimited access to all Article instances of that author, regardless of any setting in the ArticleType.

Because of this you can wrap your entity instances with a corresponding type. The properties the wrapper grants access to depend on the ArticleType and its relations to other Types. For example instead of completely denying access to the author in the ArticleType we may want to configure a UserType. Like the ArticleType the UserType can restrict access to data and schema. This way we can allow access to authors to get their public name, but can prevent the access to their drafts.

function getWrapperFactory(): WrapperObjectFactory {
    // the wrapper factory initialized with the necessary parameters
}

$wrapperFactory = getWrapperFactory();
$wrappedEntities = array_map(function (Article $articleEntity) use ($articleType): WrapperObject {
    return $this->getWrapperFactory()->createWrapper($articleEntity, $articleType);
}, $articleEntities);

Also note that the restrictions of Types are in place no matter how they are accessed. For example when you’ve restricted access to the internal e-mail address of your users using a UserType then it does not matter if the wrapper of the User object was received via a relationship from a wrapped Article`, a wrapped Comment or wrapped manually, the restriction will always be applied.

Credits and acknowledgements

Conception and implementation by Christian Dressler with many thanks to eFrane.

demos-europe/edt-access-definitions 适用场景与选型建议

demos-europe/edt-access-definitions 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 26.31k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2022 年 06 月 23 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 demos-europe/edt-access-definitions 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 demos-europe/edt-access-definitions 我们能提供哪些服务?
定制开发 / 二次开发

基于 demos-europe/edt-access-definitions 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 26.31k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 39
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 2
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-06-23