0

I am currently reading about DDD and have a issue how to implement a certain validation.

Scenario:

I have an entity Group that contains a list of Members which in turn consists of a User and a MemberState (Member, Admin). The entity has a method MakeAdmin(User user) that turns a member into an admin.

The rule is: Only if the current user is admin of the group, it is allowed to turn the member to an admin.

I have three possible implementations in mind, with some caveats each.

Variant 1

Group enitity gets a dependency IUserContext injected via constructor to get the current user. With that the entity can check if the current user is admin and is allowed to switch the member state. Caveat: I don't like that the domain entity has such a dependency injected and I don't think that is correct in a DDD view.

Variant 2

Method MakeAdmin() gets an additional parameter which turns it into MakeAdmin(User user, User currentUser). That removes the requirement for the IUserContext dependency in the entity. Caveat: I am not sure if it is correct at all that the entity validates this rule, because it is not really an invariant of the entity.

Variant 3

Validate this rule in an application service, and only call MakeAdmin(User user) if validation passed. Caveat: I consider the rule domain specific, so I think it is not correct to put it in application layer.

So what would be the best option, or is there some totally different variant?

Creepin
  • 482
  • 4
  • 20

1 Answers1

0

My suggestion would be to go with your third option: Authorise access in the application/integration layer and then call into the domain.

This goes for any domain functionality really. The domain should not concern itself with whether the action may or may not be performed based on authorisation but rather only with domain concerns. If that authorisation action happens to be a domain concern in a particular Identity & Access Control bounded context that it would make sense but you would not run into those too often.

Eben Roux
  • 12,983
  • 2
  • 27
  • 48
  • I also tend to use option 3 at the moment. But I still struggle with this "kind of admin". It's not that admin like: "Only Mark Zuckerberg as technical admin of WhatsApp company can manage all groups on WhatsApp", it's more like: "Only the domain user who created the group (admin) can manage the group". So I consider it more like a real domain concept - the real users are confronted with these terms and behavior. So I don't know if it is correct if this rule is missing in the domain model and only validated in application logic. – Creepin May 29 '19 at 08:04
  • That is probably another level of authorisation. In your application layer you would check whether the current user is the "owner" of the group that administration was requested for; as opposed to something generic like `_authorizationService.HasPermission("system://group/manage")`. – Eben Roux May 29 '19 at 08:10