Laravel政策不起作用

时间:2018-02-13 08:30:54

标签: laravel policy

在我的Laravel应用程序中,我有几个策略正在运行,但其中一个不起作用。

控制器

//
//  YMPianoRollLayout.swift
//
import UIKit

class YMPianoRollLayout: UICollectionViewLayout {
    let notes : Array<CGPoint> = []

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!;
    }

    override var collectionViewContentSize : CGSize {

        let cv = self.collectionView as! YMPianoRollCollectionView
        let screenInfo = cv.pianoRollViewController.screenInfo        
        let totalSize = screenInfo.collectionViewContentsSize();

        print("contentSize = \(totalSize)")

        return totalSize;
    }    

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

        // "screenInfo" keeps the user specified view parameters including the scale ratio by the pinch gesture
        let cv = self.collectionView as! YMPianoRollCollectionView;
        let pianoRoll = cv.pianoRollViewController;

        // Check which musical note can be included in the view rect
        let indexArray: Array<Int> = pianoRoll!.getNoteIndexes(inRect:rect, useOnlyStartTime: false);

        var retArray : [UICollectionViewLayoutAttributes] = []

        for i in indexArray {
            if let _ = pianoRoll?.pattern.eventSequence[i] as? YMPatternEventNoteOn {
                retArray.append( self.layoutAttributesForPatternEventInfo(i) )
            }
        }

        // This always reports non-zero count. Also checked the positions of each array members 
        // by breaking here and they all had proper size and positions
        print("retArray count = \(retArray.count)"); 

        return retArray
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let i = Int((indexPath as NSIndexPath).row)
        return self.layoutAttributesForPatternEventInfo(i)
    }

    //
    // This is my specific func to convert the musical time-pitch into the view geometory
    //
    func layoutAttributesForPatternEventInfo(_ index: Int) -> UICollectionViewLayoutAttributes!{
        let cv = self.collectionView as! YMPianoRollCollectionView

        // "screenInfo" keeps the user specified view parameters including the scale ratio by the pinch gesture
        let screenInfo = cv.pianoRollViewController.screenInfo 

        // Retrieve musical event
        let event = cv.pianoRollViewController.pattern.eventSequence[index]        

        let index = IndexPath(row:index, section: 0)        
        let newAttr = UICollectionViewLayoutAttributes(forCellWith:index)

        var frame : CGRect!

        if let e = event as? YMPatternEventNoteOn {
            let noteNo = e.noteNo;
            let origin = YMMusicalValuePoint(time:event.time, noteNumber:noteNo);
            let size = YMMusicalValueSize(timeLength:e.duration, numberOfNotes: 1);

            // Actual size calculation is done in my "screenInfo" class.
            frame = screenInfo.getPhysicalRange(YMMusicalValueRange(origin:origin, size:size));
        } else {
            frame = CGRect(x: 0, y: 0, width: 0, height: 0);
        }

        newAttr.frame = frame;
        newAttr.zIndex = 1;

        return newAttr
    }

    //
    // For checking the bounds
    //
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        print("BBB newBounds = \(newBounds)") 
        return true
    }
}

政策

    public function store(Project $project, CreateActionRequest $request)
{
    $this->authorize('store',  $project);

    Action::create([
        'name' => $request->name,
    ]);

    return redirect()->route('projects.show', $project->id)->withSuccess('Massnahme erfolgreich gespeichert');
}

AuthServiceProvider

namespace App\Policies\Project;
use App\Models\Project\Project;
use App\Models\User;
use App\Models\Project\Action;
use Illuminate\Auth\Access\HandlesAuthorization;
class ActionPolicy
{
use HandlesAuthorization;

public function store(User $user, Project $project)
{
    return $user->company_id === $project->company_id;
}
}

CreateActionRequest

    protected $policies = [
    'App\Models\User' => 'App\Policies\CompanyAdmin\UserPolicy',
    'App\Models\Company' => 'App\Policies\CompanyAdmin\CompanyPolicy',
    'App\Models\Team' => 'App\Policies\CompanyAdmin\TeamPolicy',
    'App\Models\Department' => 'App\Policies\CompanyAdmin\DepartmentPolicy',
    'App\Models\Location' => 'App\Policies\CompanyAdmin\LocationPolicy',
    'App\Models\Division' => 'App\Policies\CompanyAdmin\DivisionPolicy',
    'App\Models\Costcenter' => 'App\Policies\CompanyAdmin\CostcenterPolicy',
    'App\Models\Workplace' => 'App\Policies\CompanyAdmin\WorkplacePolicy',
    'App\Models\Product' => 'App\Policies\CompanyAdmin\ProductPolicy',
    'App\Models\Project\Action' => 'App\Policies\Project\ActionPolicy',
    'App\Models\Project\Project' => 'App\Policies\Project\ProjectPolicy',
];

除ActionPolicy和ProjectPolicy外,所有政策均有效。 我在策略中添加了一个__construct()方法来检查策略是否被调用。但ActionPolicy和ProjectPolicy无效。 我该如何搜索错误?我试过用dd()但我总是得到消息:这个动作是未经授权的

2 个答案:

答案 0 :(得分:0)

由于您正在注入CreateActionRequest而不是Request,这意味着您要定义自己的一套规则来授权方法中的FormRequest。此外,这意味着您必须定义一些规则,其中包括&#34; FormRequest&#34;必须通过才能到达你的控制器,这是一个很好的概念,我喜欢Laravel,因为代码不是集中的,而是传播,每一层都有它自己的责任。现在,您不必从CreateActionRequest调用任何方法,也不必在控制器中编写有关该类的任何代码,因为Laravel在authorize之前运行default方法允许Request到达您的控制器,然后在authorize中运行CreateActionRequest方法运行rules方法,该方法验证所有给定字段都通过您指定的表达式,执行是这样的CreateActionRequest => rules => authorize => IF(authorized) Controller ELSE Not authorized,希望这是有道理的。为了修复你的代码:

1。)删除$this->authorize('store', $project);

如果您的not authorized通过name方法内rules方法内的真值测试,则可以传递CreateActionRequest错误。如果您希望使用Action Policy,则需要使用它来连接自定义Request(CreateActionRequest),具体方法如下:

public function authorize()
{
    $store = $this->route('project');
    //The above line will return Project object if your mapping is correct
    //If it's not it will return the value you passed to your route for {project}
    return $this->user() && $this->user()->can('store', $store);
}

修改

Here is the link您可以在其中查看如何使用CreateActionRequest正确授权和关联政策

答案 1 :(得分:0)

您是否最后使用Request对象定义了所有控制器方法?

public function store(Project $project, CreateActionRequest $request)

Request对象应该是方法签名中的第一个参数:

public function store(CreateActionRequest $request, Project $project)
  

依赖注入&amp;路线参数

     

如果您的控制器方法也期望来自路由参数的输入,则应在其他依赖项之后列出路由参数。

大多数Laravel授权机制都有相同的方法签名,允许它们在不同的类中工作。