credentials 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/HISTORY CHANGED
@@ -1,4 +1,14 @@
1
- === 2.2.3 / 2009-11-27
1
+ === 2.4.0 / 2010-01-25
2
+
3
+ * Implemented Foo.metaclass.credentials { |foo| ... } to allow
4
+ declaration of credentials per instance. This is nice for
5
+ implementing RBA.
6
+
7
+ === 2.3.1 / 2009-12-17
8
+
9
+ * Minor bug fix (Class !== Class)
10
+
11
+ === 2.3.0 / 2009-12-16
2
12
 
3
13
  * Add support for prepositions.
4
14
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.1
1
+ 2.4.0
data/credentials.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{credentials}
8
- s.version = "2.3.1"
8
+ s.version = "2.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Matt Powell"]
12
- s.date = %q{2009-12-17}
12
+ s.date = %q{2010-01-25}
13
13
  s.description = %q{A generic actor/resource permission framework based on rules, not objects.}
14
14
  s.email = %q{fauxparse@gmail.com.com}
15
15
  s.extra_rdoc_files = [
@@ -52,9 +52,15 @@ module Credentials
52
52
 
53
53
  # Returns true if the receiver has access to the specified resource or action.
54
54
  def can?(*args)
55
- self.class.credentials.allow? self, *args
55
+ metaclass.credentials.allow?(self, *args)
56
56
  end
57
57
  alias_method :able_to?, :can?
58
+
59
+ def metaclass
60
+ class << self
61
+ self
62
+ end
63
+ end
58
64
 
59
65
  def self.included(receiver) #:nodoc:
60
66
  receiver.extend ClassMethods
@@ -81,7 +81,7 @@ module Credentials
81
81
  return false unless receiver.respond_to? condition
82
82
  !!receiver.send(condition, *args[0, receiver.method(condition).arity])
83
83
  when Proc
84
- raise ArgumentError, "wrong number of arguments to condition (#{args.size} to #{condition.arity})" unless args.size + 1 == condition.arity
84
+ raise ArgumentError, "wrong number of arguments to condition (#{args.size + 1} to #{condition.arity})" unless args.size + 1 == condition.arity
85
85
  !!condition.call(receiver, *args)
86
86
  else
87
87
  raise ArgumentError, "invalid :if or :unless option (expected Symbol or Proc, or array thereof; got #{condition.class})"
@@ -11,6 +11,7 @@ module Credentials
11
11
  attr_accessor :klass
12
12
  attr_accessor :options
13
13
  attr_accessor :rules
14
+ attr_reader :superklass_rulebook
14
15
 
15
16
  DEFAULT_OPTIONS = {
16
17
  :default => :deny
@@ -18,23 +19,28 @@ module Credentials
18
19
 
19
20
  def initialize(klass)
20
21
  self.klass = klass
21
- @rules = if klass.superclass.respond_to?(:credentials) && !klass.superclass.credentials.empty?
22
- klass.superclass.credentials.rules.dup
22
+ superklass = if klass.to_s =~ /^#<Class:#<([\w_]+)/ # there must be a better way
23
+ $1.constantize
23
24
  else
24
- []
25
+ klass.superclass
26
+ end
27
+
28
+ @rules = []
29
+ if superklass == Object
30
+ @superklass_rulebook = nil
31
+ @options = {}
32
+ else
33
+ @superklass_rulebook = superklass.credentials
34
+ @options = superklass_rulebook.options.dup
25
35
  end
26
- @options = {}
27
36
  end
28
37
 
29
38
  # Creates a Rulebook for the given class.
30
39
  # Should not be called directly: instead,
31
40
  # use +class.credentials+ (q.v.).
32
41
  def self.for(klass)
33
- rulebook = new(klass)
34
- if superclass && superclass.respond_to?(:credentials)
35
- rulebook.rules = superclass.credentials.rules.dup
36
- end
37
- rulebook
42
+ @rulebooks ||= {}
43
+ @rulebooks[klass] ||= new(klass)
38
44
  end
39
45
 
40
46
  # Returns +true+ if there are no rules defined in this Rulebook.
@@ -199,11 +205,13 @@ module Credentials
199
205
 
200
206
  # Subset of rules that grant permission by exposing an +allow?+ method.
201
207
  def allow_rules
208
+ @allow_rules ||= (superklass_rulebook ? superklass_rulebook.allow_rules : []) +
202
209
  rules.select { |rule| rule.respond_to? :allow? }
203
210
  end
204
211
 
205
212
  # Subset of rules that deny permission by exposing an +deny?+ method.
206
213
  def deny_rules
214
+ @deny_rules ||= (superklass_rulebook ? superklass_rulebook.deny_rules : []) +
207
215
  rules.select { |rule| rule.respond_to? :deny? }
208
216
  end
209
217
  end
@@ -9,4 +9,19 @@ describe Credentials::Rulebook do
9
9
  Animal.credentials.should_not == Carnivore.credentials
10
10
  Animal.credentials.rules.should_not == Carnivore.credentials.rules
11
11
  end
12
+
13
+ describe "created for an instance" do
14
+ before :all do
15
+ @penguin = Bird.new("Penguin")
16
+ @penguin.metaclass.credentials do |penguin|
17
+ penguin.can :swim
18
+ end
19
+ @emu = Bird.new("Emu")
20
+ end
21
+
22
+ it "should grant permissions only for that instance" do
23
+ @penguin.should be_able_to(:swim)
24
+ @emu.should_not be_able_to(:swim)
25
+ end
26
+ end
12
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: credentials
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Powell
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-17 00:00:00 +13:00
12
+ date: 2010-01-25 00:00:00 +13:00
13
13
  default_executable:
14
14
  dependencies: []
15
15