How can i add some additional checking with the Resource Bundle to allow me to auto assign the new resource to the current User (also check they are logged in) and when editing check that the current user owns the resource?
Is this possible through settings or do i need to override each action in the controller?
Originally posted here - https://github.com/Sylius/Sylius/issues/5907
Just to summarize:
As I understood you have 2 cases.
First is to create a owned resource.
Best approach would be to decorate a default resource factory, where you will inject some UserContext to determine a currently logged in user. Or just pass it to the factory method as a second argument.
Second one is to update a resource. You want to allow editing of resource only to an owner? Some repository method, which would receive not only resource id, but also a current user will do the job. Then, you would have a method findByIdAndCustomer, so only allowed user would be able to access an editing page. Otherwise an error would be displayed. I guess it would be 404.
If this is what you want, you will end up with two overridden resources(custom factory and repository) and you will need to handle rest in yaml when defining a routing. No controller changes needed.
Some comparison of both approaches:
Resolving it with listener would be probably faster (only one class needed) and easier.
Managing it by event listener would not require any routing changes.
Overriding a factory will ensure, that this object will be always created with given user. Event is dispatched after creation, but before persisting it to the database.
Custom repository method will ensure, that the editing page cannot be even displayed by not-owner.
Both are correct. IMHO first is faster, second one is cleaner. Just decide what you need
You can use events fired by the controller for that. Have a look here: http://docs.sylius.org/en/latest/bundles/general/events.html
In the listener, you should inject the security.context service, which will allow you to check whether the user is logged in or not.
Edit: Please have a look at #Łukasz's answer, which contains alternative, a bit cleaner solution. ;)
Paweł is recommending events, as I also first, but Łukasz was suggesting some overriding of factory and repositories.
Although I agree both of them are correct and help the original poster to achieve his goal, I'm wondering what are the arguments behind both of them.
The solely purpose of this comment is the debate of these two solutions.
Related
OK, one may argue that there shouldn't be business logic in entity. But sometimes there is a good reason. For example when getting roles for a user, one may force a role to be returned by default from within getter method, for example as explained here.
Anyway, my question is in many documentation pages it is either done in the function which creates/updates user or with doctrine listener. For example as mentioned here.
Doing it manually every time is extra work, meanwhile using doctrine listener seems inefficient for something which will be used rarely.
So, I was wondering, why not encode the password within setPlainPassword() function in entity? always one needs to encode the password after calling this method anyway.
Next part of the question is how to access the encoder from inside the User entity?
Thanks!
I'm migrating a legacy PHP project (pre-OO) to Symfony2. On every request I have to:
compute some dynamic data (depending on the current date and/or some request parameter)
use that data (multiple times!) in the rendered response.
A naive approach would be:
At the start of every controller method, call some global helper function to compute the data.
At the end of every controller method, pass the data as a parameter to the twig template.
Sounds tedious. Maybe it would be better to:
Create a subscriber for request events that computes the data when a request comes in and provides access to it via getter methods.
Define that subscriber/service as a global twig variable in config.yml.
In twig templates, call the getter methods on that service as needed.
Is that viable?
In particular, are the twig variable/service and the subscriber always identical? Or could the service be a newly created instance?
Is this some sort of misuse? Or is there an officially recommended way for such a use case?
EDIT The data is not only needed in every twig template but in some controllers, too.
Calling a specific method in every Controller-Action would really be a bad solution. Your solution to use a subscriber isn't perfect either.
Without knowing your use-case in detail it´s hard to find a suitable way.
Maybe one approach would be to write a Twig-Extension and injecting a Service into this Extension. The Service would get the Request-Stack via Dependency-Injection and compute the relevant Data. You could then access this data "on demand" through the Twig-Extension during the rendering.
Another approach could be using sub-requests during the rendering (Symfony: How to handle common request scope data)
Maybe these tips already helped you a bit. Otherwise let me know more details, where / how you need the data during the rendering.
Let's say that in my ASP.NET MVC project, I have a ViewModel that is used on a form for editing a product. Among many other fields, I have a list of product types I want the user to be able to select from, in a dropdown.
When I map my domain object to my ViewModel, I'm calling a service to fetch the domain object, then using AutoMapper to map it to the ViewModel. To fill a dropdown for that list of product types, I call another service, which fetches that data from the database and uses it to populate another property on my ViewModel.
What I'm wrestling with is whether it's better to call that secondary service explicitly in the controller, versus potentially putting that call into a custom ValueResolver class and configuring my mapping to use it.
I like the prospect of removing the dependency on the product type service from my controller (because there are a lot of these, and the controller ends up with a lot of dependencies), but I'm worried that putting this sort of logic (which can hit the database) into a ValueResolver is an inappropriate use of a ValueResolver and might violate what I'd call the principle of least surprise. (I.e., I probably wouldn't expect mapping code to be causing database requests.)
Is this a common thing to use a ValueResolver for?
Answered by Jimmy Bogard on the AutoMapper Mailing List:
Yeah, it's definitely not uncommon. Drop-down list data sources....man, they're the toughest thing to figure out in our ViewModel world.
Keep in mind that you'll need to worry about the POST scenarios, refilling-in the information for validation failures, etc.
I am trying to determine the best way to implement the retrieval of detail records based upon the master's ID.
Obviously you would set up API controllers for both master and detail.
Solutions I've considered:
Have API consumers use OData to get all details filtered by a master ID. While I don't have an issue with this solution, I kinda feel bad putting that onto the API consumer and feel it is something that should be handled internally by the API
Go against the convention of just having the Get/Put/Post/Delete methods and create an action of "GetMastersDetails" on the detail controller and make it accessible via routing. While this would certainly work, I feel this gets away from the whole point of Web API (to an extent).
Create a 3rd controller named "MastersDetailsController" which would have a Get based upon a master ID with different possible return types:
Which would return a list of detail IDs which would then be used to call a Get on the details controller to get those actual details
Which would return a list of actual detail objects. What I don't like about that is having a controller returning a different type than what it is based upon.
Option 2 will be fine. Option 1 opens up a lot more risk depending on your scenario, and what you want to allow the user to get at.
It's not really "against convention" to add custom methods to an ApiController. You can do that however you like. It would only be "against convention" if you did so and used the wrong HTTP methods (i.e. a GET when you're deleting something in your custom method).
I'd go with either #1 or #2.
For #1, OData support enables not only the scenario you describe but offers a lot of additional functionality which might be desired in the future.
For #2, I don't think it gets away from the point of Web API's. Maybe a bit from a true RESTful service, but it's easy to implement and easy to understand.
My problem is quite simple - I think. I'm doing an ASP.NET MVC project. It's a project that requires the user to be logged in at all time. I probably need the current user's information in the MasterPage, like so; "Howdy, Mark - you're logged in!".
But what if I need the same information in the view? Or some validation in my servicelayer?
So how to make sure this information is available when I need it, and where I need it?
How much user information do you need? You can always access the Thread.Current.Principal and get the user's name - and possibly use that to look up more info on the user in a database.
Or if you really really really need some piece of information at all times, you could implement your own custom principal deriving from IPrincipal (this is really not a big deal!), and add those bits of information there, and when the user logs in, create an instance of the MyCustomPrincipal and attach that to the current thread. Then it'll be available anywhere, everywhere, anytime.
Marc
I've had exactly the same issue, and have yet to find a satisfactory answer. All the options we've explored have had various issues. In the specific example you mention, you could obviously store that data in the session, as that would work for that example. There may be other scenarios, that we've had, where that may not work, but simple user info like that would be fine in the session.
We've just setup a BaseController that handles making sure that info is always set and correct for each view. Depending on how you're handling authentication, etc, you will have some user data available in HttpContext.User.Identity.Name at all times. Which can also be referenced.
Build a hierarchy of your models and put the shared information in the base model. This way it will be available to any view or partial view.
Of course it has to be retrieved on each request since web applications are not persistent.
You should store this in Session and retrieve it into your controllers via a custom ModelBinder.
Not sure if I get what you want to ask, but if you are looking for things like authentication and role-based authorization, actually ASP.net is providing a great framework to work on/start with.
This article (with also 2nd part) is something I recently discovered and read about which is really good start with the provider-pattern which help to understand the underlying authentication framework of ASP.net. Be sure to read about the membershipProvider class and the RoleProvider class in msdn also, they together make a great framework on most basic role-base authentication to work with (if you are comfortable with the function they provided, you even don't need to code data-access part, all are provided in the default implementation!)
PS: Check out Context.Users property too! It stores the current authenticated user information.
HttpContext.Current.Users.Identity returns the current user's information. Though I am not sure whether it gets passed implicitly when you make a webservice call.