Nested authorization support in Symfony2 - php

A system has nested resources. For example
Farm HasMany Sectors
An example object relation will be like below
farm1 => [sector1]
farm2 => [sector2, sector3]
Now say, user1 has read,write permission on farm1.
user1 Has(read,write) on farm1
I need the system to automatically use the access for all the nested resources of farm1, in this case sector1.
In other words, something like user1.hasWritePermisson(sector1) should return true, though the ACL is actually stored with farm1. I need this even to work on the nested resources of sector and so on.
A straightforward solution would probably be to copy the access to all of the children objects of farm1 at the updating its acl. But I believe this would be a really inefficient one if farm1 contains thousands of sectors.
What would be the best way to achieve this in symfony2?

First of all. I think your question has nothing to do with SF2. In my opinion, you should create a efficient database which helps you to do the task. The rest is only a few queries away.
As I understand, it will be 3 major objects: User, Farm and Sector.
User could be in many Farms and Farms could be seen/wrote by many users
A Farm has many sectors, but a sector can only be in one farm
That being clarified, you will also need to declare the permissions for every user has in a farm. But, this will be declared in the many-to-many relationship with two relationship properties (read, write).
Once everything well designed, you should be able to create queries that satisfy your needs.
I know it's hard to understand because I'm talking in abstract, but let me know if you don't understand and I will draw you a scheme.

Related

resource items total count calculation (separate query vs collection)

im struggling with finding the best way to get total items of items when returning a resource collection im thinking of two approaches just want your opinion regarding whats best ?
scenario :
a user want to retrieve list of 10 vehicles from my 10000 vehicles with some cursors such as (limit, before, after, filters, etc ...)
option 1:
class VehiclesRepo()
{
function getVehicles(){
// get 10000 vehicles with one query; : returns collection
// return 10000 vehicles and do filtration on transformation layer to keep total_count of vehicles
}
}
option 2:
class VehiclesRepo()
{
function getVehicles(){
// get 10 vehicles with one query including filtration; : returns collection
// return 10 vehicles, and do another query for total_count
}
}
please consider operation effect on memory, cpu circles ? also my system is fully ddd so im trying not to have a domain leaks
im trying to do that without having to access infrastructure layer
from outside the domain
That's actually your problem. DDD aggregates are designed around command processing, transactional consistency and business invariants, not querying needs.
That's why CQRS is so popular these days. I would strongly advise you not to rely on your domain model for query needs.
Both options are basically ok, but I think with 10'000 vehicles you have already a performance problem if you use option 1. So I'd go with option 2.
But there is probably another problem with your design:
I'm trying to do that without having to access infrastructure layer from outside the domain.
This comment suggests that you have the following layering:
Application
⇣
Domain
⇣
Infrastructure
If you don't use some kind of the Dependency Inversion Priciple that actually makes the infrastructure dependent on the domain layer, then you have a problem with this design. The domain should be as pure as possible. If the domain has a dependency on the infrastructure, this means that you cannot use your domain model independently of the infrastructure. This is bad, because the infrastructure is an artificial thing that does not exist in the real world of your domain.
So what you should do conceptually is this:
Application
⇣ ⇣
⇣ Infrastructure
⇣ ⇣
Domain
Then your repository implementations become natural and allow query operations like e.g.:
Give me Vehicle with ID X
Give me all Vehicles with more than Y wheels
Give me all Vehicles that match the filter Z
Note that these query operations should return actual business objects, not DTOs or database rows or alike.
If you want to read more about pros and cons of different architectures with DDD, I suggest you read the chapter "Architecture" in Implementing DDD by Vaughn Vernon.
Note on #plaxl's answer: The answer is specific to CQRS, which you don't mention in your question with a single word. So outside of a CQRS context, using the domain model for query operations is perfectly fine.

domain driven design proxy, cheating?

I am quite new to DDD and have some fundamental problems that i cant really understand.
Consider we have a User entity. A User has some Friend's (one to Many).
There are 2 possible solutions to fetch the friends.
Solution 1:
user.getFriends()
The Problem here is that all the friends have to be loaded or I am forced to use a Proxy.
If i use a Proxy it feels for me like cheating because the entity must not have an instance of the Repository. Can the Proxy have one?
Solution 2:
Avoid the getFriends Method and load the Friends Based on the User Repository, like:
userRepository.getFriendsOf(user)
This could sometimes be a good idea, but where to stop here? Whats about an AddressRepository for accessing user Addresses, or ?
I think you should look at it from perspective of Aggregate Roots.
In case of user.getFriends() - the user seem to be AR with associated friends which I don't think is correct. The definition of AR says "that we treat as a unit for the purpose of data changes". Friends are outside of the Boundary of user AR.
Considering the above the other option seem better - userRepository.getFriendsOf(user)
I'm not sure that either of them are correct. I think from a DDD point of view, the code is supposed to use the Ubiquitous Language of the domain. In that regard, getters are frowned upon.
Why are you getting the friends of a user? The public methods of User should reflect the ubiquitous language.
For example if your domain is a social networking site, users should have methods to update status which will internally notify friends etc. How the User knows who its friends are or how they are queried is hidden as an implementation detail.
One thing to keep in mind is that you shouldn't use your domain model for querying. So you do not want to be lazy-loading or applying any other fetching strategies.
You also need to identity your aggregates. An aggregate is loaded in its entirety from the data store.
In your case if a Friend class can only ever exist in the context of a User then it is part and parcel of the User and its life-cycle is linked to that of the User. That means that when the User is deleted (conceptually, as one probably would not want a hard delete) then the associated Friend instances are deleted also.
So if a Friend represent the association between users then it probably only contains the User Id. So you could go with a list of Ids in that case. This would depend on your domain.
I would guess that you very rarely would need to load the entire list of User instances that are friends of another user. If you need related data you could implement a light-weight query layer.

Row level permissions and Laravel app structuring

I'd like to ask other opinions about code structuring of business logic on Laravel applications, mainly regarding permissions at the row level.
For those that don't know it, Laravel is a MVC framework for PHP, much like Rails.
For the sake of understanding, let's suppose a multi-tenant application where each user has his own albums and pictures, so far so good.
Now, each user can invite others to collaborate (by uploading photos) into his album.
Both, the album's owner and collaborator that uploaded the picture may be able to delete or update information about that picture.
Only the owner may edit the album and invite new collaborators.
Collaborators can remove themselves of the album if they want so.
Pinterest should be a nice example of something similar, but our application is probably 3 or 4 times more complex.
The question is: where should I handle that kind of logic?
Laravel proposes the approach of having repositories, entities and services, which I don't fully understand, probably because of the lack of good examples. So the obvious first choice to meet those deadlines was to put it all on controllers (ew!). Now, digging into refactoring, there are many possible ways to un'spaghettize our code:
I've seen people implement ACL at row level (looks kinda dumb and overkill)
It would be possible to turn models into behavior aware objects and not only data containers, something like $album->add_photo($photo) and check permissions at that function
It would also be possible to override model's save method and do there those checks
Or, follow the Laravel proposed road of having separate layers of concern
I suppose that having methods like $album->can_be_edited_by($user) may simplify the displaying of 404 erros on routes not allowed, hiding view's links as well as validating before saving the models
Which would you recommend, and does anyone know any simple, but understandable, example of repositories, entities and services not using .NET?
Thanks!
Edit: I guess that a full ACL system would cause excessive overhead, since there may be thousands of resources associated with each user, but only one role per kind of association. For instance, pictures will have an uploader_id and albums will have an owner_id.
I could be wrong but I think ACLs are OBJECT based permissions (i.e., a user can or can't delete photos in GENERAL). What you want is more custom MODEL based permissions (row level like you said), i.e., a user can delete photos that they themselves created (SPECIFIC ones).
Most Laravel packages are designed for object based permissions I think, but not https://github.com/deefour/authorizer - this one is a great hidden gem. We don't use it in our project but I found that it really covers all the bases we'd need.
We have really advanced model permissions on our app, I have them scattered throughout my models, but I take a very model centric approach, which isn't necessarily very "laravel-esque". In your example with delete, I would override the delete method in your model or listen for the eloquent event and prevent it there. If you have to prevent read/write on certain attributes you could even do that by extending your validator or using custom mutators/getters, serializers or listening on events. More on where to add business logic in my question/answer here: https://stackoverflow.com/a/27804817/796437
I'm still trying to find the best approach, if I do I'll update this - but thought I'd post.
In Laravel you can use Policies or use solutions, like Symfony Voters.
For Laravel exists same package - Laravel Simple Voters.
Using this, you can check access to custom objects, looks like this:
Access::isGranted('edit', $post) // current user can edit this post?
You can put this logic, to example, into middleware, if you wish check requests to controllers.

Can you have too many models in a PHP mvc?

I'm currently creating my own PHP mvc for a site that I run so that it will include just the code needed yo be as light and fast as possible.
The site has quite a large range of functions and user features so working out which actions go where in which models controlled by which controllers is starting to get quite complex.
Example
Say I have the following member features
Favourites
Friends
History
Each of those can be controlled by the membercontroller but then my question is whether to have them all inside one model or a model for each.
Each of those three has sub many actions such as:
Add to favourites
Remove favourites
Show favourites
Add to history
Remove history
Show history
Add as friend
Remove friend
Message friend
...etc
At the moment I'm thinking a model for each (favourite, friends, history) is probably the best way, but can it get to a point where you have too many models?
At the moment the whole site has 6 controllers, 17 models and 25 views
Yes you can technically have too many models, there is a limit (as always) of how many classes can exist in PHP. But it's pretty large, so keep on going. You can not only have many but also different kind of models at once. So keep on going, don't restrain your coding by thinking there might be a limit you don't see so far.
So not the count of files, but how nicely written your code is, e.g. is everything grouped properly that belongs together? See as well Domain Model.
I suggest you let ModelController deal with actions that somehow modify Model.
I.e. FavoritesController deals with adding, removing and showing favorites (stored on FavoritesModel). Keeps your controllers lean/slim, is a lot easier to test (less methods) and keeps logical app parts together.
Also, you could divide the application into smaller apps that deal each with:
Auth/Login
Social/Sharing
add/read/show articles (main app)
In such scenarios there is no "right" answer, so all I can give you is my own interpretation. I would use a service to do bind one or more models together. So, a User service would use the User model and the Favourite model to manipulate and display user favourites.

Aggregates and Repository. How to determine aggregates?

I have recently been looking at the Repository Pattern as a way of brushing all the details of persistence under the carpet where the client code is concerned. While reading around it appears that a Repository is/can be [usually?] responsible for aggregates rather than just straight-forward classes.
This make sense to me as you could have a class defining Posts and another defining Comments. This makes an ideal candidate for an aggregate since the two are very closely related. However, how would I represent a Users class and its relationship with his or her Posts?
Would it make sense to aggregate Users with the Posts/Comments aggregate, or keep Users by itself and simply have an association via a good old fashioned reference?
I have tried looking for the answer myself using Google, but a lot of the examples I find are just stand-alone. ie, Posts/Comment or maybe Order and OrderLine etc. I can't find anything that shows how other related classes fit together.
I am not applying this to anything specific, though PHP or Java/C# would probably be the area I would look to using these ideas. In any case I am just exploring and trying to get my head around some of these ideas and concepts before I run off and create a monster. :)
Thank you for your time.
The Repository Pattern is fairly loosely defined and does not necessarily have any relationship to the Aggregate Pattern. However, if you subscribe to the DDD way of doing things, then yes, repositories are unique to aggregates.
So let's have a look at this from the DDD point of view. DDD says that objects within an aggregate can have a reference to another aggregate root, but objects within an aggregate can only be accessed via the root. The rule of thumb for determining aggregates is what should be deleted when deleting the root. However, DDD discourages the use of relationships more than most methodologies saying that just because a relationship exists in a domain, it does not need to exist in your model of the domain, so just keep that in mind.
In your case, when you delete a post I assume that you would also delete the comments, but not the user who created the post or users who commented on it. Therefore, you are correct in defining the post/comment aggregate, but it would not make sense to group users into that aggregate.
Users, being its own aggregate, can contain a relationship to all of their posts, because Post is the aggregate root. You could also implement this a method on the PostRepository to get all of the posts by a given user. Hope that helps!

Categories