lib/authority.rb in authority-2.9.0 vs lib/authority.rb in authority-2.10.0
- old
+ new
@@ -35,14 +35,14 @@
# @return [Model] resource instance
def self.enforce(action, resource, user, options = {})
unless action_authorized?(action, resource, user, options)
raise SecurityViolation.new(user, action, resource)
end
- resource
end
def self.action_authorized?(action, resource, user, options = {})
+ raise MissingUser if user.nil?
resource_and_maybe_options = [resource, options].tap {|args| args.pop if args.last == {}}
user.send("can_#{action}?", *resource_and_maybe_options)
end
class << self
@@ -65,9 +65,33 @@
def self.require_authority_internals!
require 'authority/abilities'
require 'authority/authorizer'
require 'authority/user_abilities'
+ end
+
+ class MissingUser < StandardError
+ def message
+ "You tried to check authorization on `nil`. Authority doesn't know what
+ `nil` is allowed to do. There are two ways you can fix this.
+
+ 1. Authenticate before authorizing. If the user isn't signed in, force
+ them to sign in before they can attempt any action that requires
+ authorization.
+
+ 2. When the user is not signed in, return a Null Object instead of
+ `nil`. (You could create an AnonymousUser class, for example.) It should
+ respond to the normal methods Authority will call (like `can_delete?`),
+ possibly by including `Authority::UserAbilities` and teaching your authorizers
+ what an anonymous user can do.
+
+ The downside of solution #2 is that a user who forgot to sign in will be
+ told they are not authorized for an action they could normally do. This might
+ be confusing.
+
+ However, you might use both strategies in different parts of your application.
+ "
+ end
end
end
require 'authority/configuration'