Browse Source

ACL things

pull/1/head
Nicolae Claudius 13 years ago
parent
commit
f29f75d83b
  1. 8
      app/controllers/application_controller.rb
  2. 12
      app/models/ability.rb
  3. 3
      app/models/domain.rb
  4. 12
      app/models/user.rb
  5. 9
      config/initializers/cancan.rb
  6. 43
      spec/models/ability_spec.rb
  7. 23
      spec/support/matchers/be_able_to.rb

8
app/controllers/application_controller.rb

@ -3,6 +3,7 @@ class ApplicationController < ActionController::Base
include SentientController include SentientController
protect_from_forgery protect_from_forgery
before_filter :check_honeypot before_filter :check_honeypot
helper_method :client_remote_ip, :respond_to
rescue_from CanCan::AccessDenied, ActiveScaffold::ActionNotAllowed do |exception| rescue_from CanCan::AccessDenied, ActiveScaffold::ActionNotAllowed do |exception|
flash.now[:error] = exception.message flash.now[:error] = exception.message
@ -29,13 +30,6 @@ class ApplicationController < ActionController::Base
@client_remote_ip ||= request.env["HTTP_X_FORWARDED_FOR"] @client_remote_ip ||= request.env["HTTP_X_FORWARDED_FOR"]
end end
def current_ability
@current_ability ||= ::Ability.new(:user => current_user)
end
helper_method :client_remote_ip
helper_method :respond_to
def check_honeypot def check_honeypot
render :nothing => true if params[Settings.honeypot].present? render :nothing => true if params[Settings.honeypot].present?
end end

12
app/models/ability.rb

@ -6,12 +6,12 @@ class Ability
attr_accessor :context attr_accessor :context
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities # See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
def initialize(options) def initialize(user, options = {})
@user = options[:user] || User.new @user = user || User.new
@context = options[:context] || :application @context = options[:context] || :application
action_aliases action_aliases
if user.persisted? if @user.persisted?
owner_abilities owner_abilities
sharing_abilities sharing_abilities
end end
@ -41,14 +41,14 @@ class Ability
# can manage shared domains and records descendants # can manage shared domains and records descendants
for domain in user.permitted_domains for domain in user.permitted_domains
can CRUD, Domain, :name_reversed.matches => "#{domain.name_reversed}.%" # descendants can CRUD, Domain, :name_reversed.matches => "#{domain.name_reversed}.%" # descendants
can CRUD, Record, :domain => {:name_reversed.matches => "#{domain.name_reversed}.%"} # descendant's can CRUD, Record, :domain => {:name_reversed.matches => "#{domain.name_reversed}.%"} # descendants
end end
end end
def action_aliases def action_aliases
alias_action :row, :show_search, :render_field, :to => :read alias_action :list, :row, :show_search, :render_field, :to => :read
alias_action :update_column, :add_association, :edit_associated, alias_action :update_column, :add_association, :edit_associated,
:edit_associated, :new_existing, :add_existing, :to => :update :edit_associated, :new_existing, :add_existing, :new_token, :to => :update
alias_action :delete, :destroy_existing, :to => :destroy alias_action :delete, :destroy_existing, :to => :destroy
end end

3
app/models/domain.rb

@ -76,7 +76,8 @@ class Domain < ActiveRecord::Base
# If current user present authorize it # If current user present authorize it
# If current user not present, just allow (rake tasks etc) # If current user not present, just allow (rake tasks etc)
def can_be_managed_by_current_user? def can_be_managed_by_current_user?
User.current.present? ? User.current.can?(:manage, self) : true return true if User.current.nil?
Ability::CRUD.all?{|operation| User.current.can?(operation, self)}
end end
def slave?; self.type == 'SLAVE' end def slave?; self.type == 'SLAVE' end

12
app/models/user.rb

@ -31,21 +31,21 @@ class User < ActiveRecord::Base
"#{first_name} #{last_name}" "#{first_name} #{last_name}"
end end
# domains per user limit for DOS protection
def domains_exceeding?
domains.count >= Settings.max_domains_per_user.to_i
end
delegate :can?, :cannot?, :to => :ability delegate :can?, :cannot?, :to => :ability
def ability(options = {:reload => false}) def ability(options = {:reload => false})
options[:reload] ? _ability : (@ability ||= _ability) options[:reload] ? _ability : (@ability ||= _ability)
end end
# domains per user limit for DOS protection
def domains_exceeding?
domains.count >= Settings.max_domains_per_user.to_i
end
protected protected
def _ability def _ability
Ability.new(:user => self) Ability.new(self)
end end
end end

9
config/initializers/cancan.rb

@ -57,7 +57,14 @@ module CanCan
# Return the conditions directly if there's just one definition # Return the conditions directly if there's just one definition
@rules.first.conditions.dup @rules.first.conditions.dup
else else
@rules.reverse.inject(false_sql) {|acc, rule| acc | rule.conditions.dup} @rules.reverse.inject(false_sql) do |accumulator, rule|
conditions = rule.conditions.dup
if conditions.blank?
rule.base_behavior ? (accumulator | true_sql) : (accumulator & false_sql)
else
rule.base_behavior ? (accumulator | conditions) : (accumulator & -conditions)
end
end
end end
end end

43
spec/models/ability_spec.rb

@ -4,25 +4,26 @@ require 'spec_helper'
describe Ability do describe Ability do
include_context "data" include_context "data"
let(:crud){Ability::CRUD}
context "basic" do context "basic" do
it "allows me to manage my domains and their records, and my hosts" do it "allows me to manage my domains and their records, and my hosts" do
user.should be_able_to(:manage, domain) user.should be_able_to(crud, domain)
user.should be_able_to(:manage, a_record) user.should be_able_to(crud, a_record)
user.should be_able_to(:manage, soa_record) user.should be_able_to(crud, soa_record)
user.should_not be_able_to(:delete, soa_record) # SOA deleted only via parent user.should_not be_able_to(:delete, soa_record) # SOA deleted only via parent
user.should be_able_to(:manage, host_a_record) user.should be_able_to(crud, host_a_record)
end end
it "denies other user to manage my domains and their records, and my hosts" do it "denies other user to manage my domains and their records, and my hosts" do
user2.should_not be_able_to(:manage, domain) user2.should_not be_able_to(crud, domain)
user2.should_not be_able_to(:manage, a_record) user2.should_not be_able_to(crud, a_record)
user2.should_not be_able_to(:manage, soa_record) user2.should_not be_able_to(crud, soa_record)
user2.should_not be_able_to(:manage, host_a_record) user2.should_not be_able_to(crud, host_a_record)
end end
it "allows admin to manage other user's hosts" do it "allows admin to manage other user's hosts" do
admin.should be_able_to(:manage, host_a_record) admin.should be_able_to(crud, host_a_record)
end end
end end
@ -32,35 +33,35 @@ describe Ability do
end end
it "allows other user to manage user's domains and records, if permitted" do it "allows other user to manage user's domains and records, if permitted" do
user2.should be_able_to(:manage, domain) user2.should be_able_to(crud, domain)
user2.should be_able_to(:manage, a_record) user2.should be_able_to(crud, a_record)
user2.should be_able_to(:manage, soa_record) user2.should be_able_to(crud, soa_record)
end end
it "denies third user to manage user's permitted domains and records" do it "denies third user to manage user's permitted domains and records" do
user3.should_not be_able_to(:manage, domain) user3.should_not be_able_to(crud, domain)
user3.should_not be_able_to(:manage, a_record) user3.should_not be_able_to(crud, a_record)
user3.should_not be_able_to(:manage, soa_record) user3.should_not be_able_to(crud, soa_record)
end end
it "allows other user to manage user's permitted subdomains" do it "allows other user to manage user's permitted subdomains" do
user2.should be_able_to(:manage, subdomain) user2.should be_able_to(crud, subdomain)
user2.should be_able_to(:manage, subsubdomain) user2.should be_able_to(crud, subsubdomain)
end end
it "denies third user to manage other user's permitted subdomains" do it "denies third user to manage other user's permitted subdomains" do
user3.should_not be_able_to(:manage, subdomain) user3.should_not be_able_to(crud, subdomain)
user3.should_not be_able_to(:manage, subsubdomain) user3.should_not be_able_to(crud, subsubdomain)
end end
end end
context "permission" do context "permission" do
it "allows me to manage my domain's permissions" do it "allows me to manage my domain's permissions" do
user.should be_able_to(:manage, permission) user.should be_able_to(crud, permission)
end end
it "denies other user to manage my domain's permissions" do it "denies other user to manage my domain's permissions" do
user2.should_not be_able_to(:manage, permission) user2.should_not be_able_to(crud, permission)
end end
end end

23
spec/support/matchers/be_able_to.rb

@ -0,0 +1,23 @@
# Allow matching arrays in "ba_able_to"
#
# user.should be_able_to [:read, :write], post
#
RSpec::Matchers.define :be_able_to do |*args|
match do |ability|
arguments = args.dup
first = arguments.delete_at(0)
if first.is_a?(Array)
first.all?{|operation| ability.can?(operation, *arguments)}
else
ability.can?(*args)
end
end
failure_message_for_should do |ability|
"expected to be able to #{args.map(&:inspect).join(" ")}"
end
failure_message_for_should_not do |ability|
"expected not to be able to #{args.map(&:inspect).join(" ")}"
end
end
Loading…
Cancel
Save