multiple conditions to user in declarative_authorization if_attribute
I have 4 different levels of access; admin, partner, employee and client. Admin, Partner, and Employee have administrative access over clients. Basically开发者_如何学编程 what I have done is created a Rails app where clients can upload documents to their vendor (partners). Everything works great except for the client level access. I have two codes; partercode and client code. Partners can only see files where the file's partercode field equals the partner's partner code. This works just fine. However, the client can only see files where the partnercode matches and the clientcode matches. Below is my client section. What is working is that the client IS only allowed to see the partercode files, but it is setting them see other clients that belong to the partner. (by typing in the number in the URL). I doubt this would ever be an issue, but it's a security hole that I would definitely want closed.
role :client do
has_permission_on [:users], :to => [:client, :edit, :update] do
if_attribute :username => is { user.username }
end
has_permission_on [:documents], :to => [:client, :new, :create]
has_permission_on [:documents], :to => [:client, :index, :show, :edit, :update, :destroy, :documents] do
if_attribute :partnercode => is { user.partnercode }, :clientcode => is { user.clientcode }
end
end
I don't think nesting the if_attribute
statements actually works like that. Declarative_authorization by default joins these if_attribute
statements with an or
statement, but if I understand correctly you want them joined with and
. The way to change this is to set the :join_by
attribute to :and
.
role :client do
has_permission_on [:documents], :to => [:do_whatever], :join_by => :and do
if_attribute :partnercode => is { user.partnercode }
if_attribute :clientcode => is { user.clientcode }
end
end
source: http://www.tzi.org/~sbartsch/declarative_authorization/master/classes/Authorization/Reader/AuthorizationRulesReader.html#M000184
I found the answer. The answer, ironically, was in the tags of this question; nested.
role :client do
has_permission_on [:users], :to => [:client, :edit, :update] do
if_attribute :username => is { user.username }
end
has_permission_on [:documents], :to => [:client, :new, :create]
has_permission_on [:documents], :to => [:client, :index, :show, :edit, :update, :destroy, :documents] do
if_attribute :clientcode => is { user.clientcode } do
if_attribute :partnercode => is { user.partnercode }
end
end
end
Once I validate that the clientcode is correct then create another do .. end to check the partnercode.
:join_by
works, but my issue with it is that sometimes you need both AND
and OR
. You can specify multiple if conditions, on a single line as different arguments. These will be compared together using AND
whereas each line is evaluated with OR
.
role :client do
has_permission_on [:documents], :to => [:do_whatever], :join_by => :and do
if_attribute :partnercode => is { user.partnercode },
:clientcode => is { user.clientcode } # These two are evaluated with AND
if_attribute :some_attr => is { some_val }
end
end
精彩评论