2017-03-31 26 views
1

有時,我有一個頁面,我想對不同規則的複雜組合做出反應,這些總體上只是一件事:'當前用戶可以這樣做嗎?'。在Symfony選民中使用isGranted

目前,大部分這些檢查都是直接我的控制器中,所以我不得不例如:

if($this->isGranted('DRAFT_EDITOR', $draft) && $now < $deadline && $draft->getStatus() != Draft::STATUS_FINAL) {...} 

那些五花八門的,如果條件得到相當長的,並有可能最終被各地重複代碼,都實現了完全相同的目的。所以我想抽象這些伸到選民,這樣我就可以只說:

if($this->isGranted('DRAFT_CAN_EDIT') {} 

這將隨後去DraftCanEdit選民這將封裝在IF語句中的所有這些檢查在這篇文章中的一個頂部的地方,可以很容易地改變是什麼讓編輯草稿的規則,容易意外錯過的條件或混亂一個某處,創造漏洞等

的問題是,選民不能調用isGranted() ,因爲它被認爲是一個循環引用,只是爲了向選民注入security.authorization_checker服務。

對我來說,一個調用isGranted的選民在選舉人繼承的形式上似乎很好,只要選舉人不支持傳遞給它的屬性/主題,實際上不應該導致任何形式的循環參考問題。當然,我可以複製DraftCanEditVoter內的DraftEditorVoter邏輯,或者我可以在DraftCanEditVoter內部實例化DraftEditorVoter,但這兩個看起來並不理想,不僅僅是出於代碼重複的原因,也因爲我實際上有兩個選民,一起確定是否某人是DRAFT_EDITOR。

我也意識到我可以通過製作自己的非選民對象並直接使用它來封裝IF條件,但認爲這可能有點反模式。

+0

您可以在DraftCanEditVoter選民中注入DraftEditorVoter嗎?另外,選民是不是有一個共同的結論?比如,至少有一個人必須投贊成票,或者至少有50%的人必須投贊成票,否則不得投不。 – Joshua

+0

將策略更改爲一致,然後讓兩位選民處理DRAFT_CAN_EDIT權限。 http://symfony.com/doc/current/security/voters.html#changing-the-access-decision-strategy – Cerad

回答

1

從我的角度來看,你可以做兩件事情:

  1. 我很好奇你的問題,所以我搜索的文檔。這樣,我遇到了這部分文檔,AccessDecisionManagerhttp://symfony.com/doc/current/security/voters.html#checking-for-roles-inside-a-voter。我敢打賭,你可以用它來檢查你的DraftEditorVoter

  2. 你可以注入你的DraftEditorVoterDraftCanEditVoter。這樣,您可以使用其voteOnAttribute方法而不創建依賴性循環。您需要調用它的所有內容都已傳遞給您的選民,因此參數不應該成爲問題。

+1

另一種方法是隻有一個DraftVoter。 – Cerad

+0

哦,很奇怪,我以爲我已經檢查過文檔,什麼都沒發現,並且在教程中它是正確的! – Kookas

+0

@Kookas雖然沒有冒犯的意思:) – Joshua