2012-01-16 12 views
14

में गतिशील रूप से भूमिकाएं जोड़ना हम अपने ऐप के कुछ हिस्सों तक उपयोगकर्ताओं की पहुंच को प्रतिबंधित करने के लिए सिम्फनी 2 की भूमिकाओं का उपयोग कर रहे हैं। हमारी प्रत्येक उपयोगकर्ता संस्थाओं में कई सदस्यता संस्थाएं होती हैं जिनकी प्रारंभ तिथि और अंत होता है और उपयोगकर्ता वार्षिक सदस्यता खरीद सकते हैं।उपयोगकर्ता को

अब, क्या उपयोगकर्ता के पास 'सक्रिय' सदस्यता है या नहीं, इसके आधार पर गतिशील रूप से एक भूमिका जोड़ने का कोई तरीका है? रेल में मैं मॉडल को संभालने देता हूं कि उसके पास आवश्यक अधिकार हैं या नहीं, लेकिन मुझे पता है कि डिजाइन symfony2 इकाइयों द्वारा सिद्धांत तक पहुंच नहीं है।

मुझे पता है कि आप एक इकाई उदाहरण के भीतर से एक इकाई के संघों का उपयोग कर सकते लेकिन यह है कि सभी उपयोगकर्ता की सदस्यता वस्तुओं के माध्यम से जाना होगा और है कि मेरे पास unnecessaryly बोझिल लगता है।

उत्तर

27

मुझे लगता है कि आप कस्टम मतदाता और विशेषता को बेहतर तरीके से स्थापित करेंगे।

/** 
* @Route("/whatever/") 
* @Template 
* @Secure("SUBSCRIPTION_X") 
*/ 
public function viewAction() 
{ 
    // etc... 
} 

SUBSCRIPTION_X भूमिका (उर्फ विशेषता) एक कस्टम मतदाता वर्ग द्वारा नियंत्रित किया जा करने की आवश्यकता होगी।

class SubscriptionVoter implements VoterInterface 
{ 
    private $em; 

    public function __construct($em) 
    { 
     $this->em = $em; 
    } 

    public function supportsAttribute($attribute) 
    { 
     return 0 === strpos($attribute, 'SUBSCRIPTION_'); 
    } 

    public function supportsClass($class) 
    { 
     return true; 
    } 

    public function vote(TokenInterface $token, $object, array $attributes) 
    { 
     // run your query and return either... 
     // * VoterInterface::ACCESS_GRANTED 
     // * VoterInterface::ACCESS_ABSTAIN 
     // * VoterInterface::ACCESS_DENIED 
    } 
} 

आप कॉन्फ़िगर और अपने मतदाता को टैग करने की आवश्यकता होगी:

services: 
    subscription_voter: 
     class: SubscriptionVoter 
     public: false 
     arguments: [ @doctrine.orm.entity_manager ] 
     tags: 
      - { name: security.voter } 
+0

@ webda2l मुझे आपके प्रश्न को समझ में नहीं आता –

+0

क्षमा करें .. मैं समझने में थोड़ा आसान होने की कोशिश करूंगा। मतदाता वर्ग, जो एक क्वेरी प्रेरित करता है, केवल उपयोगकर्ता द्वारा या प्रत्येक पृष्ठ लोड पर एक बार कहा जाता है? इस अंतिम मामले में, क्वेरी की पुनरावृत्ति से बचने के लिए, वोट फ़ंक्शन में सत्र के साथ प्रबंधित करने का सबसे अच्छा तरीका है, है ना? – webda2l

+0

आप फिट बैठते समय कैशिंग तंत्र जोड़ सकते हैं या ऑप्टिमाइज़ कर सकते हैं। –

2

मान लीजिए कि आपके उपयोगकर्ता इकाई में सही संबंध "सदस्यता" है।

public function getRoles() 
{ 
    $todayDate = new DateTime(); 
    $activesSubscriptions = $this->subscriptions->filter(function($entity) use ($todayDate) { 
     return (($todayDate >= $entity->dateBegin()) && ($todayDate < $entity->dateEnd())); 
    }); 

    if (!isEmpty($activesSubscriptions)) { 
     return array('ROLE_OK'); 
    } 

    return array('ROLE_KO'); 
} 

भूमिका बदलना साथ किया जा सकता:

$sc = $this->get('security.context') 
$user = $sc->getToken()->getUser(); 
$user->setRole('ROLE_NEW'); 
// Assuming that "main" is your firewall name : 
$token = new \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken($user, null, 'main', $user->getRoles()); 
$sc->setToken($token); 

लेकिन एक पेज परिवर्तन के बाद, प्रदाता के refreshUser समारोह कहा जाता है और कभी कभी, के रूप में

आप शायद की तरह कुछ कोशिश कर सकते हैं EntityUserProvider के साथ यह मामला है, भूमिका एक क्वेरी द्वारा अधिलेखित है। इससे बचने के लिए आपको एक कस्टम प्रदाता की आवश्यकता है।

+0

मुझे पता है। लेकिन जैसा कि मैंने कहा, मैं सभी सब्सक्रिप्शन ऑब्जेक्ट्स के माध्यम से नहीं जाऊंगा बल्कि माईएसक्यूएल को 'भारी उठाने' देना चाहिए, क्योंकि यह हर अनुरोध पर होना है। (मैंने कभी इसका परीक्षण नहीं किया है, लेकिन यह मुझे धीमा लगता है कि वस्तुओं की एक गुच्छा को जबरदस्त हाइड्रेट करने के लिए मुझे धीमा लगता है। अगर मैं गलत हूं तो मुझे सही करें।) – maiwald

+0

आप डॉक्टरेटिन तक पहुंच के साथ एक सेवा का उपयोग करने के लिए form_login के success सफलता_handler विकल्प का उपयोग कर सकते हैं। इसके अंदर, प्रमाणीकरण सफलता समारोह में, आप सही भूमिका पाने के लिए अनुरोध करते हैं। और, क्योंकि, प्रत्येक पृष्ठ परिवर्तन के साथ भूमिकाएं पुनः लोड की जाती हैं, आप एक कस्टम उपयोगकर्ता प्रदाता का उपयोग करते हैं जो उपयोगकर्ता को रीफ्रेश नहीं करता है। – webda2l

+0

लेकिन क्या उपयोगकर्ता को लॉग इन करना होगा और फिर सत्र में बदलाव करना चाहिए? मैं वह नहीं चाहता। – maiwald

संबंधित मुद्दे