how to make a dynamic roles in Symfony - symfony

I am a begginer, I would like to know if is possible to transform a roles in dynamic role like the #Route model.
/**
* #IsGranted("ROLE_{dance}_{level}")
* #Route("/{dance}/{level}", name="danceLevel")
*/
I have a project to make a website with some restrictions to accees to the content and I would like to throught by a interface like "easy Admin" to create a new category of dance and level that will be transform in role automaticaly
thanks by advance for your help

The security annotations would be for statically named roles and other permissions (checked by Voters).
You would be able to do more dynamic checks with:
$this->denyAccessUnlessGranted("ROLE_{$dance}_{$level}", $user, 'No access');
It's possible that a Security voter would be able to simplify the checks to what would be a static name and so used in #IsGranted (Or, it could for example, get the current $request, via the RequestStack service, to get dance and level parameters, if required).

Related

Shopware 6 Authorize customers

I would like to create a controller for providing downloadable files to a specific customer group. I need to authenticate the customer and check if they are authorized.
I checked the context and the HTTP header but I was unable to find valuable data about the customer.
What would be an appropriate approach?
I was able to retrive the customer using the SalesChannelContext.
I used
$event->getSalesChannelContext()->getCustomer();
To restrict access to your own route to only logged in customers you can use the #LoginRequired annotations, e.g.:
/**
* #LoginRequired()
* #Route("/account", name="frontend.account.home.page", methods={"GET"})
*/
public function index(Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
Under the hood the annotation will also check the current customer of the SalesChannelContext.
To get the customer group of the current customer, your proposed solution is the way to go:
$salesChannelContext->getCustomer()->getGroup();

#Security annotation and user parameter

In a controller, I have an action meant to display a user. The argument is the user to be displayed and is automatically fetched through a parameter converter.
Now I want to secure this action (displaying a user profile) so that only users with the USER_VIEW permission (currently implemented as a custom Voter) have access.
Using an #Security annotation it would look like:
/**
* #Security("is_granted('USER_VIEW', user)")
*/
public function showAction(User $user) {...}
This doesn't work because the user variable in the expression refers to the authenticated user rather than the action argument.
The documentation mentions that, but this is rather unfortunate.
How can I fix this issue and get my $user argument passed to the security expression? I could rename it, but perhaps there's something better to do.
I was also wondering if this should be considered a bug in Symfony, since 'user' is a rather common word, perhaps it should be renamed to something more specific such as 'authenticated_user' or 'security_user' or something. The same goes for the other 3 variables that are passed to the expression by Symfony: 'token', 'request', 'roles'.
Thanks.

Doctrine2 , generate on a fly the value of a Entity's attribute that depends on symfony2 container

I have an API, with an API call GET /users which returns me a list of users that all have a avatar_url field
in database this field is just the image name, and in the controller i'm then putting the base URL of my static domain serving images. So that it's only one URL to change in my conf , so the code works in staging/production etc.
but things start to get tricky with GET /comments etc. that all have sub-resource users that needs to have the url, so it means that currently every single point using users needs to have this logic, which is not very DRY
I would like to have something like that
// in my entity
use JMS\Serializer\Annotation as Serializer;
/**
* #Serializer\VirtualProperty
* #Serializer\SerializedName("url")
*/
public function getUrl()
{
return $this->container->getParameter('IMG_URL').$this->imgName;
}
so that regardless on how deeply nested my entity is, I will be able to seralize it with the property.
It seems to me it is possible to achieve something like as there's a bundle
https://github.com/KnpLabs/DoctrineBehaviors
which seems to achieve something similar
Check this out. http://jmsyst.com/libs/serializer/master/handlers
From what I understand you could create your own handler for the url serializer. By having the handler as a service written by you, then you can inject anything you want in it.
More info can be found at Creating a JMS Serializer handler in symfony2

Accessing Symfony2 global parameter in entity class

I have a value stored in my parameters.ini file, and I need to access it during the prepersist method of my model.
Normally I use $this->container->getParameter('value');, but the container is not available in the entity.
Is there a way to get parameters within an entity class?
P.S. The value is an API key for a service I am pulling info from during prepersist. Best practice is to keep keys/passwords in parameters.ini
Best practice is to use a service to persist your entity. This one would inject the container and set your parameter when you call your updateMyEntity() service method.
Inside your controller (or whatever you want):
$user = new User('foo');
$user->setSomeProperty('bar');
$userService->update($user);
Inside the UserService:
public function update(User $user) {
$user->setSomeParameter($this->container->getParameter('value'));
$this->em->persist($user);
}
In addition to Florent's answer, Entities are meant to be purely data objects. They should not know about any other variables or services within your application. I'm more curious about why your entity needs to know anything about an API key that is system-wide. With very little background information, I'd say you should rethink what you are trying to do.
You need a service to interact with the API, ideally configured through the container. I don't see what that has to do with an entity.

Sonata admin bundle, how to use entity repository classes

Using this code in PropertyAdmin extends Admin :
public function createQuery($context = 'list')
{
$user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser();
$query = $this->getModelManager()->createQuery($this->getClass(), 'o');
$query->where('o.Creator=:creator')->setParameter("creator", $user);
return $query;
}
I was able to limit "list" results to those who "belong" to logged admin ie. only Properties (that is an entity) created by logged admin.
The problem:
By manually changing the URL (id value like 1, 2...), I can edit Property that belongs to other user. For edit action, above query is not called at all. How to change that behavior?
2.Instead of putting query in controllers, can I fetch it from PropertyRepository class? That would keep logic in models for which I could write unit tests.
3.I am trying:
ProductAdmin extends AdminHelper {....}
AdminHelper extends Admin { .... }
But it fails saying "Cannot import resource "D:_development\rent2\app/config." from "D:_development\rent2\app/config\routing.yml".
AdminHelper is abstract class but Sonata still reads it. Any solution?
1.a) Use ACL for your objects, CRUD controller has permission checking.
1.b) Redefine edit action, make sure that user tries to edit property that belongs to him, something similar to Page Admin Controller, there create action is redefined
2) In controller $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository($this->getClass()); gives you access to repository registered for this model. Probably there are few other ways to get service container and entity manager from it.
3) To create your admin class you should extend Sonata Admin: docs for this, this problem does not seems to be related to sonata as for me. Can you please provide content for D:_development\rent2\app/config\routing.yml ?

Resources