Pergunta

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
Foi útil?

Solução 2

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.

Outras dicas

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

: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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top