Skip to content

Instantly share code, notes, and snippets.

@grosser
Created September 18, 2009 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grosser/189079 to your computer and use it in GitHub Desktop.
Save grosser/189079 to your computer and use it in GitHub Desktop.
Controller:
before_filter :can_create, :only=>%w[new create]
before_filter :can_write, :only=>%w[edit update destroy]
before_filter :can_read, :only=>%w[show]
protected
def can_create
can_do(:create)
end
def can_write
can_do(:write)
end
def can_read
can_do(:read)
end
def can_do(action)
return if (current_user||User.new).send("can_#{action}?", requested_object)
access_denied
end
def requested_object
case params[:action]
when 'new','create' then build_object
else current_object
end
end
model
def can_create?(object)
return true if admin?
case object
when User then anonymouse?
when Command, ... then false
...
else raise "NOT SUPPORTED"
end
end
def can_write?(object)
return true if admin?
case object
when User then object == self
when Command, ... then false
...
else raise "NOT SUPPORTED"
end
end
def can_read?(object)
return true if admin?
case object
when User, Command then true
....
else raise "NOT SUPPORTED"
end
end
protected
def anonymouse?
new_record?
end
specs
describe "ACL" do
before :all do
@owner = Factory(:user)
@other = Factory(:user)
@noone = User.new
end
it "User" do
user = User.find(@owner.id)
behaves_like_owner_changeable(user)
end
it "Command" do
behaves_like_static(Factory(:command))
end
def behaves_like_static(item)
check_can(:read, true, true, true, item)
check_can(:write, false, false, false, item)
check_can(:create, false, false, false, item)
end
def behaves_like_owner_changeable(item)
check_can(:read, true, true, true, item)
check_can(:write, true, false, false, item)
check_can(:create, nil, false, true, item)
end
def check_can(action, owner, other, noone, item)
method = "can_#{action}?"
@owner.send(method, item).should == owner unless owner == nil
@other.send(method, item).should == other
@noone.send(method, item).should == noone
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment