aclatraz 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ == Version 0.1.1
2
+
3
+ * Riak store [Thanks seven1m]
4
+ * Optimized Redis store
5
+ * Fixed tests
6
+
1
7
  == Version 0.1.0
2
8
 
3
9
  * Inherited access control lists
data/README.rdoc CHANGED
@@ -26,7 +26,7 @@ Suspects are objects which we can assign specific permissions. There is only
26
26
  one condition which object have to meet to be suspect - it must have the #id
27
27
  method which returns an unique identifier after which we will be able to
28
28
  reference this object. To enable suspect behaviour you have to include the
29
- +Aclatraz::Suspect+ module to specified class, eg:
29
+ <tt>Aclatraz::Suspect</tt> module to specified class, eg:
30
30
 
31
31
  class Account < ActiveRecord::Base
32
32
  include Aclatraz::Suspect
@@ -38,24 +38,22 @@ Now your suspect have few methods which will helps you manage it permissions.
38
38
 
39
39
  ACLatraz distinguishes between three types of roles:
40
40
 
41
- *global* ::
42
- simple roles, which are most commonly assigned to many users. We can say that
43
- they are kind of groups. Global roles are eg. _guest_, _admin_, _customer_.
44
- *class-related* ::
45
- roles that affects management of a particular class. Example of this kind
46
- of role can be *manager* of +Pages+, *admin* of +Products+, etc.
47
- *object-related* ::
48
- roles that affects management of an object. For example *author* of
49
- _specified page_, *owner* of _specified product_, etc.
41
+ * <b>global:</b> simple roles, which are most commonly assigned to many users.
42
+ We can say that they are kind of groups. Global roles are eg. _guest_, _admin_,
43
+ _customer_.
44
+ * <b>class-related:</b> roles that affects management of a particular class.
45
+ Example of this kind of role can be *manager* of +Pages+, *admin* of +Products+, etc.
46
+ * <b>object-related:</b> roles that affects management of an object. For example
47
+ *author* of <em>specified page</em>, *owner* of <em>specified product</em>, etc.
50
48
 
51
- Now there is two ways for managing roles. You can use +#roles+ or semanticaly
52
- look like +#is+ and +#is_not+ proxies.
49
+ Now there is two ways for managing roles. You can use <tt>#roles</tt> or semanticaly
50
+ look like <tt>#is</tt> and <tt>#is_not</tt> proxies.
53
51
 
54
52
  ==== Assigning
55
53
 
56
- To add given role you can use +#assign+ method from +#roles+ proxy or use
57
- semantic shortcuts. Semantic shortcut have to ends with *!*, and can have
58
- optional suffixes: <em>_on</em>, <em>_of</em>, <em>_at</em>, <em>_for</em>,
54
+ To add given role you can use <tt>#assign</tt> method from <tt>#roles</tt> proxy
55
+ or use semantic shortcuts. Semantic shortcut have to ends with <b>"!"</b>, and
56
+ can have optional suffixes: <em>_on</em>, <em>_of</em>, <em>_at</em>, <em>_for</em>,
59
57
  <em>_in</em>, <em>_by</em>. Take a look at the following examples to get
60
58
  everything to be clear:
61
59
 
@@ -67,51 +65,58 @@ everything to be clear:
67
65
  @account.roles.assign(:responsible, Foo) # or...
68
66
  @account.is.responsible_for!(Foo)
69
67
 
70
- ...will assign to the account _responsible_ role related with Foo class.
68
+ ...will assign to the account _responsible_ role related with +Foo+ class.
71
69
 
72
70
  @account.roles.assign(:author, Page.find(15)) # or...
73
71
  @account.is.author_of!(Page.find(15))
74
72
 
75
- ...will assign to the account _author_ role related with given page object.
73
+ ...will assign to the account _author_ role related with given +Page+ object.
76
74
 
77
75
  ==== Checking
78
76
 
79
- Using #roles proxy you can call +#has?+ method on it, eg:
77
+ Using #roles proxy you can call <tt>#has?</t> method on it, eg:
80
78
 
81
79
  @account.roles.has?(:admin) # => true
82
80
  @account.roles.has?(:responsible, Foo) # => true
83
81
  @account.roles.has?(:author, Page.find(15) # => true
84
82
 
85
- With semantic shortcuts your method name have to ends with *?* and can contain
83
+ With semantic shortcuts your method name have to ends with <b>"?"</b> and can contain
86
84
  any of suffixes listed above, eg:
87
85
 
88
- @account.is.admin? # => true
89
- @account.is.responsible_for?(Foo) # => true
90
- @account.is.author_of(Page.find(15)) # => true
86
+ @account.is.admin? # => true
87
+ @account.is.responsible_for?(Foo) # => true
88
+ @account.is.author_of?(Page.find(15)) # => true
91
89
 
92
90
  Few more examples with semantic negation:
93
91
 
94
- @account.is_not.admin? # => false
95
- @account.is_not.responsible_for(Foo) # => false
92
+ @account.is_not.admin? # => false
93
+ @account.is_not.responsible_for?(Foo) # => false
94
+
95
+ You can also check permissions using nice block-style syntax. The code inside
96
+ the block will be executed only when object has given role. An quick example:
97
+
98
+ @account.is.admin? do
99
+ # only admins can se this...
100
+ end
96
101
 
97
102
  ==== Deleting
98
103
 
99
- To unassign given role from object use +#delete+ method from +#roles+, eg:
104
+ To unassign given role from object use <tt>#delete</tt> method from <tt>#roles</tt>, eg:
100
105
 
101
106
  @account.roles.delete(:admin)
102
107
  @account.roles.delete(:responsible, Foo)
103
108
 
104
- Another way is to use semantic negation, where method name have to ends with *!*
109
+ Another way is to use semantic negation, where method name have to ends with <b>"!"</b>
105
110
  and can contain one of allowed suffixes, eg:
106
111
 
107
112
  @account.is_not.admin!
108
- @account.is_not.author_of(Page.find(15))
113
+ @account.is_not.author_of!(Page.find(15))
109
114
 
110
115
  == Guards
111
116
 
112
117
  To enable access control in your for your objects you have to include to it the
113
- +Aclatraz::Guard+ module. This module provides methods for defining and checking
114
- permissions of an suspected object. Take a look for this basic example:
118
+ <tt>Aclatraz::Guard</tt> module. This module provides methods for defining and
119
+ checking permissions of an suspected object. Take a look for this basic example:
115
120
 
116
121
  class Foo
117
122
  include Aclatraz::Guard
@@ -122,23 +127,23 @@ permissions of an suspected object. Take a look for this basic example:
122
127
  end
123
128
  end
124
129
 
125
- The +#suspects+ block is passing one argument - suspected object. When there is
126
- symbol given, like in example above, then will treat #account instance method
127
- result as suspected object. When you will use string, eg:
130
+ The <tt>#suspects</tt> block is passing one argument - suspected object. When
131
+ there is symbol given, like in example above, then will treat <tt>#account</tt>
132
+ instance method result as suspected object. When you will use string, eg:
128
133
 
129
134
  suspects "account" do # or suspects "@account" do ...
130
135
 
131
- ... it will treat @account instance variable as suspect. You can also specify
132
- suspected object directly, eg:
136
+ ... it will treat <tt>@account</tt> instance variable as suspect. You can also
137
+ specify suspected object directly, eg:
133
138
 
134
139
  account = Account.find(1)
135
140
  suspects account do # ...
136
141
 
137
- === Allowing and denying access
142
+ === Setting up permissions
138
143
 
139
144
  As you probably noticed, there is two methods responsible for access control,
140
- namely +#allow+ and +#deny+. As its argument you can pass simple name of role
141
- or permission statement, eg:
145
+ namely <tt>#allow</tt> and <tt>#deny</tt>. As its argument you can pass simple
146
+ name of role or permission statement, eg:
142
147
 
143
148
  allow :admin
144
149
  deny :guest
@@ -146,8 +151,8 @@ or permission statement, eg:
146
151
  allow :author_of => "@page"
147
152
 
148
153
  Like you see, you can easy specify access for each kind of role. The object-related
149
- permissions behaviour is similar to +#suspects+ method. When given related object
150
- is string then applies permissions for an instance variable, when symbol then
154
+ permissions behaviour is similar to <tt>#suspects</tt> method. When given related
155
+ object is string then applies permissions for an instance variable, when symbol then
151
156
  applies it for instance method, otherwise directly for given object.
152
157
 
153
158
  === Actions
@@ -172,9 +177,10 @@ Obviously all actions inherits all permissions from main block.
172
177
 
173
178
  === Authorizing
174
179
 
175
- The +Aclatraz::Guards+ module provides +#guard!+ method for checking permissions.
176
- When suspected object don't have any of allowed permissions or have any of defnied
177
- then it will raise the +Aclatraz::AccessDenied+ error. Here's an comprehensive example:
180
+ The <tt>Aclatraz::Guards</tt> module provides <tt>#guard!</tt> method for checking
181
+ permissions. When suspected object don't have any of allowed permissions or have
182
+ any of defnied then it will raise the <tt>Aclatraz::AccessDenied</tt> error.
183
+ Here's an comprehensive example:
178
184
 
179
185
  class Foo
180
186
  suspects "@account" do
@@ -215,7 +221,7 @@ then it will raise the +Aclatraz::AccessDenied+ error. Here's an comprehensive e
215
221
  end
216
222
 
217
223
  There is also a very nice feature. You can define additional permissions directly
218
- in +#guard!+ block, eg:
224
+ in <tt>#guard!</tt> block, eg:
219
225
 
220
226
  def foo
221
227
  guard! do
@@ -253,8 +259,8 @@ in each child class you can freely modify permissions. Here's an example:
253
259
 
254
260
  === Aliases
255
261
 
256
- If you prefer you can use aliases: +#access_control+ instead of +#suspects+ and
257
- +#authorize!+ instead of +#guard!+.
262
+ If you prefer you can use aliases: <tt>#access_control</tt> instead of
263
+ <tt>#suspects</tt> and <tt>#authorize!</tt> instead of <tt>#guard!</tt>.
258
264
 
259
265
  == Note on Patches/Pull Requests
260
266
 
data/Rakefile CHANGED
@@ -16,6 +16,7 @@ begin
16
16
  gem.add_development_dependency "rspec", ">= 1.2.9"
17
17
  gem.add_development_dependency "mocha", ">= 0.9"
18
18
  gem.add_development_dependency "redis", "~> 2.0"
19
+ gem.add_development_dependency "riak-client", "~> 0.8"
19
20
  gem.add_dependency "dictionary", "~> 1.0"
20
21
  end
21
22
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
data/aclatraz.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{aclatraz}
8
- s.version = "0.1.0"
8
+ s.version = "0.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kriss 'nu7hatch' Kowalik"]
12
- s.date = %q{2010-09-16}
12
+ s.date = %q{2010-09-17}
13
13
  s.description = %q{ Extremaly fast and flexible access control mechanism inspired by *nix ACLs,
14
14
  powered by fast key value stores like Redis or TokyoCabinet.
15
15
  }
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
35
35
  "lib/aclatraz/helpers.rb",
36
36
  "lib/aclatraz/store.rb",
37
37
  "lib/aclatraz/store/redis.rb",
38
+ "lib/aclatraz/store/riak.rb",
38
39
  "lib/aclatraz/suspect.rb",
39
40
  "spec/aclatraz/acl_spec.rb",
40
41
  "spec/aclatraz/guard_spec.rb",
@@ -71,17 +72,20 @@ Gem::Specification.new do |s|
71
72
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
72
73
  s.add_development_dependency(%q<mocha>, [">= 0.9"])
73
74
  s.add_development_dependency(%q<redis>, ["~> 2.0"])
75
+ s.add_development_dependency(%q<riak-client>, ["~> 0.8"])
74
76
  s.add_runtime_dependency(%q<dictionary>, ["~> 1.0"])
75
77
  else
76
78
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
77
79
  s.add_dependency(%q<mocha>, [">= 0.9"])
78
80
  s.add_dependency(%q<redis>, ["~> 2.0"])
81
+ s.add_dependency(%q<riak-client>, ["~> 0.8"])
79
82
  s.add_dependency(%q<dictionary>, ["~> 1.0"])
80
83
  end
81
84
  else
82
85
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
83
86
  s.add_dependency(%q<mocha>, [">= 0.9"])
84
87
  s.add_dependency(%q<redis>, ["~> 2.0"])
88
+ s.add_dependency(%q<riak-client>, ["~> 0.8"])
85
89
  s.add_dependency(%q<dictionary>, ["~> 1.0"])
86
90
  end
87
91
  end
@@ -1,26 +1,16 @@
1
1
  module Aclatraz
2
2
  module Helpers
3
- # Pack given permission data.
4
- #
5
- # pack(10) # => "10"
6
- # pack(10, "FooClass") # => "10/FooClass"
7
- # pack(10, FooClass.new) # => "10/FooClass/{foo_object_ID}"
8
- def pack(owner, object=nil)
9
- case object
10
- when nil
11
- "#{owner}"
12
- when Class
13
- "#{owner}/#{object.name}"
14
- else
15
- "#{owner}/#{object.class.name}/#{object.id}"
16
- end
17
- end
18
-
19
3
  # Given underscored word, returns camelized version of it.
20
4
  #
21
5
  # camelize(foo_bar_bla) # => "FooBarBla"
22
6
  def camelize(str)
23
7
  str.split('_').map {|w| w.capitalize}.join
24
8
  end
9
+
10
+ # If given object is kind of string or integer then returns it, otherwise
11
+ # it tries to return its ID.
12
+ def member_id(member)
13
+ member.is_a?(String) || member.is_a?(Integer) ? member.to_s : member.id.to_s
14
+ end
25
15
  end # Helpers
26
16
  end # Aclatraz
@@ -1,6 +1,7 @@
1
1
  module Aclatraz
2
2
  module Store
3
3
  autoload :Redis, 'aclatraz/store/redis'
4
+ autoload :Riak, 'aclatraz/store/riak'
4
5
  #autoload :Memcached, 'aclatraz/store/memcached'
5
6
  #autoload :TokyoCabinet, 'aclatraz/store/tokyocabinet'
6
7
  end # Store
@@ -6,47 +6,78 @@ end
6
6
 
7
7
  module Aclatraz
8
8
  module Store
9
+ # List of global roles are stored in ROLES set. Each member has its
10
+ # own key, which contains list of assigned roles. Roles are stored in
11
+ # following format:
12
+ #
13
+ # member.{:member_id}.roles:
14
+ # "role_name"
15
+ # "role_name/ClassName"
16
+ # "role_name/ObjectClass/object_id"
9
17
  class Redis
10
18
  include Aclatraz::Helpers
11
19
 
12
- ROLES_KEY = "aclatraz.roles"
13
- MEMBER_ROLES_KEY = "member.%s.roles"
20
+ ROLES = "roles"
21
+ MEMBER_ROLES = "member.%s.roles"
14
22
 
15
23
  def initialize(*args) # :nodoc:
16
24
  @backend = ::Redis.new(*args)
17
25
  end
18
26
 
19
- def set(role, owner, object=nil)
27
+ def set(role, member, object=nil)
20
28
  @backend.multi do
21
- unless object
22
- @backend.hset(ROLES_KEY, role, 1)
23
- @backend.hset(MEMBER_ROLES_KEY % owner.id.to_s, role, 1)
24
- end
25
- @backend.sadd(role.to_s, pack(owner.id, object))
29
+ @backend.sadd(ROLES, role.to_s) unless object
30
+ @backend.sadd(MEMBER_ROLES % member_id(member), pack(role.to_s, object))
26
31
  end
27
32
  end
28
33
 
29
34
  def roles(member=nil)
30
35
  if member
31
- @backend.hkeys(MEMBER_ROLES_KEY % member.id.to_s)
36
+ @backend.smembers(MEMBER_ROLES % member_id(member)).map {|role|
37
+ role = unpack(role)
38
+ role[0] if role.size == 1
39
+ }.compact.uniq
32
40
  else
33
- @backend.hkeys(ROLES_KEY)
41
+ @backend.smembers(ROLES)
34
42
  end
35
43
  end
36
44
 
37
- def check(role, owner, object=nil)
38
- @backend.sismember(role.to_s, pack(owner.id, object)) or begin
39
- object && !object.is_a?(Class) ? check(role, owner, object.class) : false
45
+ def check(role, member, object=nil)
46
+ @backend.sismember(MEMBER_ROLES % member_id(member), pack(role.to_s, object)) or begin
47
+ object && !object.is_a?(Class) ? check(role, member, object.class) : false
40
48
  end
41
49
  end
42
50
 
43
- def delete(role, owner, object=nil)
44
- @backend.srem(role.to_s, pack(owner.id, object))
51
+ def delete(role, member, object=nil)
52
+ @backend.srem(MEMBER_ROLES % member_id(member), pack(role.to_s, object))
45
53
  end
46
54
 
47
55
  def clear
48
56
  @backend.flushdb
49
57
  end
58
+
59
+ private
60
+
61
+ # Pack given permission data.
62
+ #
63
+ # pack(foo) # => "foo"
64
+ # pack(foo, "FooClass") # => "foo/FooClass"
65
+ # pack(foo, FooClass.new) # => "foo/FooClass/{foo_object_ID}"
66
+ def pack(role, object=nil)
67
+ case object
68
+ when nil
69
+ "#{role}"
70
+ when Class
71
+ "#{role}/#{object.name}"
72
+ else
73
+ "#{role}/#{object.class.name}/#{object.id}"
74
+ end
75
+ end
76
+
77
+ # Unpack given permission data.
78
+ def unpack(data)
79
+ data.to_s.split("/")
80
+ end
50
81
  end # Redis
51
82
  end # Store
52
83
  end # Aclatraz
@@ -0,0 +1,83 @@
1
+ require 'yaml'
2
+
3
+ begin
4
+ require "riak"
5
+ rescue LoadError
6
+ raise "You must install the redis-client gem to use the Riak store"
7
+ end
8
+
9
+ module Aclatraz
10
+ module Store
11
+ # The most optimal way to store roles in riak database is pack everything
12
+ # in a single key name, eg:
13
+ #
14
+ # :suspect_id/:role_name
15
+ # :suspect_id/:role_name/:ClassName
16
+ # :suspect_id/:role_name/:ObjectClass/object_id
17
+ class Riak
18
+ include Aclatraz::Helpers
19
+
20
+ def initialize(bucket_name, *args) # :nodoc:
21
+ @backend = ::Riak::Client.new(*args).bucket(bucket_name)
22
+ end
23
+
24
+ def set(role, member, object=nil)
25
+ obj = @backend.new(pack(role.to_s, member_id(member), object))
26
+ obj.content_type = "text/plain"
27
+ obj.data = "1"
28
+ obj.store
29
+ end
30
+
31
+ def roles(member=nil)
32
+ roles = []
33
+ # Also this can be a little bit slow...
34
+ @backend.keys.each do |key|
35
+ @backend.exists?(key) ? perm = unpack(key) : next
36
+ if perm.size == 2 && (!member || (member && perm[0].to_s == member_id(member)))
37
+ roles.push(perm[1])
38
+ end
39
+ end
40
+ roles.compact.uniq
41
+ end
42
+
43
+ def check(role, member, object=nil)
44
+ @backend.exists?(pack(role.to_s, member_id(member), object)) or begin
45
+ object && !object.is_a?(Class) ? check(role, member, object.class) : false
46
+ end
47
+ end
48
+
49
+ def delete(role, member, object=nil)
50
+ @backend.delete(pack(role.to_s, member_id(member), object))
51
+ end
52
+
53
+ def clear
54
+ # not optimal... yea but there is no other way to clear all keys
55
+ # in the riak bucket -_-"
56
+ @backend.keys.each {|key| @backend.delete(key) }
57
+ end
58
+
59
+ private
60
+
61
+ # Pack given permission data.
62
+ #
63
+ # pack("foo", 10) # => "10/foo"
64
+ # pack("foo", 10, "FooClass") # => "10/foo/FooClass"
65
+ # pack("foo", 10, FooClass.new) # => "10/foo/FooClass/{foo_object_ID}"
66
+ def pack(role, member, object=nil)
67
+ case object
68
+ when nil
69
+ "#{member}/#{role}"
70
+ when Class
71
+ "#{member}/#{role}/#{object.name}"
72
+ else
73
+ "#{member}/#{role}/#{object.class.name}/#{object.id}"
74
+ end
75
+ end
76
+
77
+ # Unpack given permission data.
78
+ def unpack(data)
79
+ data.to_s.split("/")
80
+ end
81
+ end # Riak
82
+ end # Store
83
+ end # Aclatraz
@@ -7,14 +7,4 @@ describe "Aclatraz helpers" do
7
7
  camelize("foo_bar_bla").should == "FooBarBla"
8
8
  camelize("foo").should == "Foo"
9
9
  end
10
-
11
- it "#pack should return packed permission" do
12
- pack(10).should == "10"
13
-
14
- class StubTarget; def id; 10; end; end
15
- pack(10, StubTarget).should == "10/StubTarget"
16
-
17
- target = StubTarget.new
18
- pack(20, target).should == "20/StubTarget/10"
19
- end
20
10
  end
@@ -2,6 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  STORE_SPECS = proc do
4
4
  it "should properly assign given roles to owner and check permissions" do
5
+ subject.clear
5
6
  subject.set("foo", owner)
6
7
  subject.check("foo", owner).should be_true
7
8
 
@@ -17,13 +18,14 @@ STORE_SPECS = proc do
17
18
  end
18
19
 
19
20
  it "should properly delete given permission" do
21
+ subject.clear
20
22
  subject.set("foo", owner)
21
23
  subject.set("bar", owner, StubTarget)
22
24
  subject.set("bla", owner, target)
23
25
 
24
- subject.delete("bar", owner)
26
+ subject.delete("foo", owner)
25
27
  subject.delete("bar", owner, StubTarget)
26
- subject.delete("bar", owner, target)
28
+ subject.delete("bla", owner, target)
27
29
 
28
30
  subject.check("bar", owner).should be_false
29
31
  subject.check("bar", owner, StubTarget).should be_false
@@ -35,6 +37,7 @@ STORE_SPECS = proc do
35
37
  subject.set("bar", owner)
36
38
  subject.set("bla", owner)
37
39
 
40
+ subject.roles.should_not be_empty
38
41
  (subject.roles - ["foo", "bar", "bla"]).should be_empty
39
42
  end
40
43
 
@@ -43,8 +46,8 @@ STORE_SPECS = proc do
43
46
  subject.set("bar", owner)
44
47
  subject.set("bla", owner)
45
48
 
46
- (subject.roles(owner.id) - ["foo", "bar", "bla"]).should be_empty
47
- subject.roles(33).should be_empty
49
+ subject.roles(owner).should_not be_empty
50
+ (subject.roles(owner) - ["foo", "bar", "bla"]).should be_empty
48
51
  end
49
52
  end
50
53
 
@@ -56,7 +59,14 @@ describe "Aclatraz" do
56
59
  before(:all) { @redis = Thread.new { `redis-server` } }
57
60
  after(:all) { @redis.exit! }
58
61
  subject { Aclatraz.init(:redis, "redis://localhost:6379/0") }
59
- before(:each) { subject.clear }
62
+
63
+ class_eval &STORE_SPECS
64
+ end
65
+
66
+ describe "Riak store" do
67
+ before(:all) { @riak = Thread.new { `riak start` } }
68
+ after(:all) { @riak.exit! }
69
+ subject { Aclatraz.init(:riak, "roles") }
60
70
 
61
71
  class_eval &STORE_SPECS
62
72
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aclatraz
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kriss 'nu7hatch' Kowalik
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-16 00:00:00 +02:00
18
+ date: 2010-09-17 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -65,9 +65,24 @@ dependencies:
65
65
  type: :development
66
66
  version_requirements: *id003
67
67
  - !ruby/object:Gem::Dependency
68
- name: dictionary
68
+ name: riak-client
69
69
  prerelease: false
70
70
  requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ hash: 27
76
+ segments:
77
+ - 0
78
+ - 8
79
+ version: "0.8"
80
+ type: :development
81
+ version_requirements: *id004
82
+ - !ruby/object:Gem::Dependency
83
+ name: dictionary
84
+ prerelease: false
85
+ requirement: &id005 !ruby/object:Gem::Requirement
71
86
  none: false
72
87
  requirements:
73
88
  - - ~>
@@ -78,7 +93,7 @@ dependencies:
78
93
  - 0
79
94
  version: "1.0"
80
95
  type: :runtime
81
- version_requirements: *id004
96
+ version_requirements: *id005
82
97
  description: " Extremaly fast and flexible access control mechanism inspired by *nix ACLs, \n powered by fast key value stores like Redis or TokyoCabinet.\n"
83
98
  email: kriss.kowalik@gmail.com
84
99
  executables: []
@@ -105,6 +120,7 @@ files:
105
120
  - lib/aclatraz/helpers.rb
106
121
  - lib/aclatraz/store.rb
107
122
  - lib/aclatraz/store/redis.rb
123
+ - lib/aclatraz/store/riak.rb
108
124
  - lib/aclatraz/suspect.rb
109
125
  - spec/aclatraz/acl_spec.rb
110
126
  - spec/aclatraz/guard_spec.rb