2012-01-18 12 views
7

Przyjrzałem się deklarative_authorization, CanCan i CanTango. Wszyscy są dobrzy w dodawaniu autoryzacji do aplikacji, ale zastanawiałem się, w jaki sposób można dodać autoryzację do konkretnej instancji modelu, tj. Osoba może mieć dostęp do zarządzania w jednym projekcie i jest tylko ograniczona (czytaj mniej niż zarządzaj: ograniczona aktualizacja itp.) winnym.Autoryzacja w Railsach 3.1: CanCan, CanTango, declaative_authorization?

mógłbyś lepszy sposób? Przepraszam, jeśli moje pytanie brzmi zbyt trywialnie. Może tak być, ponieważ jestem nowy w RoR.

dzięki, John

+0

W CanCan można definiować umiejętności za pomocą bloków z warunkami - https://github.com/ryanb/cancan/wiki/Defining-Abilities-with-Blocks. –

+0

1. TeamMembers ma wielu użytkowników, role 2. Zespoły mają wielu TeamMembers 3. Projekt ma jeden zespół ... W przypadku bloków powyższa konfiguracja nie zapewnia możliwości filtrowania dla konkretnej instancji projektu. Jeśli sądzisz, że da się to zrobić ... Czy mógłbyś podać mi np. Z góry dziękuję. –

Odpowiedz

4

co wiem CanCan i declarative_authorization, a ja realizowane zezwoleń oparte na rolach zarówno polecam kankana. Tylko moje dwa centy.

Przykład (niesprawdzone, niestety nie mogę przetestować tutaj i nie mam dostępu do mojego kodu)

Więc powiedzmy, że mamy strukturę takiego:

class User < ActiveRecord::Base 
    belongs_to :role 
end 

class Role < ActiveRecord::Base 
    has_many :users 

    # attributes: project_read, project_create, project_update 
end 

Następnie CanCan może wyglądać tak:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    @user = user 
    @role = user.role 

    # user can see a project if he has project_read => true in his role 
    can :read, Project if role.project_read? 

    # same, but with create 
    can :create, Project if role.project_create? 

    # can do everything with projects if he is an admin 
    can :manage, Project if user.admin? 
    end 

end 

Możesz znaleźć wszystkie potrzebne informacje w wiki CanCan na github. Osobiste zalecenie, aby przeczytać:

Zasadniczo wystarczy przedłużyć powyższy przykład zawierać swoje role poprzez swoje relacje. Aby to było proste, możesz także utworzyć dodatkowe metody pomocnicze w ability.rb.

Głównym średnią zastrzeżenie może spaść do (przynajmniej ja): Upewnij się, że użytkownik może coś zrobić z modelem przed określić co użytkownik nie może. W przeciwnym razie będziesz siedział sfrustrowany i myślisz "ale dlaczego? Nigdy nie napisałem, że użytkownik nie może". Tak. Ale nigdy też wyraźnie napisał, że może ...

+0

Zaimplementowałam cancan .. ale nie mogę wymyślić, jak zdefiniować/ograniczyć użytkownika dla konkretnej instancji (np. Projektu). Dowolny byłoby naprawdę pomocne. Istnieje pośrednie połączenie między Użytkownikiem a Projektem ... 1. TeamMembers ma wielu użytkowników 2. Zespoły mają wielu TeamMembers 3. Projekt ma jeden zespół –

+0

zaktualizowany na przykładzie. – pduersteler

+0

Czy muszę zainstalować program Cancan i utworzyć model roli? Nie widzę w dokumentacji Cancan, że jest ona potrzebna. Czy możesz to wyjaśnić? dzięki –

0
class User < ActiveRecord::Base 

    belongs_to :role 
    delegate :permissions, :to => :role 

    def method_missing(method_id, *args) 
    if match = matches_dynamic_role_check?(method_id) 
     tokenize_roles(match.captures.first).each do |check| 
     return true if role.name.downcase == check 
     end 
     return false 
    elsif match = matches_dynamic_perm_check?(method_id) 
     return true if permissions.find_by_name(match.captures.first) 
    else 
     super 
    end 
    end 


    private 

    def matches_dynamic_perm_check?(method_id) 
    /^can_([a-zA-Z]\w*)\?$/.match(method_id.to_s) 
    end 

    def matches_dynamic_role_check?(method_id) 
    /^is_an?_([a-zA-Z]\w*)\?$/.match(method_id.to_s) 
    end 

    def tokenize_roles(string_to_split) 
    string_to_split.split(/_or_/) 
    end 

end 

Zastosowanie:

user.is_an? Administrator

user.can_delete?