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
Related
I am trying to show here that Admin is a sub-class of User which is shown through the open triangle relationship connection. Is this enough to show that the sub-class relies on the main parent class to exist or would I then need to further apply composition? I have shown my example below. I am super confused regarding this. I feel it's enough to show it through the specialization arrow but I am not sure.
Is this enough to show that the sub-class relies on the main parent class to exist or would I then need to further apply composition?
Because of the generalization an Admin is a User, so if there is no User at all (User.allInstances()->size() = 0) then there is no Admin too. But of course you can have User(s) without having Admin.
If you just want to say that nothing more than the generalization is necessary.
But if you want to indicates an Admin is a User and there is 1 and only 1 admin you can do :
As you can see admin is a property of the class User (isStatic is true) because it is written underlined, no need to have it for all instances (including the admin(s)).
An other way to say the same without using an additional relation is :
Of course if you want to say there is at least one admin and not exactly one just use the multiplicity 1..* in the first solution or modify the constraint to have {allInstances()->size() >= 1} in the second solution.
I'd like to add another view to Bruno's excellent and accurate answer regarding generalization.
Yes, it is indeed sufficient to make Admin a specializatrion of User: this means that Admin is a User. It also means that Admin inherits User's non-private properties and operations (i.e. AuthenticateUser()). Finally it means that an instance a of Admin is also an instance of User and has hence a username and a password, although these are visible only to User instances. Unfortunately, once an object created as Admin, it will always stay an Admin.
Your hesitation about composition is therefore perfectly understandable: it is often advised to prefer composition over inheritance. You could perfectly imagine to have a User that has an Admin role, without Admin inheriting from User. But this is a radically different design. And in this specific case, it would be strange, if there wouldn't be other roles as well.
Last but not the least, it's worth to mention de decorator pattern that may combine inheritance with aggregation (instead of composition): In this design, you would make Admin a decorator of User: it extends the reponsibilities of the User with Admin responsibilities (i.e. with additional operations). But this can be done at runtime: you can create a User, add an Admin responsibility, or remove the Admin responsibility. THis is much more dynamic.
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
Every user has one or more roles, every role has one or more permissions. So far I can gather all permissions that are associated to a user via the roles.
The Problem
Some permissions have some constraints. For example:
A user can edit all posts that belong to his site, but no other posts.
Therefore the permission "edit post" should have this constraint.
Regarding the model: If the Constraints are related to the permission, I can't resolve which constraints are active for the particular user.
The user model can have an attribute like "site", but not all users, that belong to one site should have the constraint mentioned above. Some of them should be able to edit all posts.
Question
What is the best way to determine which constraint is active for a particular user. Do I have to split this into seperate permissions and integrate the constraints into the permission model or is there a better solution? I stumbled upon attribute based access control but I am not sure if I should switch to a completely different appoach
Any help is appreciated :)
I replied the following to a previous similar question
You want to use a solution that is agnostic of the type of application it protects. That's the goal of XACML, the eXtensible Access Control Markup Language.
XACML provides attribute-based, policy-based access control (ABAC and PBAC). This gives you the ability to write extremely expressive authorization policies and managed them centrally in a single repository. A central authorization engine (called Policy Decision Point or PDP) will then serve decisions to your different applications.
The minimum set of attributes you will need is typically attributes about the user (Subject), the resource, and the action. XACML also lets you add environment attributes. This means you can write the following type of policy:
Doctors can view the medical records of patients they are assigned to.
Doctors describes the user / subject
view describes the action
medical records describes the targeted resource
of patients describes the targeted resource too. It's metadata about the resource
they are assigned to is an interesting case. It's an attribute that defines the relationship between the doctor and the patient. In ABAC, this gets implemented as doctor.id==patient.assignedDoctorId. This is one of the key benefits of using XACML.
Benefits of XACML include:
- the ability to externalize the authorization logic as mentioned by Bell
- the ability to update authorization logic without going through a development/deployment lifecycle
- the ability to have fine-grained authorization implemented the same way for many different applications
- the ability to have visibility and audits on the authorization logic
HTH
The application is written in Ruby on Rails but the problem I am facing is more a design matter than language related.
the system provides service to a number of users to maintain a registry. So it relates persons to things. As such it has a model called Person representing owners and it has a model called User representing those who manage the registry.
Now a new requirement has arisen to allow People to log in and be able to change personal details which it was not required for the original design.
The question is how to refactor the application to allow this new requirement in?
One easy solution is to create Users for each person who request login credentials and link user to person entity but that is not very DRY as some fields such as firstname, surname etc. are in both classes and in particular, that is precisely the data people will be able to change. Besides User and Person are stored in separate tables.
The other possibility I was considering is to make one to extend the other but having data in separated tables it makes it a bit messy. Additionally the logical extension would be User <- Person as an user is (generally) a person but thinking on the implementation Person <- User is quite a lot easier.
One last option could be to scrap User and move login credentials into Person leaving logon fields empty for those who won't log in and half of the fields empty for those just login in.
Can you think of a better solution?
You could think about how this should ideally work if you were to write the application bottom-up, and then figure out how to make a reasonable compromise between that and your current setup. Here are some generic inputs.
As authentication is involved, you need an "Identity" that can be authenticated. This can be e.g. an email address and an associated password, with email verification.
An Identity can potentially be associated to multiple "Roles" and someone authenticated with the identity can choose which role to perform, e.g. "I am now an administrator" vs. "I am now a regular site user", and the role defines the user's current rights for the logged in identity. Or if you don't need that level of complexity, you can say that an Identity is a (single) Role.
You need some tracking between possible "Rights" and the Role the user is performing. E.g. the simplest setup could be the Identity or Role has some boolean can_edit_profile or can_modify_registry properties.
Whenever a user attempts to perform an action which requires certain Rights, it is simply a matter of looking up the corresponding rights set for the Role being performed by the user, to check whether the user is allowed to proceed.
For your application this may just involve adding a 'can_change_registry' property for your user objects, and check whether that property is True for any code accessing that part of the site.
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