sebk/swoft-voter

Swoft 投票系统

1.1 2021-10-30 10:33 UTC

This package is auto-updated.

Last update: 2024-09-29 05:50:04 UTC


README

Swoft 的投票系统

安装

创建您的 Swoft 项目:http://swoft.io/docs/2.x/en/quick-start/install.html

需要 Swoft Voter 包(https://github.com/sebk69/swoft-voter

composer require sebk/swoft-voter

文档

参数

在您的 'config' 文件夹中,创建一个 'voter.php' 文件

<?php

return [
    'path' => [
        __DIR__ . '/../app/Security/Voter',
        __DIR__ . '/../app/Security/ModelVoter',
    ],
];

您可以将任何路径作为参数。

创建一些投票者

要创建一个投票者,在投票者文件夹中放置一个新的投票类,该类实现了 Sebk\SwoftVoter\VoterManager\VoterInterface(请参阅参数部分)。

该接口很简单

namespace Sebk\SwoftVoter\VoterManager;

interface VoterInterface
{
    // Responses
    const ACCESS_GRANTED = 1;
    const ACCESS_ABSTAIN = 0;
    const ACCESS_DENIED = -1;

    // Attributes
    const ATTRIBUTE_READ = "READ";
    const ATTRIBUTE_WRITE = "WRITE";
    const ATTRIBUTE_UPDATE = "UPDATE";
    const ATTRIBUTE_DELETE = "DELETE";

    /**
     * Is voter sopported by vote ?
     * @param $subject
     * @param $attibutes
     * @return bool
     */
    function support($subject, array $attibutes);

    /**
     * Vote
     * @param $user
     * @param $subject
     * @param array $attributes
     * @return int
     */
    function voteOnAttribute($user, $subject, array $attributes);
}

'support' 方法必须返回一个布尔值,表示投票者是否关心由主题和属性表示的投票。

'voteOnAttribute' 方法是用户投票的结果。它必须返回接口常量之一

  • ACCESS_GRANTED:投票者认为用户被允许
  • ACCCESS_DENIED:投票者认为用户不被允许
  • ACCCESS_ABSTAIN:投票者不考虑任何响应

在投票时,所有相关的投票者(在 'support' 调用中返回 true)都会被查询

  • 如果其中一个投票者授予访问权限,则认为投票被授予。
  • 如果投票者弃权,则不将其响应计入。
  • 如果所有投票者都拒绝访问,则认为用户拒绝了访问。

以下是一个检查控制器访问权限的投票者示例

<?php

namespace App\Security\Voter;

use App\Http\Controller\Abstract\TokenSecuredController;
use Sebk\SwoftVoter\VoterManager\VoterInterface;

class ControllerVoter implements VoterInterface
{

    /**
     * Is voter sopported by vote ?
     * @param \stdClass $subject
     * @param array $attibutes
     * @return bool
     */
    public function support($subject, array $attibutes)
    {
        $result = false;

        // Check attributes
        foreach ($attibutes as $attibute) {
            switch ($attibute) {
                case VoterInterface::ATTRIBUTE_READ:
                case VoterInterface::ATTRIBUTE_UPDATE:
                    $result = true;
            }
        }

        // If attributes checked, check subject
        if ($result) {
            if (!$subject instanceof TokenSecuredController) {
                $result = false;
            }
        }

        return $result;
    }

    /**
     * Vote
     * @param $user
     * @param $subject
     * @param array $attributes
     * @return int
     */
    public function voteOnAttribute($user, $subject, array $attributes)
    {
        if ($user->getLogin() == "KS" && in_array(VoterInterface::ATTRIBUTE_READ, $attributes)) {
            return VoterInterface::ACCESS_GRANTED;
        }

        return VoterInterface::ACCESS_DENIED;
    }

}

投票

实例化投票管理器

use Sebk\SwoftVoter\VoterManager\VoterManagerInterface;

$this->voterManager = bean(VoterManagerInterface::class);

并对您想要投票的对象进行投票

use Sebk\SwoftVoter\VoterManager\VoterInterface;

$subject = $this->objectToVote;
$attributes = [
    VoterInterface::ATTRIBUTE_READ,
    VoterInterface::ATTRIBUTE_WRITE,
];
$voteResult = $this->voterManager->vote($this->getUser(), $subject, $attributes);
if ($voteResult != VoterInterface::ACCESS_GRANTED) {
    // And deny access if not granted
    throw new AccessDeniedException("Forbidden access");
}