Let's say we have three main roles that are directly related to the user database table: ROLE_USER , ROLE_MODERATOR and ROLE_ADMIN .
BUT, we also got some other roles that are used for the Crews component (see UML below). I use the following roles for actions generated in Crew : ROLE_CREW_BOSS , ROLE_CREW_LEFTHAND , ROLE_CREW_RIGHTHAND , ROLE_CREW_MEMBER .
+ ---------------- + + ------------------ +
| users | | crews |
| ---------------- | | ------------------ |
| id | | id |
| username <--- + | name |
| password | | + ---> cash |
| roles | | + ------------------- + | | ... |
| ... | | | crew_members | | | |
| | | | ------------------- | | | |
+ ---------------- + | | crew_id + -------------- + | |
+ ---- + user_id | + -------- ^ --------- +
| roles | |
| ... | + ------------ +
| | |
| | | + ------------------ +
| | | | forum_topics |
| | | | ------------------ |
| | | | id |
+ ------------------- + + --- + crew_id |
| title |
| description |
| ... |
| |
| |
| |
+ ------------------ + This is the basic structure, I hope this part is clear. Now the problem is ...
Problem
Each user with the ROLE_MODERATOR role can create ForumTopic objects, but not the one where crew_id set, because that one is private for a specific crew. In addition, only crew members (who are also users) who have the roles ROLE_CREW_BOSS , ROLE_CREW_LEFTHAND or ROLE_CREW_RIGHTHAND can edit their team's forum topics. How to check this complexity? With Voter maybe?
UPDATE 1
I solved the problem by 50%, but not durable. I created a selector specific to the Entity\\ForumTopic .
public function vote(TokenInterface $token, $object, array $attributes) { if ($object instanceof ObjectIdentityInterface) { if ($object->getType() == 'Entity\\ForumTopic') { $member = $token->getUser(); $userTable = new UserTable(); $user = $userTable->getByMember($member); $userInCrewTable = new UserInCrewTable(); $crewMember = $userInCrewTable->getByUser($user); if ($crewMember && in_array($crewMember->getRole(), array('boss', 'lefthand', 'righthand'))) { return self::ACCESS_GRANTED; } } } return self::ACCESS_ABSTAIN; }
The only problem here is that I am not using the appropriate roles, so I cannot use the functionality of the role hierarchy, for example. Has anyone got a better solution or an improvement to my current solution?
Thanks!
Steffen
symfony acl
Steffen brem
source share