Restrict access to database resources in Entity Framework + UoW + Generic Repositories - entity-framework

I'm using ASP.NET MVC3 with Entity Framework 4.
I am using the Unit Of Work + Generic Repository pattern.
I searched for similar question everywhere, I see that many people have my problem, but still can't find a good and practical solution.
We have a multi-tenant database.
Imagine a database with a similar structure:
customers
groups, associated to a customer
users, associated to one or many groups
And then, for each customer we have
resources, associated to one or many groups, and linked between each other with foreign keys, many-to-many relationships and so on
So, when a user logs in, he is associated to one or many groups, and he needs to have access to the parent and child resources associated to that groups.
Now the problem is:
I implemented a sort of pre-filtering with a .Where() clause into the unit of work, in the repositories, based on the id of the logged in user.
And this is working.
The pre-filtering I did on the repositories is working fine, but of course it works only if you access directly the repository of the sources of TYPE A or TYPE B or TYPE C and so on.
But a resource is linked to other resources with many-to-many tables and foreign keys.
So, it happens that sometimes a resource belongs to a group to which the user has access, but sometimes the resources linked to this resource belong to a group to which the user does not have access.
If I traverse the navigation properties of the "parent" resource, the user can access all the linked resources, even the one belonging to other groups.
So, if you are starting from a TYPE A resource, and traverse the navigation properties to reach the TYPE B and TYPE C resources, they are not filtered.
If you access the TYPE B and TYPE C repositories, they are filtered.
Now my filters, as I said before, are in the Unit Of Work class, but I tried to move them into a custom DBContext, applying the filters directly into the DBSet, but nothing changes:
It seems that EF is accessing directly the database to build the navigation properties, thus not using the other repositories or the other DBSet, avoiding the prefilter.
What can we do?
I see that NHibernate has Global Filters that could accomplish my task, so I'm evaluating a migration from EF to NH.
I see that many other people is asking for .Include() filters, thus disabling lazy loading.
Thank you.
I can provide some piece of code if needed, but I hope I explained my problem correctly.
Thank you i.a.
Best Regards,
Marco

I saw a solution with mapping to views and stored procedures, but I'm not sure how hard it was in development and maintanace. In short, it is possible to map EF model to views, where data will be filtered; in this solution each user have own database credentials.

Related

Entity Framework - What is Service layer's role in repository pattern

Currently, I'm working on an ASP MVC4 project using EF5 with repository pattern.
I have just joined this project.
In this project, we have implemented many repository class, these repository will responsible for search, update, delete etc using the dbcontext, they also return the DTO classes and in the service layer we use those repositories to get the DTO then convert to the view model.
Every time I want to do some logic with the entities, I will go to the repositories and write code here. So I wonder why we need the service layer and the repositories at the same time, we can write the logic code directly in the service layer or use repositories in the controller directly.
I don't see any advantage here since our source code is too complicated and we need so many classes (DTO, viewmodel...) and I think the performance will be not good compare to using repositories or services directly.
Can you point out the key here? Thank you.
It's very simple:
Repositories are for data access
Services are for business logic
But once you've started to instill business concepts into repositories it becomes very hard to turn the tide.
An example of how easily business concepts mingle with data access concerns is soft deletes. Let's say that there is a table journal_voucher from which rows should never be deleted, only inactivated. So there is a boolean (bit) field IsActive that's set to false if a row should be off the record.
Now it seems obvious to have a Delete method in JournalRepository that sets the IsActive flag in stead of deleting an entity. Likewise, any retrieval methods may automatically filter out inactive records.
Wrong. Being active or inactive is a business concept. For a data access layer the content of any database field is meaningless. It's only supposed to read and write it properly.
Now see what happens: other entities will probably just be hard-deleted. Maybe yet others can't ever be deleted, or, why not, never be created. If one repository has this active/inactive responsibility, the next obvious step is to implement these other CRUD rules in the appropriate repositories as well. Then a business requirement emerges that only records of the current year are interesting... Oh, and we have to check whether a journal_voucher can even be inactivated... And so on and so forth.
You end up with a host of very different repository classes and scattered business logic.
I believe that if you decide to use your own repositories on top of Entity Framework's repositories (DbSets) they should be generic repositories. That is: for each entity class they do exactly the same thing. It's even arguable whether they should return DTOs instead of EF entity objects (I'd vote for the latter).
Everything else is done in services. So there will probably be a JournalService that inactivates journal_vouchers, with proper checking. The service decides that IsActive is set to false and instructs the repository to update the entity. (In fact a unit of work should do that, but that's a different story).
This distinction has many benefits:
The rest of the world only communicates with services.
Therefore, repositories can safely return IQueryable. The services limit the amount of retrieved data.
It's much easier to decide where business logic involving multiple entities belongs (i.e. almost all business logic).
It is much easier with dependency injection.
The repositories can be mocked relatively easily and the services can be readily unit tested without duplicating business rules in mocked repositories.

Many domain models sharing one data context in EF 5

I recently, out of ignorance and lack of time, merged the domain models (POCO entity classes) from several projects into one 'DataModel' project, because I didn't want to duplicate dedicated DbContexts over all the projects. It struck me as ideal that something generic might be done, like a DbContext extension, to which one can add DbSet instances from various client projects.
I have read mention of such things, normally in the same circles as authors that contend - and I agree wholeheartedly - that the repository functionality is fulfilled completey by the DbSet class.
Can anyone offer any advice for building a generic DbContext which can exist in one project, where other projects can all have their domain models (sets of domain entities) registered with the shared DbContext, where they are all allocated they own DbSet to act as their repository?
building a generic DbContext which can exist in one project, where other projects can all have their domain models (sets of domain entities) registered
Interesting idea, but I'm not sure what you would gain by that.
For one, you'd never be able to simply type db.Customer (or similar). It should always be genericdb.Set<Customer>(), not knowing whether genericdb knows about Customer at all. (It may not have been registered).
Then, how should this registering take place? There are two ways to let a context map a class to a database model:
Creating a DbSet property in a DbContext-derived class and rely on code-first default conventions concerning table and column names, pluralization, etc.
Providing mapping configuration.
The first option defeats the purpose of a generic context class, so you'd have to register the domain classes by supplying EntityTypeConfiguration<T>s for each class in the domain, also for classes that normally could do without. (This should be done in the context's constructor, by the way.)
A further implication would be that somewhere you'd need a component/service that knows which groups of classes belong together and is able to deliver a coherent list of configurations. So, in stead of having dedicated contexts as an organizing principle out of the box you'd have to create your own organizer.
But back to the start. Couldn't you create a DAL that contains a DbContext factory that supplies the contexts as they previously existed for your projects? You don't have to duplicate dedicated DbContext classes this way.

Entity relationships design with JPA2

I have two entities, User and UserSetting. The obvious relationship between these two has User as the first rate entity which contains a set / list of UserSettings so when a User is loaded the settings get loaded too. E.g User 1-->* UserSetting
Trouble is that's not what I want. At the moment users only have a few settings but that won't always be the case and when a user is active in the system they typically only need access to a small subset of all their settings. What I want is to load individual user settings on demand. The obvious choice is to make the UserSetting list lazy load but that won't work as I want to use the User in a detached state.
My current "solution" is to include the User in the UserSetting object but that feels wrong as it makes the relationship UserSetting *-->1 User which feels like the UserSetting is the dominant entity. Is this the best solution?
Assuming my current solution is the best I can get will a delete of the User still cascade correctly?
There's 2 points here
First, if your User entity has an association towards UserSettings and that association can contain a lot of members which are not needed all the time, the right thing to do is configure it as lazyLoaded by default (via JPA2 mapping config) and then force an eager fetch on it only when you need to (i.e. in those situations you mentioned where you need the values of that assocation on a detached User Entity). Look at "join fetch" to see how to do this, it should be something like:
SELECT u FROM User u JOIN FETCH u.userSettings
If there's only a subset of those UserSettings that are needed often, you could make two associations in the User entity, such as userSettingsMain and userSettingsExtra, both lazy loaded by default, and just join fetch the one you needed on a certain detached User entity. Or, as a more advanced thing, you can make a Map association on the user settings, and have different keys for the important UserSetting, and the extra ones (such as i1, i2,... e1, e2, etc) and then eagerly fetch only those sets of keys that are needed, but this only works (at least at the moment) with EclipseLink JPA2, Hibernate's implementation just throws a big exception on Map associations (see my question here: Hibernate JPQL - querying for KEY() in Map association error on this)

Zend_ACL : How to design Role based ACL for multiple small teams?

How role based ACL should be designed for :
Multiple teams, each team consisting of one manager and multiple members and working from one location. Each location could have multiple teams and there are multiple locations.
Manager of each team could only view/edit data for his team members. A person could also be member of multiple teams, independent of location.
Location_1
-Team_1 -Team_2
-Manager -Manager
-Member_1 -Member_1
-Member_2 -Member_2
Location_2
-Team_1 -Team_2
-Manager -Manager
-Member_1 -Member_1
-Member_2 -Member_2
My thought: I'm thinking of separating it in two parts. Part 1: There should be one group for each team. Maintain table of group membership in database. Part 2: Now, each user can have any role. And ACL could be designed based on those roles. But data would be fetched based on Part 1. this way new teams could be added without change in code. Is this a right way to go?
Kind of a fairly chatty answer here, loose discussion only, no code, at least for now.
Your own model/data structure has to consider members, locations, and teams. I think you have described the relationships pretty clearly, so that should be straightforward. Thinking relationally: a table for team members, including managers; a table for locations; a table for teams with a foreign key into locations and a foreign key into members identifying the manager; a cross-ref table linking members to teams. I assume your member model will have methods for isManagerOfTeam($team), isMemberOfTeam($team), stuff like that. Pretty straightforward.
But much of this is just modeling the relationships, arguably independent of access-control.
For access-control, it appears that location is irrelevant; it's team membership and team management that are the key.
It also sounds like the data you are trying to access-control (what will eventually be the 'resource') will be tagged with a member id, identifying the "owning" member. So, the model for that data might have a method getMember() or even just getMemberId().
So I see some Acl rules that use a Zend_Acl_Assert_Interface instance to make dynamic examinations on the relationships between the role ($member) and those resources:
My_Acl_Assertion_BelongsToSelf
My_Acl_Assertion_BelongToMemberUnderManagement
Then the assert() methods could call the relevant model methods on the passed role and resource to check the team and management relationships.
Like I said, kind of a loose answer, but hopes it helps with some ideas.

ASP.NET MVC - I think I am going about this wrong

Or I don't understand this at all.
I have started my ASP.NET MVC application using the Controller --> ViewModel --> Service --> Repository pattern.
Does every type of object (Customer, Product, Category, Invoice, etc..) need to have it's own repository and service? If so, how do you bring common items together?
I mean there are a lot of the times when a few of these things will be displayed on the same page. So I am not getting this I don't think.
So I was thinking I need a ShopController, which has a ShopViewModel, which could have categories, sub categoires, products, etc. But the problem, for me, is that it just does not seem to mesh well.
Maybe ASP.NET WebForms were for people like me :)
Edit
So would an aggregate consist of say:
Category, SubCategory, Product, ChildProduct, ProductReview with the Product being the aggregate root?
Then in the ViewModels, you would access the Product to get at it's child products, reviews, etc.
I am using entity framework 4, so how would you implement lazy loading using the repository/service pattern?
Does every type of object (Customer,
Product, Category, Invoice, etc..)
need to have it's own repository
You should have a repository per aggregate root in your domain. See this question for more information on what is an aggregate root.
In the example you give I could see a CustomerReposiotry which would handle retrieve all pertinent customer data(Customer has orders a order has a customer). A ProductRepository that handles retrieving product information.
and service? If so, how do you bring
common items together?
A service layer is nice but only if there is added value in adding this layer. If your service simply passes straight into the repository it might not be needed. However if you need to perform certain business logic on a Product a ProductService might make sense.
This might not make sense
public void UpdateProduct(Product product)
{
_repo.Update(product);
}
But if you have logic this layer makes sense to encapsulate your business rules for products.
public void UpdateProduct(Product productToUpdate)
{
//Perform some sort of business on the productToUpdate, raise domain events, ....
_repo.Update(productToUpdate);
}
So I was thinking I need a
ShopController, which has a
ShopViewModel, which could have
categories, sub categoires, products,
etc. But the problem, for me, is that
it just does not seem to mesh well.
If the domain is flushed out the view model ends up making sense
public ActionResult Index()
{
ShopViewModel shopViewModel = new ShopViewModel();
shopViewModel.Products = _productRepo.GetAll();
//other stuff on the view model.
return(shopViewModel);
}
Update
What happens when you also need to
provide data unobtainable from an
aggregate root? For example, say I
have a create Customer view and in
that view, I also need to provide the
user with a collection of Companies to
choose from to associate a new
customer with. Does the collection of
Companies come from CustomerRepository
or would you also need a
CompanyRepository?
If a Company can live by itself (e.g. you edit, update, delete a company) I would suggest a Company is also an aggregate root for your domain (A Customer has a company and a company has a list of Customers). However if a Company is only obtainable via a Customer, I would treat a company as a ValueType/Value Object. If that is the case I would create a method on the customer repository to retrive all CompanyNames.
_repo.GetAllCompanyNames();
Repositories are indispensable, just go with them. They hide out data implementation. Used with an ORM you can pretty much forget about core db activity (CRUD). You'll find generally there's 1:1 map between an object and a repository, but nothing stops a repository returning anything it likes. Typically though you will acting upon an instance. Create non-object specific repositories for your queries that don't naturally fit into an existing one.
You will find a lot of conflicting arguments on the "Services" part of it - which some people like to split between Domain Services (i'd call these business rules that don't comfortably fit into a Core Domain Object) and Application Services (logical groupings of operations on Domain Objects). I've actually gone for one, separate project called [ProjectName].Core.Operations that lives in my [ProjectName].Core solution folder. Core + Operations = Domain.
An operation might be something that returns a DTO of all the information a View requires built via a number of repository calls and actions on the Domain. Some people (myself included) prefer to hide Repositories completely from Presentation and instead use Operations(Services) as a facade to the them. Just go with gut feeling on naming and don't be afraid, refactoring is healthy. Nothing wrong with a HomePageOperations class, with a method GetEveryThingINeedForTheHomepage returns a ThingsINeedForTheHomePage class.
Keep your controllers as light weight as possible. all they do is map data to views and views to data, talk to "Services" and handle application flow.
Download and have a look at S#arp architecture or the Who Can Help Me projects. The latter really shows a good architecture IMHO.
Lastly don't forget one of the major concerns of tiers is pluggability/testability, so I advise getting your head around a good IoC container (I'm a fan of Castle.Windsor). Again S#arp architecture is a good place to find about this.
You can pass more than one type of Repository to the controller (I'm assuming your using some kind of IoC container and constructor injection). You may then decide to compose some type of service object from all of the passed repositories.