I have a RentalProperty class which looks something like this:
class RentalProperty
{
Money MonthlyRent;
List<MaintainenceCall> MaintainenceCalls;
}
From my understanding, using DDD to change the MonthlyRent, I would get the RentalProperty, change the MonthlyRent property, and call RentalPropertyRepository.Save(). The same process would be handled to add a new MaintainenceCall.
The problem I have is that, for example, a Handyman should be able to add a MaintainenceCall, but should not be allowed to change the MonthlyRent. How should I implement this (as well as other similar) security policy?
Amongst the techniques introduced to manage the complexity of the application development process is Domain-driven design (DDD). DDD prescribes a specific application of separation of concerns to the application model into a domain model and DDD-services.
An aggregate is a domain-driven design pattern. It's a cluster of domain objects (e.g. entity, value object), treated as one single unit. A car is a good example. It consists of wheels, lights and an engine.
Domain-Driven Design(DDD) is a collection of principles and patterns that help developers craft elegant object systems. Properly applied it can lead to software abstractions called domain models. These models encapsulate complex business logic, closing the gap between business reality and code.
In short, you should apply this business rule directly in your model. In your case, directly in the MonthlyRent getter and setter property. We all know how complicated that can get with lots of checks and security levels; so, that is what Specifications are for.
The DDD playbook introduces the concept of Specifications, for exactly this purpose of focusing the light on the model itself. You first setup your getter and setter like described above to get the functionality. Then, during your refactoring, look for making the model cleaner by abstracting the long getter/setter code into Specification classes.
Employee employee =
employeeRepository.findEmployee(employeeID);
Specification employeeCanModifyRent = new
Specification(
new EmployeeHasAccessToManagement()
, new EmployeeHasAccessToMoney());
if(employeeCanModifyRent.isSatisfiedBy(employee))
{
rentService.changeRent();
}
else
{
throw new exception("Access denied.");
}
Reading the code makes it very obvious to exactly what the code does. This is the core DDD concept in itself. Specifications should be kept very simple, and straight forward.
This code comes from Domain-Driven Design Quickly, a short and quick read for DDD quickly. It really is a short-n-sweet book on DDD that warrants a read over a few hours. Just 100 pages or so.
AOP. PostSharp is really slick for stuff like this.
Because security is really a cross-cutting concern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With