permissions and authorization

In my app I have 3 different models in a linear fashion:

M1, M2, and M3. M1 has many M2 which has many M3.

M1 has 2 properties: private and completed. If it's private then only the person who created M1 can do anything with it (all the rest actions), and if it's completed then more M2 and M3 cannot be added.

For M2, only the M1 creator and the M2 creater (the M2 creator is most likely a different person) can do anything with it (rest actions), and the same goes for M3 except the people who can do anything with M3 are the owners of M1, M2, and M3.

It seems these permissions are really complex and I'm not sure how I should go about this. Before I just had protected methods in each of the controllers of these models, but theres a lot of repeated code and its just not pretty to look at. Should I abstract some of this into the ApplicationController, or create a module/helper for this?

Look at CanCan or Aegis as gems that deal with authorization. Your matrix isn’t all that complicated as a model of permissions :slight_smile:

I'm using CanCan right now but I don't see any options for it to help me with these kinds of permissions. Or can it? I read through the little readme on github and didn't see anything.

Ah. Well, I favour Aegis (mainly as I discovered it before CanCan) and it certainly does support custom permissions, and complex conditionals when required in a permissions evaluation.

Regular controller authorization in my Permissions.rb file such as:   resources :environments do     action :index do       # everyone can access the index page       allow :user       allow :admin     end     action :show do       # users can only see environments they're allocated to       allow :user do         user.environments.include? object       end       # admins can see environments they're allocated to, or that they're administering       allow :admin do         user.environments.include?(object) || user.administering?(object)       end     end   end

...which lets me do "current_user.may_show_environment?(environment)" in a controller, view, wherever.

Or a custom permission:   action :view_all_evidence_for_control do     # flatly only allow admins     # (or have big case statement that evaluates true or false depending on future criteria)     allow :admin   end me "current_user.may_view_all_evidence_for_control?(control)"

Unfortunately, I can't tell you how to do the same with CanCan... just that I *thought* it was almost equivalent.