We have tasks, roles, and operations.
ok.
we have associated users with certain roles.
ok.
Now we have a method called doThis() on a given controller, that we wish to assign or allow, to a certain user, or role.
Where do we do that?
Your question is a bit vague, but I think this is what you're looking for:
http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#access-control-filter
Related
I have an application where each resource has multiple "sites". A user can have permission to access this resource for a number of these sites or none at all.
I have middleware set up that reads a user from a jwt and adds that user to the context. I then have an authorize attribute that simply checks for the existence of a user.
This is where I could use some help. I am not sure of the best way to conditionally restrict access to the resource (the condition being which site the end-user is specifically requesting the resource from).
I could break the resource into separate action methods and use an attribute that requires a specific role, but that feels a bit too much like duplication, I'd rather not deal with 7 endpoints that basically do the same thing, and adding new sites in the future will require adding a ton of new action methods.
Another solution I had in mind is to create an attribute/filter that compares the end-users permissions to the specific site that they are requesting. This sounds better but I'm not sure how to access specific arguments on the action method from the attribute. Also not sure of the best way to store all of a users "Roles" on an entity class...
Any insight is appreciated.
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.
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
This might be very simple; I don't know Rails very well.
I have a match myController/myAction/myID in my routes.rb that will direct hyperlinks to the proper page (using link_to). But here's the problem: I don't want people to be able to freely modify the id parameter, passing in via the URL whatever they like.
Is there a way to perhaps restrict access to routes to the link_to method only? Or maybe there's another way to go about this, using a passed in hidden variable param or something?
Users access you site via urls like: /controller/action/:id right? A user can change an id and must not view another non authorized resource. How to achieve this?, on your controller, return only those resources that user is allowed to access.
For example, suppose that you are using devise:
class AController < ApplicationController
def index
#resouces = current_user.find_all_by_id params[:id]
end
end
This way if the user tries to access something he does not have access to, he will get an error.
Hope this helps, if not please let me know and I'll try to elaborate.
About current_user, yes it is supposed to be the current logged in user, it doesn't have to be devise, you can implement your own session handling logic and then create a helper method to retrieve the currently logged in user.
About using devise, if you don't want to implement your own session handling logic, plus if you want features like:
remember me
already created views that you can fully customize
authentication
authorization
password encryption
many more (please look at the docs for further information)
Then devise is a good way to go.
Also, it is always a great idea, if possible and as a learning exercise, implement your own authentication and authorization layers, you won't regret.
Best regards
Emmanuel Delgado
I have created a forum, but have now found out that to create more traffic I need to enable anonymous users to add posts.
The idea is that a user who doesn't have an account, can write a post, and fill out the following fields (as you can with stackoverflow):
[UserName][Email][Message]
The datamodel is looking something like this (A bit simplified):
ForumThread/ForumPost: [Id][CreatedDate][Title][Message][UserId]...
User: [Name][Email][CreatedDate][Address][City]...
The question is now, what is the best way to extend the existing datamodel to support anonymous users. Anonymous users don't need all the fields as the regular users e.g. Address etc. The pragmatic way would be to create a UserType describing the different types of users, or I could use some inheritance of a user, but this requires quite a bit of redoing.
Is there a third option I have forgotten?
Add a Role property to the User and have Anonymous and Registered as roles. Leave the properties null that are irrelevant to anonymous users. Although personally, I would just refactor into subtypes.
Create a user in the Users table that is an "anonymous" user, and make anonymous posts under that user's userid.