Where to put domain specific authentication interface

162 views
Skip to first unread message

Jeroen De Dauw

unread,
Mar 22, 2016, 9:53:31 AM3/22/16
to Clean Code Discussion
I'm working on a project that has Donation in its domain. Several Use Cases / Interactors that deal with a Donation need to do some kind of authentication check. For this I have a DonationAuthorizer interface, with these methods:

* public function canModifyDonation( int $donationId ): bool;
* public function canAccessDonation( int $donationId ): bool;

It is unclear to me where I should place this interface. As far as I can tell, its current location is not good, and my project has no good directory / package to put it into yet. I have these directories (amongst others):

* UseCases - subfolder per UC that holds the UC plus request and response models
* Domain - entities, domain services and stuff uses by those (this includes interfaces for repositories)
* DataAccess - implementations of domain repositories and services that bind to databases, the web, etc
* Infrastructure - generic subdomain stuff that is used by the UCs (but not the domain) and does not depend on the domain

Right now DonationAuthorizer, which was initially named just Authorizer (with Donation in its methods names), resides in Infrastructure, with its implementation residing in DataAccess. The interface being in Infrastructure adds a dependency from Infrastructure onto Domain, which I'd like to avoid. My first inclination was to just move it to Domain, which would solve this particular issue. However that would add knowledge of authentication to the domain, which it does not need. As the interface is only used by the UCs, putting it into some UC specific package would be nice. This package would be able to depend on the Domain, but not on the UCs, or anything further outwards in terms of Clean Architecture, such as DataAccess or Presentation.

Do you agree such a package is a good location to put the DonationAuthorizer interface? And if so, what would you call such a package?

Caio Fernando Bertoldi Paes de Andrade

unread,
Mar 22, 2016, 10:10:36 AM3/22/16
to clean-code...@googlegroups.com
I’ve faced this problem more than once, and I’d like to suggest a rephrase for the main question: Does authorization logic belong in the domain?

I don’t have a definitive answer to that question, and I’m not sure there is one. My two cents are more questions:

When we read business logic, is it important to always keep in mind who is authorized to do such and such actions? When we test business logic, is it too cumbersome to add authorization arrangements and asserts? When business logic changes, does authorization logic change with it? How about the opposite?

Depending on the answers to those questions (and I tend to believe they change from project to project), I follow one of the following approaches:

- Delegate authorization to a 3rd party library in the infrastructure layer.
- Create a Bound Context specifically for authorization inside my domain, used by Outer Usecases, Domain Services but not by Entities or Core Domain.
- Build authorization inside the domain itself.

I haven’t yet come to a conclusion about which is best, I reckon it depends on the project’s domain. I hope this helps you on your journey. :-)

Caio


--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at https://groups.google.com/group/clean-code-discussion.

Łukasz Duda

unread,
Mar 22, 2016, 12:01:46 PM3/22/16
to Clean Code Discussion
If use case depends on DonationAuthorizer interface, I'd put it close to the use case. Does anything else depend on this interface?
Can you give an example implementation of canModifyDonation?

Łukasz Duda

unread,
Mar 22, 2016, 12:12:48 PM3/22/16
to Clean Code Discussion
What's the difference between domain service and use case?


W dniu wtorek, 22 marca 2016 14:53:31 UTC+1 użytkownik Jeroen De Dauw napisał:

Jeroen De Dauw

unread,
Mar 22, 2016, 12:13:03 PM3/22/16
to Clean Code Discussion
> If use case depends on DonationAuthorizer interface, I'd put it close to the use case. Does anything else depend on this interface?

The only consumers of the interface are use cases. There are multiple use cases that use this interface though, not just one.

I agree with putting it close to those use cases. However I do not want to put it into my UseCases folder, as this is not a UseCase itself. It is also not a dependency of a specific UC, so I cannot put it into the dedicated UC sub-folder.


> Can you give an example implementation of canModifyDonation?

The relevant high level info here is that this code binds to the database and is initialized with a token coming from the HTTP request in a controller. In case you want to look at the actual code, you can find it here: https://github.com/wmde/FundraisingFrontend/blob/678837a09d7414a5de41157768c133d63949b1e2/src/DataAccess/DoctrineDonationAuthorizer.php

Łukasz Duda

unread,
Mar 31, 2016, 4:10:27 AM3/31/16
to Clean Code Discussion
You could create folder for donation use case family (a kind of bounded context), for example:
  • FundraisingFrontend/src/UseCases/DonationUseCases/
    • DonationAuthorizer.php
  • FundraisingFrontend/src/UseCases/DonationUseCases/ShowDonationConfirmation
    • ShowDonationConfirmationRequest.php
    • ShowDonationConfirmationResponse.php
    • ShowDonationConfirmationUseCase.php
  • FundraisingFrontend/src/UseCases/DonationUseCases/CancelDonation
    • CancelDonationRequest.php
    • CancelDonationResponse.php
    • CancelDonationUseCase.php
Reply all
Reply to author
Forward
0 new messages