I'm working with symfony 2.3. How I can show the user roles without (ROLE_). I want to change the view, but in the database are intact.
When I display the roles in the view I have this
ROLE_ADMIN
ROLE_CONSULTOR
and I want
Admin
Consultor
Role Entities just need to implement the RoleInterface. You can add your own custom fields such as the names you want.
http://api.symfony.com/2.3/Symfony/Component/Security/Core/Role/RoleInterface.html
Not clear what you want to achieve, but if there are few roles, may be 2-3, (e.g. ROLE_ADMIN, ROLE_CONSULTOR, ROLE_USER), just define a method which receives the system role, returns the human readable one. May be like this:
public function convertToHumanreadable($role)
{
$return = null;
switch ($role) {
case 'ROLE_ADMIN':
$return = 'Admin';
break;
...
}
return $return;
}
Or even like this:
public function convertToHumanreadable($role)
{
$roleParts = explode('_', $role)
return ucfirst(strtolower($roleParts[1]));
}
Or you can create your own role entity by implementing the RoleInterface as #DerickF mentioned.
Related
Symfony 4 app, and I am using the FOSUser bundle for my user system at present.
I would like to add a complete your profile feature after the user first registers their account. Perhaps it continues to appear until a condition is met or a time is expired.
To begin with what should I add to my User class to flag the user needs to be redirected to /profile/complete ?
ie. Is one extra field required ... completeProfile with methods setCompleteProfile and hasCompleteProfile?
How can I set a condition or time limit on when the user doesn't need to be flagged for complete profile?
ie. is this done in the controller? what symfony service can be used?
Do you have a $ registredAt and $ hasCompleteProfile property in your Entity App\Entity\User or something else?
You can do like this, in your Controller ...
public function yourController(User $user) {
if (!$user->getHasCompleteProfile()) { // Getters of $hasCompleteProfile inside App\Entity\User
$completeProfileLimt = 4; // In months or days, 4 is just and example
$now = new \Datetime();
$userRegistredDate = $user->getRegistredAt();
$elapsedTime = $now - $userRegistredDate; // You can not do it like this but it's an example
if ($elapsedTime > $completeProfileLimt) {
// Your action
}
// Your Response Return
}
// Your Response Return
}
Lets say I have a Car Entity. Other than typical Car properties I have updatedBy attribute
In sonata I created a CRUD admin page using AppBundle\Admin\CarAdmin.php
Inside the class CarAdmin I have the required methods like configureListFields, configureFormFields, etc...
I'm guessing I need to add updatedBy using the method prePersist($object) but I'm facing that $this->getUser() is not available
The question is, how can I get the logged in user to populate updateBy attribute?
You can get logged user using $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser(). In your case you need to do something like this:
public function setUpdatedByAttribute($car)
{
$user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser();
$car->setUpdatedBy($user);
}
public function prePersist($car)
{
$this->setUpdatedByAttribute($car);
}
public function preUpdate($car)
{
$this->setUpdatedByAttribute($car);
}
I am currently working on a project where Moderation is the requirement.
There are multiple groups of users:
Content Creator
Content Reviewer
Admins
The business requirement is that once CREATOR has submitted items for REVIEW, they should not be able to edit it anymore.
How can we disable editing on certain items by checking if STATUS of the item is UNDER_REVIEW?
The standard way would be to use ACLs, as described in the Sonata Admin Security docs.
In summary:
Integrate with FOSUserBundle, conveniently by using SonataUserBundle (I'm sure there are other options for managing users)
Configure ACLs in Sonata
Set up your Roles as required, and then create a Custom Voter which can check the Role of the User, and the state of the object, and vote to grant access only if appropriate, something like this:
Voter
public function vote(TokenInterface $token, $object, array $attributes)
{
//...
foreach ($attributes as $attribute) {
if ($this->supportsAttribute($attribute) && $object instanceof Item) {
if $attribute == 'EDIT' && ($token->getUser()->hasRole('ROLE_CREATOR') && $object->getStatus() == 'UNDER_REVIEW')
return self::ACCESS_DENIED;
}
if (($token->getUser()->hasRole('ROLE_ADMIN') {
return self::ACCESS_GRANTED;
}
//etc etc
}
}
//...
}
It seems like a basic need but can't find any resource on the subject.
In the User Admin form, I need to filter the selectable groups depending on current user's roles.
Let's say we should only be able to select groups for which we are granted to all attached roles.
I think ACLs are not required here.
Could I use a voter ?
As it seems to me like a common need, could someone point me to any resource ?
As I can see the maddening rush to respond to my question, I'm going to give my humble contribution.
I have not been able to use ACL nor voters for that.
So I did a custom type extending choice
This type retrieves the groups from a service with security.context and doctrine injected.
This service have a function for gathering groups that have this little algorithm:
public function allExistingGroups()
{
$finalGroupsList = array();
/* Get all existing groups */
$groups = $this->doctrine->getRepository('SonataUserBundle:Group')
->findAll();
foreach ($groups as $group) {
$isGranted = true;
foreach ($group->getRoles() as $role) {
if (!$this->securityContext->isGranted($role)) {
$isGranted = false;
}
}
/* User is granted, so he can see the group */
if ($isGranted) {
$finalGroupsList[$group->getId()] = $group->getName();
}
}
return $finalGroupsList;
}
The user will now see only groups to which he is granted to all the roles.
For sure there should be a prettier solution, but this did the trick for me.
On my site, I have three roles:
Role 1
Role 2
Role 3
Role 1 may only ever have 10 nodes of type "NODE_TYPE".
Role 2 may only ever have 100 nodes of type "NODE_TYPE".
Role 3 may only ever have 1000 nodes of type "NODE_TYPE".
What can I use to enforce this? The following modules don't do the trick:
node_limit
user quota
Anyone?
How this can be achieved largely depends on how NODE_TYPE is created.
Assuming you have a NODE_TYPE module you could implement hook_validate by doing something like this:
function NODE_TYPE_validate($node, &$form) {
if (NODE_TYPE_reached_post_limit()) {
form_set_error('form_name', t('You have reached your post limit'));
}
}
function NODE_TYPE_reached_post_limit() {
global $user;
//Write code to do the following:
//-> Check which group $user belongs to
//-> Create query to see how many posts $user has made
//-> Return true if $user has reached the limit
}
If you do not have access to the module that creates the NODE_TYPE you could create a new module and implement hook_nodeapi:
function yournewmodule_nodeapi(&$node, $op) {
switch ($op) {
case 'validate':
if ($node->type == "NODE_TYPE" && yournewmodule_reached_post_limit()) {
form_set_error('form_name', t('You have reached your post limit'));
}
break;
}
}
function yournewmodule_reached_post_limit() {
global $user;
//Write code to do the following:
//-> Check which group $user belongs to
//-> Create query to see how many posts $user has made
//-> Return true if $user has reached the limit
}
I'm not 100% sure whether validate is the best hook to implement but it certainly is an option.