2014-09-15 29 views
8

Opracowuję prosty CRUD do zarządzania użytkownikami/rolami/grupami aplikacji, w których pracuję. Aby zarządzać użytkownikami, używam FOSUserBundle. Co chcę zrobić można osiągnąć na kilka sposobów:Zarządzanie użytkownikami/rolami/grupami w FOSUserBundle

  • Przypisywanie ról do grup, a następnie przypisać użytkowników do tych grup
  • Przypisywanie ról do użytkowników bezpośrednio

Ale nie mam pojęcia, jak to zrobić. Wiedziałem, że klasa FOSUser BaseUser ma już kolumnę roles, a w artykule documentation FOSUser wyjaśniono, jak ustanowić relację między użytkownikami i grupami, ale nie mów nic o rolach. Jedyny pomysł, który przychodzi do głowy jest stworzenie podmiotu do zarządzania rolami, a także formularz do tego samego celu, coś co można zobaczyć poniżej:

Podmiot Rola

use Symfony\Component\Security\Core\Role\RoleInterface; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Table(name="fos_role") 
* @ORM\Entity(repositoryClass="UserBundle\Entity\Repository\RoleRepository") 
* 
* @see User 
* @see \UserBundle\Role\RoleHierarchy 
* 
*/ 
class Role implements RoleInterface 
{ 
    /** 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id() 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\Column(name="name", type="string", length=80, unique=true) 
    */ 
    private $name; 

    /** 
    * @ORM\ManyToOne(targetEntity="Role", inversedBy="children") 
    * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true) 
    * @var Role[] 
    */ 
    private $parent; 

    /** 
    * @ORM\OneToMany(targetEntity="Role", mappedBy="parent") 
    * @var ArrayCollection|Role[] 
    */ 
    private $children; 

    /** 
    * @ORM\ManyToMany(targetEntity="User", mappedBy="roles") 
    */ 
    private $users; 

    public function __construct($role = "") 
    { 
     if (0 !== strlen($role)) { 
      $this->name = strtoupper($role); 
     } 

     $this->users = new ArrayCollection(); 
     $this->children = new ArrayCollection(); 
    } 

    /** 
    * @see RoleInterface 
    */ 
    public function getRole() 
    { 
     return $this->name; 
    } 

    public function getId() 
    { 
     return $this->id; 
    } 

    public function setId($id) 
    { 
     $this->id = $id; 
    } 

    public function getName() 
    { 
     return $this->name; 
    } 

    public function setName($name) 
    { 
     $this->name = $name; 
    } 

    public function getUsers() 
    { 
     return $this->users; 
    } 

    public function addUser($user, $addRoleToUser = true) 
    { 
     $this->users->add($user); 
     $addRoleToUser && $user->addRole($this, false); 
    } 

    public function removeUser($user) 
    { 
     $this->users->removeElement($user); 
    } 

    public function getChildren() 
    { 
     return $this->children; 
    } 

    public function addChildren(Role $child, $setParentToChild = true) 
    { 
     $this->children->add($child); 
     $setParentToChild && $child->setParent($this, false); 
    } 

    public function getDescendant(& $descendants = array()) 
    { 
     foreach ($this->children as $role) { 
      $descendants[spl_object_hash($role)] = $role; 
      $role->getDescendant($descendants); 
     } 
     return $descendants; 
    } 

    public function removeChildren(Role $children) 
    { 
     $this->children->removeElement($children); 
    } 

    public function getParent() 
    { 
     return $this->parent; 
    } 

    public function setParent(Role $parent, $addChildToParent = true) 
    { 
     $addChildToParent && $parent->addChildren($this, false); 
     $this->parent = $parent; 
    } 

    public function __toString() 
    { 
     if ($this->children->count()) { 
      $childNameList = array(); 
      foreach ($this->children as $child) { 
       $childNameList[] = $child->getName(); 
      } 
      return sprintf('%s [%s]', $this->name, implode(', ', $childNameList)); 
     } 
     return sprintf('%s', $this->name); 
    } 
} 

roli Typ formularza

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class RoleType extends AbstractType { 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
       ->add('name') 
       ->add('parent'); 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'Tanane\UserBundle\Entity\Role' 
     )); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'role'; 
    }  
} 

Jeśli tak, co by dodać użytkownika do mojej postaci będzie wyglądać następująco

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
      ->add('username', 'text') 
      ->add('email', 'email') 
      ->add('enabled', null, array(
       'label' => 'Habilitado', 
       'required' => false 
      )) 
      ->add('rolesCollection', 'entity', array(
       'class' => 'UserBundle:Role', 
       'multiple' => true, 
       'expanded' => true, 
       'attr' => array('class' => 'single-line-checks') 
      )) 
      ->add('groups', 'entity', array(
       'class' => 'UserBundle:Group', 
       'multiple' => true, 
       'expanded' => true, 
    )); 
} 

Ale nie wiem, czy to jest właściwy sposób na obsłużenie ról, ponieważ w tym przypadku tworzyłby nową tabelę w moim DB o nazwie fos_roles, gdzie byłyby relacje między użytkownikami/rolami, ale relacje między grupami/Role pozostają z tego, to wtedy jestem trochę zagubiony i potrzebuję pomocy od bardziej doświadczonych w tym, co mówi mi i ostrzegam, czy jestem na dobrej drodze, i to sprawi, że osiągną to, co wyjaśniam w dwóch pierwszych punktach. Wszelkie porady lub pomoc? Jak sobie z tym poradzić?

Odpowiedz

26

Symfony Roles

drodze FOSUserBundle oferty z rolami jest je przechowywać w kolumnie roles które widziałem, w odcinkach formacie jak poniżej: a:1:{i:0;s:10:"ROLE_ADMIN";}. Nie ma więc potrzeby żadnych innych stołów ani bytów.

^Kontrastuje to z Grupami, które muszą być jawnie skonfigurowane, reprezentowane są przez osobną Tabelę/Obiekt i wiążą się z powiązaniem Użytkowników z Grupami w DB. Grupy pozwalają definiować dowolne kolekcje ról, które mogą być następnie przydzielane każdemu użytkownikowi jako dyskretny pakiet.

Użytkownik może być członkiem dowolnej liczby ról. Są one identyfikowane za pomocą ciągów zaczynających się od "ROLE_", możesz po prostu zacząć korzystać z nowej roli.

To, co dla Ciebie oznaczają aplikacje, zależy wyłącznie od Ciebie, ale są one dość zaawansowanym narzędziem - Użytkownik jest albo w określonej roli, albo nie.

umieścić ludzi w rolach albo poprzez Symfony console:

php app/console fos:user:promote testuser ROLE_ADMIN 

Albo w PHP:

$user = $this->getUser(); 
$userManager = $container->get('fos_user.user_manager'); 
$user->addRole('ROLE_ADMIN'); 
$userManager->updateUser($user); 

I można przetestować członkostwa w PHP:

$user = $this->getUser(); 
if ($user->hasRole('ROLE_ADMIN')) 
{ 
    //do something 
} 

lub używając Annotations :

/** 
* @Security("has_role('ROLE_ADMIN')") 
*/ 
public function adminAction() 
{ 
    //... 

lub

/** 
* @Security("has_role('ROLE_ADMIN')") 
*/ 
class AdminController 
{ 
    //... 
+4

Dlaczego szeregują dane w mysql? zapach kodu – user3886650

3

I dodaje funkcjonalność, aby dodać domyślną grupę użytkownikowi podczas rejestracji poprzez nadpisanie confirmAction w kontrolerze Rejestracji

Co zrobiłem ja overrided kontroler rejestracja w moim Bundle projektu definiując rodzica jako FosUserBUndle.

Następnie stworzył confirmedAction funkcji i w ciele funkcji dodaje ten kod

$repository = $em->getRepository('AdminAdminBundle:Group'); 
     $group = $repository->findOneByName('staff'); 

     $em = $this->getDoctrine()->getEntityManager(); 
     $user = $this->getUser(); 
     $user->addGroup($group); 

     $userManager = $this->get('fos_user.user_manager'); 

     $userManager->updateUser($user); 

     if (!is_object($user) || !$user instanceof FOS\UserBundle\Model\UserInterface) { 
      throw new AccessDeniedException('This user does not have access to this section.'); 
     } 

     return $this->render('FOSUserBundle:Registration:confirmed.html.twig', array(
      'user' => $user, 
     )); 

I to doskonale zapisany w db z cesją grupowej. Mam nadzieję, że pomoże to komuś potrzebującemu, ponieważ niewiele informacji na temat implementacji znajduje się w oficjalnym dokumencie fosuserbundle.