การตั้งค่าโมเดล CanCan ability.rs

ฉันสร้างระบบเข้าสู่ระบบด้วย Devise และ CanCan ได้สำเร็จ และฉันมีผู้ใช้ 3 ประเภท ผู้ดูแลระบบ ผู้ใช้ภายในและทั่วโลก ฉันสร้างตัวควบคุมและการดำเนินการดัชนี: ผู้ดูแลระบบ, Cpanel, รายงาน และสถานะ และฉันต้องการจำกัดการเข้าถึงตัวควบคุมนี้สำหรับผู้ใช้บางราย

ผู้ใช้ที่เป็นผู้ดูแลระบบ ควรมีสิทธิ์ในการเข้าถึง: รายงาน(ทั้งหมด), สถานะ (อ่าน), ผู้ดูแลระบบ (ทั้งหมด)

ผู้ใช้ทั่วโลก ควรมีสิทธิ์ในการเข้าถึง: รายงาน (อ่านเท่านั้น) รัฐ (อ่าน) Cpanel (ทั้งหมด)

ผู้ใช้ภายใน ควรมีสิทธิ์ในการเข้าถึง: รายงาน(ทั้งหมด), สถานะ (อ่าน)

และฉันพยายามทำสิ่งนี้ด้วยโค้ดต่อไปนี้ใน ability.rs:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    if user.role? :admin
      can :manage, [Report, Admin]
      can :read, State
    elsif user.role? :global_user
      can :read, [Report, State]
      can :manage, Cpanel
    elsif user.role? :internal_user
      can :manage, Report
      can :read, State     
    end
   end
end

ในขณะนี้ ฉันมีเพียงการดำเนินการดัชนีในคอนโทรลเลอร์นี้ และเมื่อฉันลงชื่อเข้าใช้แอปด้วยผู้ใช้ภายใน ฉันสามารถเข้าถึง /admin ได้ และนั่นไม่ใช่พฤติกรรมที่ฉันต้องการ ฉันต้องการจำกัดการเข้าถึงคอนโทรลเลอร์ทั้งหมด แทนที่จะเป็นคอนโทรลเลอร์ที่แสดงอยู่ในคลาส ability.rb

ซอร์สโค้ดอยู่ที่นี่


person dormitkon    schedule 02.03.2011    source แหล่งที่มา


คำตอบ (3)


หากฉันจะป้องกันการเข้าถึงคอนโทรลเลอร์ทั้งหมด ฉันจะสร้างตัวกรองก่อนหน้าที่จะเปลี่ยนเส้นทางผู้ใช้ไปยังเพจที่ถูกปฏิเสธการเข้าถึง หากไม่มีบทบาทผู้ดูแลระบบ อาจมีลักษณะดังนี้:

def check_permissions
 raise CanCan::AccessDenied unless @current_user.role?(:admin)
end

หากฉันต้องการป้องกันการเข้าถึงการอัปเดตและสร้าง ตัวอย่างเช่น ฉันจะทำ:

def update
  raise CanCan::AccessDenied unless can?(:update,Thing)
  ...
end

def create
  raise CanCan::AccessDenied unless can?(:create,Thing)
  ...
end

คุณสามารถจัดการ CanCan::AccessDenied ข้อยกเว้นในตัวควบคุมแอปพลิเคชันของคุณ:

rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to no_access_path
  end

ฉันมีโพสต์ดีๆ เกี่ยวกับ CanCan และ Devise ที่นี่ และ ที่นี่

อัปเดต ฉันใช้วิธีนี้ในตัวควบคุมแอปพลิเคชันเพื่อตั้งค่าตัวแปรผู้ใช้ปัจจุบัน:

# Make the current user object available to views
  #----------------------------------------------------------------------------
  def get_user
    @current_user = session[:current_user]
  end
person Tony    schedule 02.03.2011
comment
เหตุใดฉันจึงได้รับ `บทบาท' วิธีการที่ไม่ได้กำหนด สำหรับ nil:NilClass? - person dormitkon; 02.03.2011
comment
และฉันมีบทบาทใน User model method หรือไม่? - person dormitkon; 02.03.2011
comment
นั่นหมายความว่าคุณกำลังเรียกบทบาทนี้ใช่ไหม? วิธีการเป็นศูนย์ หากคุณใช้โค้ดของฉันด้านบน แสดงว่าวัตถุ @current_user ของคุณมีค่าเป็นศูนย์ คุณต้องตรวจสอบให้แน่ใจว่ามีการตั้งค่าไว้ ดูการแก้ไขของฉันด้านบนเพื่อดูว่าฉันทำอย่างไร - person Tony; 02.03.2011

คุณต้องเพิ่มการตรวจสอบการอนุญาต Cancan ให้กับคอนโทรลเลอร์ของคุณ

นี่อาจเป็นเพียงการเพิ่มบรรทัดเช่น

authorize! :read, @state

ไปยังการดำเนินการดัชนีตัวควบคุมสถานะของคุณ และในทำนองเดียวกันสำหรับการดำเนินการดัชนีอื่นๆ ทั้งหมด

แก้ไข: ขออภัย ในการดำเนินการดัชนีตัวควบคุมสถานะ คุณอาจไม่มี @state ดังนั้นสิ่งที่กล่าวมาข้างต้นจึงไม่มีผล อาจมีบางอย่างเช่น

authorize! :read, State

นอกจากนี้ยังมีวิธี load_and_authorize ที่คุณสามารถใช้เพื่อรวมการอนุญาตสำหรับการดำเนินการหลายอย่างในคอนโทรลเลอร์และลดโค้ดของคุณ เวอร์ชัน load_and_authorize มีแนวโน้มที่จะมีลักษณะคล้ายกัน

load_and_authorize_resource:สถานะ

และควรอยู่ก่อนการกระทำของคุณ

คุณอาจต้องการดู railscast ในการอนุญาต cancan นี้เพื่อดูการตั้งค่าพื้นฐานที่สมบูรณ์ ( ในราง2)

ฉันสงสัยว่าจะแก้ไขปัญหาอื่นได้ เราอาจต้องดูโค้ดเพิ่มเติม ลองโพสต์โค้ดคอนโทรลเลอร์ของคุณบางส่วน

ฉันไม่ได้ใช้สิ่งนี้ใน Rails3 แต่ฉันคิดว่าส่วนใหญ่ยังคงคล้ายกันไม่มากก็น้อย

person Don Roby    schedule 02.03.2011
comment
และฉันไม่สามารถเข้าถึง /state หรือกับผู้ใช้ที่มีสิทธิ์ได้ - person dormitkon; 02.03.2011
comment
ฉันเพิ่มการอนุญาต! :index, ผู้ดูแลระบบในตัวควบคุมผู้ดูแลระบบ, การดำเนินการของดัชนี ตอนนี้ เมื่อฉันต้องการเข้าถึง /admin ที่บันทึกเป็นผู้ใช้ทั่วโลก ฉันได้รับ NameError ใน AdminController#index คงที่ที่กำหนดค่าเริ่มต้น AdminController::Admin แอปทั้งหมดอยู่ที่นี่: cl.ly/2E292R2m2B0X141q3C0S - person dormitkon; 02.03.2011
comment
:index น่าจะยังคงเป็น :read - แต่ฉันจะดูคอนโทรลเลอร์ทั้งหมดของคุณและดูว่าฉันพบสิ่งใดหรือไม่ - person Don Roby; 02.03.2011
comment
ไม่มีผู้ดูแลระบบอยู่ในรหัสของคุณ ตัวอย่างง่ายๆ สำหรับ cancan และโค้ดทั้งหมดของฉันถือว่ามีโมเดลที่ได้รับการป้องกัน ฉันไม่รู้วิธีใช้งานจริงๆ หากไม่มีโมเดล แต่บางทีอาจมีคนอื่นช่วยได้ คุณต้องทำอะไรบางอย่างในคอนโทรลเลอร์ของคุณอย่างแน่นอน แต่ฉันไม่แน่ใจว่าจะเกิดอะไรขึ้นในบริบทนี้ - person Don Roby; 02.03.2011

ฉันแก้ไขปัญหานี้ด้วย

def check_permissions
 raise CanCan::AccessDenied unless current_user.role?(:admin)
end

แต่โปรดทราบว่าฉันต้องเปลี่ยน @current_user เป็น current_user (ไม่มี @)

ขอบคุณโทนี่

person dormitkon    schedule 02.03.2011