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!
Related
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.
I have an entity (eg Image) which is related to many other entities (eg Product or Category). I would like to know which is the best way to prevent the removal of an entity if a relation exists somewhere else (eg I should not be able to delete an Image if it is related to a product). My thoughts are either searching for relations in a repository class and returning results, or doing 'something' at the preRemove lifecycle event of the entity. Which is the best Symfony2 way for preventing removal of related entities?
As long as cascade delete is not set, any directionally entity will prevent delete of the related entity. If your associations are not birectional, you'll have to query form the backside as well.
To expand upon CJ's answer, you may remove delete links, but you will also have to check the entity in controller as well, because any url hacker can delete an object if its id is known.
What I would suggest is you can better of disabled the form delete link when there is a relationship between entities. In that way you can even make the customer understand that there is related entity and he should not remove it before removing the relationship.
You can always check the entity before deleting it and when you actually call certain process in symfony on an entity you actually work on the entire object of that particular entity which gives access to all the values of that entity. So you can check it at that particular point and make conditional statement.
It my personal believe that you should not try to import excess library functions for minor things which can be achieved by you without them. this would make you code easier to understand and even lighter as the prospect for including extra libraries which will most likely have more than what you need
We're developing a business ASP.NET application. Is it better to pass an entire entity to a method or pass each property of this entity as parameters? What is the best practice?
Case 1. Pass Customer entity to a manager - InsertCustomer(Customer cust)
Case 2. Pass each property as a parameter - InsertCustomer(string name, string address...etc)
P.S. We're using Entity Framework as our data access layer
Pass the entire entity, not only for reasons given in the other answers, but generally methods with long parameter chains are bad. They are prone to error, and tough to work with from a development standpoint (just look at Interop with Office)
In general, if I see I am getting too many parameters (usually more than three), either I have a method trying to do too much, or I explore ways of encapsulating this data in a struct.
You should pass the entire entity as when you update the entity, e.g. add or remove members you do not have to update all your method calls in all your layers. You only need to change your datalayer and the layer where you are consuming the entity. asp.net is Object Oriented and therefore you should orientate your code around your objects
The whole concept of object orientation requires objects to be passed around. If all is happening internally I would go with this.
If this is being posted to a webservice / across a network etc you would need to serialize, and hence may find it better to pass each individual parameter, especially if the receiving framework is different.
Don't forget your Strings etc are all objects too.
I agree with another poster, passing a whole entity "encapsulates" everything so that it can be updated/modified so you have less to worry about.
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.
How do you properly ensure that a user isnt tampering with querystring values or action url values? For example, you might have a Delete Comment action on your CommentController which takes a CommentID. The action url might look like /Comments/Delete/3 to delete the comment with the id 3.
Now obviously you dont want anyone to be able to delete comment 3. Normally on the owner of the comment or an admin has permission to do so. Ive seen this security enforced different ways and would like to know how some of you do it.
Do you make multiple Database calls to retrieve the comment and check that the author of the comment matches the user invoking the delete action?
Do you instead pass the CommentID and the UserID down to the stored procedure who does the delete and do a Delete where UserID and CommentID equal the values passed in?
Is it better to encrypt the query string values?
You don't.
It is a cardinal rule of programming, especially in this day and age, that you never trust any input which comes from the user, the browser, the client, etc.
It is also a cardinal rule of programming that you should probably not try to implement encryption and security yourself, unless you really know what you are doing. And even if you do know what you are doing, you will only remain one step ahead of the tard-crackers. The smart ones are still going to laugh at you.
Do the extra query to ensure the logged-in user has the right set of permissions. That will make everyone's lives just that much simpler.
Enrypting and decrypting query params is a trivial process and there are some great examples of how to do so using an HttpModule here on StackOverflow.
"You Don't", "You can't", or "It's not easy" are simply not acceptable responses in this day and age...
Vyrotek: The input method is not important. GET, POST, encrypted/obfuscated GET - no real difference. No matter the way your application receives commands, to perform an administrative action it must make sure that the issuing user is allowed to do the stuff he wants. The permission check must take place AFTER the command is received and BEFORE it gets executed. Otherwise it's no security at all.
Consider using technique outlined in Stephen Walther's article Tip #46 – Don’t use Delete Links because they create Security Holes which uses [AcceptVerbs(HttpVerbs.Delete)]
You can also allow only Post requests to Delete controller action by using the Accept Verbs attribute as seen below.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int? id)
{
//Delete
}
Then you could also use the antiforgery token as discussed here:
http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
I've done funky things take the querystring, compress it, Base64 or just hex encode it, so that "commentid=4&userid=12345" becomes "code=1a2b23de12769"
It's basically "Security through obscurity" but it does make a lot of work for someone trying to hack the site.
You cannot easily do this.
I have fond memories of a site that used action urls to do deletes.
All was good until they started search crawling the intranet.
Ooops, goodbye data.
I would recommend a solution whereby you do not use querystrings for anything you do not wish to be edited.