2012-01-16 24 views
14

Kullanıcılarımızın uygulamanızın belirli bölümlerine erişimini kısıtlamak için Symfony2'nin rollerini kullanıyoruz. Kullanıcı birimlerimizin her biri, başlangıç ​​tarihi ve sonu olan ve kullanıcıların yıllık abonelik satın alabilecekleri birçok Abonelik varlığına sahiptir.Kullanıcıya dinamik olarak roller ekleme

Şimdi, bir kullanıcı için 'etkin' bir abonelik olup olmadığına bağlı olarak dinamik olarak bir rol eklemenin bir yolu var mı? Raylarda, modelin gerekli haklara sahip olup olmadığını ele almasına izin verirdim, ancak tasarımın simfony2 varlıklarının Doktrin'e erişimi olmaması gerektiğini biliyorum.

Sana bir varlık örneği içinden bir işletmenin dernekleri erişebilir ancak tüm kullanıcının abonelik nesneleri üzerinden gideceğini ve bu benim için unnecessaryly hantal görünüyor biliyoruz.

cevap

27

Özel bir seçmen ve özniteliği daha iyi ayarlayacağınızı düşünüyorum.

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

SUBSCRIPTION_X rolü (aka özellik) özel bir seçmen sınıfı tarafından ele alınması gerekir.

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 
    } 
} 

yapılandırabilir ve seçmen etiketlemek gerekir:

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

@ webda2l Sorunuzu anlamadım –

+0

Üzgünüm .. Anlamak biraz daha kolay olmaya çalışacağım. Bir sorguyu tetikleyen Voter sınıfı, kullanıcı tarafından veya her sayfa yükünde yalnızca bir kez çağrılır mı? Bu son durumda, sorgunun tekrarlanmasını önlemek için, en iyi yol oylama işlevindeki oturumla yönetmek olacaktır, öyle değil mi? – webda2l

+0

Bir önbellek mekanizması ekleyebilir veya uygun gördüğünüz şekilde optimize edebilirsiniz. –

2

Kullanıcı Kuruluşunuzda doğru ilişki "abonelikleri" bulunduğunu varsayarsak. olarak, bazen

$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); 

Ama bir sayfa değişiklikten sonra

, sağlayıcının refreshUser fonksiyonu denir ve: rol değiştirme

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'); 
} 

ile yapılabilir:

Belki gibi bir şey deneyebilirsiniz EntityUserProvider ile durum budur, rol bir sorgu tarafından üzerine yazılır. Bunu önlemek için özel bir sağlayıcıya ihtiyacınız var.

+0

biliyorum. Ama dediğim gibi, tüm abonelik nesnelerini gözden geçirmemek yerine MySQL'in 'ağır kaldırma' yapmasına izin vermekteyim, çünkü her istekte bu gerçekleşiyor. (Bunu hiç denemedim, ama bir sürü nesneyi gereksiz yere hidratlamak bana göre daha yavaş görünüyor. Yanılıyorsam düzeltin.) – maiwald

+0

Doctrine erişimi olan bir hizmeti kullanmak için, form_login success_handler seçeneğini kullanabilirsiniz. İçinde, onAuthenticationSuccess işlevinde, doğru rolü almak için istekte bulunursunuz. Ayrıca, roller her sayfa değişikliğiyle yeniden yüklendiğinden, kullanıcıyı yenilemeyen özel bir kullanıcı sağlayıcısı kullanırsınız. – webda2l

+0

Ancak, bir oturum sırasında rollerin değişmesi durumunda bir kullanıcının çıkış yapıp tekrar giriş yapması gerekmez mi? Bunu istemezdim. – maiwald

İlgili konular