How to Combine Data From Different Bounded Context in DDD - oop

Example:
I have two bounded contexts Exams and Courses. The Exams context has a Student entity that has information about the students to take an exam. And the Courses context has a teachers entity that contains information about the teacher teaching a course.
I also have an AuthService (purely CRUD), that is used for Authentication and Authorisation of users. The AuthService has an Accounts entity, which contains information like accounts user's name, address, phone number e.t.c.
Bringing them all together, The Student and the Teacher both have Accounts hence their information is already available.
I have a couple of question about this.
Is it anti-pattern in DDD to store the AccountId in the Student and Teachers Entity? If it isn't anti-pattern at what point is it ok to collect students account information using the AccountId, In repository or in the API controller, or should we use RPC/API calls.
Is it okay to copy the details needed from the Account entity into a Student or Teacher Entity?

I assume the AuthService is in its designated bounded context for authentication and, Accounts is in that same bounded context too.
Here are my answers:
Is it anti-pattern in DDD to store the AccountId in the Student and
Teachers Entity?
You can store AccountId in Student and Teachers entities. This is not an anti-pattern but rather opposite - this is how different aggregates refer to each other, by keeping the Id of the other aggregates.
If it isn't anti-pattern at what point is it ok to
collect students account information using the AccountId, In
repository or in the API controller, or should we use RPC/API calls.
I don't understand which repository you mean exactly, for Account, Student, or Teacher? Each aggregate root has its own repository and that repository is responsible for storing those aggregates only. It does not know or query other aggregates. If you need to query other bounded contexts, do that from the application layer - if the operation that does this is not a domain concern. If it's a domain concern, then do this in the domain layer by representing another bounded context as a domain service (interface). RPC/API is an implementation detail for the inter-bonded context calls and you can use either way to query another bounded context, as long as the implementation details don't leak into the domain layers.
Is it okay to copy the details needed from the Account entity into a Student or Teacher Entity?
That is also okay. You do that to achieve higher availability for the price of eventual consistency. In such a case, the bounded context/entity that holds information from another one acknowledges that the copy of the data can go stale but that is acceptable by the business terms.
Let me know if any questions. I am a long-run DDD practitioner.

I think you are in the wrong way. Something that is related to Authentication should not to be in the domain layer. Student and Teacher are entity, but Account in AuthService is not entity. As far as I see, you would like to add a new Student or Teacher by using some information that come from Account, but for doing that you should pass this information by fetching User Account info and pass them to Student or Teacher class to instantiate a new object.
For your second question, depends on our business, you could have same properties. DDD just emphasize that you should use ubiquitous language for naming entities and methods and it doesn't matter you use same properties.

Related

How to best leverage ASP.Net Core Identity for a unique form of multitenancy in a Blazor Server app

I am in the process of designing a Blazor Server app that sits on top of a single MSSQL db.
I have done a fair amount of research and learning on the subject but I am still very new to Core Identity, so I need to better understand how it is meant to be used so that I can properly design the Authentication and Authorization pieces.
The app will consist of organizations. Users can belong to one or more organizations and within each organization, can belong to one of two roles: Coach or Student. But the Coach in one organization could be a student in another organization, and a student could be a student of more than one organization. But all of this should be tied to a single user account/login. If a user belongs to more than one organization, they will be presented with a screen to select which organization they want to access after completing the login process. Once they have selected the organization, their activity and access will be limited to that organization.
What would be the proper way to handle this type of arrangement? Since one user could be a coach in one org and a student in another, are roles the proper way to handle that? Or would those be claims where for example I would store the ID of the organization as the value of a claim called "Coach" or "Student"? Or some other way?
Initially, I was planning to only use Identity for Authentication and then use my own custom logic to perform Authorization based on these criteria, but I don't want to reinvent the wheel if I don't have to.
Thanks in advance for your guidance and recommendations on this.

Keycloak authorization: Adding a Role to a domain object or an entity

I am new to the Keycloak framework and after writing my own solution painfully we are hoping to convert to KeyCloak. It seems to be a promising solution but unfortunately lacking self describing documentation. I have gone through the tutorials and the terminology, however, I can not seem to mold a suitable model for my authorization use case through Keycloak concepts. I posted my question! in Keycloak mailing list without any response so I decided to reach out here.
Please consider this use scenario:
You provide a SaaS solution for Car Dealerships.
Every dealership inherits a set of default roles upon creation e.g. admin, manager, sales, accountant,..)
Dealership could add/remove permissions to the default roles.
Dealership can define their own custom roles.
A dealership has multiple vendors and each vendor has a couple of roles (admin, accountant, vendor)
A dealership has numerous departments and each department may have their own roles for that department.
Basically you have different roles in different contexts.
In my built-in model, I have a table that connects a Role to a Principal (an entity) and the ACLs (or permissions) are assigned to the roles. The Principal could be any of "DealershipA", "DealershipB", "Vendor1" "Department0".
Now my questions is: What is the best practice to implement this scenario in Keycloak.
How would you add/assign a role to an entity?
Would you consider a Dealership, Vendor or a Department a Resource?
Thank you in advance for all your help,
IIUC this scenario could be achieved with different approaches, based on the level of KeyCloak integration you want to do. Let me try to articulate one such way. This could most probably be suboptimal, however you could probably use it as a starting point.
As a start, the Dealership could be considered as a tenant separator, so users in a single Dealership could be gathered to a KeyCloak Realm 1. A Realm groups users together and it sounds like a Dealership is a such separator (if users are indeed allowed to have access to different Dealerships through the same user profile, then this separation cannot be applied).
On to Roles, in one approach each Dealership, Vendor, Department role (admin, sales, acct etc) could be a Realm Role 2. These are Roles available to users in a specific Dealership. However I can't think of a KeyCloak native way to differentiate between Dealership roles vs Vendor roles vs Department roles. These could be differentiated through a naming standard perhaps (ex: vendor-admin)?
In another approach, each entity (Dealership, Vendor, Department) could also be a Group with own attributes and Roles [3]. One advantage could be that the relationship between the entities could be replicated in Group-Subgroup relationship.
sample-group-hierarchy
attributes-of-a-dept-group
This could give you a start on modeling the entities inside KeyCloak.
In authorization, it looks like you will be able to use the Authorization Services available in KeyCloak [4]. I haven't personally used this feature but if you want to rely on KeyCloak as the PAP, PDP and the PEP [5] this looks like the way to go.
For an example, users can be granted or denied access to resources on a specific vendor or department, since user information contains the user's group relationship. This seems like something achievable with a Group based Policy [6].
To give a more direct answer to the questions,
User creation process should make sure proper Role and (or) Group associations are made
Resources seem to be the services offered by each entity type (ex: add_vendor(), view_accounts())
Hope this helps to get a design going. Since most details are not clear at this moment, the design will have to be redone based on future requirements, but at least with a model to validate against you will be able to do it better.
1 - https://www.keycloak.org/docs/6.0/server_admin/#core-concepts-and-terms#realms
2 - https://www.keycloak.org/docs/6.0/server_admin/#realm-roles
[3] - https://www.keycloak.org/docs/6.0/server_admin/#groups
[4] - https://www.keycloak.org/docs/5.0/authorization_services/
[5] - https://www.keycloak.org/docs/5.0/authorization_services/#_overview_architecture
[6] - https://www.keycloak.org/docs/5.0/authorization_services/#_policy_group

Are there any approaches to use EF + DDD in the microservices architecture properly?

I've read a lot of topics about making ef core + ddd working together but they are only show an example where we have only one microservice. I stuck with solution about putting EF Core + DDD right where it's more than one. For example we have 1 database and 2 microservices (identity, schedule). In every service we have to keep own bounded context. Identity service only working with User, Role, ... tables... In opposite, schedule service working with User, Appointment, etc. Also, when we design a domain model we only using properties we need. So, in Appointment service for User entity I only need to use for example Id, NameDetails, Address, ContactInfo when in identity service I use Email, Password, etc. The question is: Should I use the different db context for each microservice? If yes, how I should handle migrations in that case?
Using one database for two or more microservices is a contradiction in itself. A microservice is supposed to be autonomous, meaning it should not share the same database with a different microservice.
If you need to reference a user-id for instance in two services, you would only store this id, whether it's an integer, a string or any other kind of key.
Your second database will not be able to validate the existence of that foreign key, since it doesn't know about the table where the Users are stored in.
You would want to create a single db-context for each service, that has it's own migrations and it's own database, when you really want to use microservices.
If you still want to use the same database to do that, you can create many DbContexts that actually point to the same database, but only define a set of entities.
In general there are different levels of domain-driven-design. You can do domain-driven-design without microservices and even without distributed systems. Keywords like Aggregates, Commands and Events, Distributed Systems are all part of domain-driven-design.
Some resources to read about domain-driven-design
https://stackoverflow.com/a/1222488/5397642
https://martinfowler.com/bliki/DDD_Aggregate.html
https://medium.com/withbetterco/using-aggregates-and-factories-in-domain-driven-design-34e0dff220c3
https://dev.to/designpuddle/apps--microservices--what-you-need-to-know-autonomy-and-the-challenges-you-will-face-39e1
I think that in this particular case User in Identity service isn't the same as User in Appointment service. I would make new Entity called, for example Person(with attributes such as NameDetails, Address, ContactInfo, DateOfBirth etc..) , in Appointment service and save it in separate database for that service (2 databases 2 services).

Designing a User Access/Permissions class

I'm working on a site, which will have several modules that either fully available to certain users, semi available to other users, and unavailable to the rest.
For example:
An 'employee' is able to respond to the customer support tickets assigned to him.
A 'Manager' is able to manage all employees and support tickets in his team, including viewing the tickets of a specific employee.
An 'Admin' is able to manage all managers, employees, and tickets in all teams, as well as some other core functionality.
In addition, on some pages there will be some additional fields shown if the current user is an admin or manager. (E.g links to delete/flag things). These won't be shown to employees.
I want to create one 'Permissions' model which will handle the logic for:
Determining if a user can access the current page or not.
Determining whether a particular part of a page should be displayed or not. (E.g special links for editing/deleting to be shown to admins and managers only).
I need some recommendations/advice for designing this class, particularly what methods it should have in order to accomplish the 2nd requirement.
The way I have approached this problem when it has come up is to give each action that can be taken or piece of information that can be shown it's own Permission. Each User then has a collection of Permissions. From this, you can add other layers of structure to help manage the huge number of permissions that will exist, such as hierarchies or categories of permissions.
Once that is in place, you can either have the various parts ask the User if they have the needed permission(s), or you can have a PermissionManager take a User and a set of Permissions and determine if the given user has the needed Permissions. Either way will work fine, but which one you choose has an impact on dependencies and the architecture of your system.
The PermissionManager approach has the advantage that your application pieces don't need to depend on a User, so you could use a different PermissionManager that always returns False if no permissions is appropriate, or True if all permissions is appropriate.
For simple situations, this approach can be overkill, and it often seems like it is at first, but I've gone the route of using basic hierarchical or coarse-grained Roles and fond that virtually every system I've worked on quickly got too complicated for most vanilla, pre-built Roles-based permission systems.
My approach to this problem from database point of view would be to have a user table which holds the list of users, a role table for the list of roles, e.g.: employee, manager, admin; and permission table which stores all of the values of every action/feature available in the system and its permission for a specific role, e.g.: say for admin, the values for actions/features like create, edit, delete, view are all true. The relationships can be seen below whereas (N) ---- (N) is a many-to-many relationship.
Users (N) ------- (N) Roles (N) -------- (N) Permission
My impression is that you would require to make use of roles e.g. employee, Manager, and Admin. So a roles table with these would do. Then for the particular actions/permisions you would have to make use of branching logic i.e. for example for the employee you will have
if User.IsInRole("employee")
// insert logic to deal with customer support tickets
else if User.IsInRole("manager")
// insert logic to deal with manager responsibilities
and finally logic to deal with admin responsibilities
So you need both the users table and the roles table to achieve this.
Hope it helps

Simple OO design: where to put the Add responsibility?

My application domain has Users. It also has Organisations. Users can create Organisations.
My question is On which controller should I put the CreateOrganisations method? Does it belong on the UserController? Or does it belong on the OrganisationController? And how do I make that decision?
In any case, I plan to have an Add method on the Organisation model.
Any thoughts?
It belongs on the OrganizationController.
The Organization controller should be managing any creation/change to the organization model. The user should have no knowledge on how or what is involved in creating an organization. If you give them the ability to create organizations you are coupling logic. You make this decision because you have both a User and a Organization Controller.
If your user/organization don't really justify existence, aka they aren't really controlling much then merge them into one.
If both classes exist I vote for organization.
Like you said, a User can create an organization, so unless the organization doesn't tracks the owner (unlikely), you should have the CreateOrganization method delegated onto the user. A basic idea I can think of would be like:
User: Creates organizations by calling OrganizationRepository::Add( OwnerId )
Organizations: Can only be created given the id of the owner.
If (and only if) you don't need to track the creator of organizations, then the idea of placing an Add method directly on the organization without requiring anything else looks fine.
Hope I can help!
David