Created
June 8, 2022 22:07
-
-
Save JoshCheek/e2ee4064b3e91df6b05c3756bfcbc7e4 to your computer and use it in GitHub Desktop.
Modifying CanCanCan's default behaviour to raise when asked about undeclared abilities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem 'cancancan', '= 2.1.2' # the version from our gemfile | |
require 'cancan' | |
module CanCan::StrictAbility | |
include CanCan::Ability | |
# Overrides this method: https://github.com/CanCanCommunity/cancancan/blob/2.1.2/lib/cancan/ability.rb#L67-L74 | |
# NOTE: on newer cancans, the implementation of that method changed to allow attribute level rules | |
def can?(action, subject, *extra_args) | |
had_relevant_rule = false | |
extract_subjects(subject).each do |a_subject| | |
relevant_rules_for_match(action, a_subject).each do |rule| | |
had_relevant_rule = true | |
return rule.base_behavior if rule.matches_conditions? action, a_subject, extra_args | |
end | |
end | |
return false if had_relevant_rule | |
# The overridden method would return `false` here, but if we expect that we will | |
# declare all expected permissions, then this is actually an error situation. | |
# Either that assumption is wrong, or the call site is wrong. | |
raise RuntimeError, "NO RULE DECLARED FOR #{action.inspect} ON #{subject.inspect}", caller | |
end | |
end | |
ability = Object.new.extend(CanCan::Ability) | |
ability.can :upcase, String | |
ability.cannot :downcase, String | |
# By default, undeclared abilities (capitalize) behave as though they have not been granted | |
ability.can? :upcase, String # => true | |
ability.can? :downcase, String # => false | |
ability.can? :capitalize, String # => false | |
# But we could override `can?` to explode instead | |
ability.extend CanCan::StrictAbility | |
ability.can? :upcase, String # => true | |
ability.can? :downcase, String # => false | |
ability.can? :capitalize, String # => RuntimeError: NO RULE DECLARED FOR :capitalize ON String | |
# ~> RuntimeError | |
# ~> NO RULE DECLARED FOR :capitalize ON String | |
# ~> | |
# ~> program.rb:38:in `<main>' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment