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 +11 -1
- data/VERSION +1 -1
- data/credentials.gemspec +2 -2
- data/lib/credentials/extensions/object.rb +7 -1
- data/lib/credentials/rule.rb +1 -1
- data/lib/credentials/rulebook.rb +17 -9
- data/spec/rulebook_spec.rb +15 -0
- metadata +2 -2
data/HISTORY
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
=== 2.
|
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.
|
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.
|
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{
|
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
|
-
|
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
|
data/lib/credentials/rule.rb
CHANGED
@@ -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})"
|
data/lib/credentials/rulebook.rb
CHANGED
@@ -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
|
-
|
22
|
-
|
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
|
-
|
34
|
-
|
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
|
data/spec/rulebook_spec.rb
CHANGED
@@ -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.
|
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:
|
12
|
+
date: 2010-01-25 00:00:00 +13:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|