aclatraz 0.1.0 → 0.1.1

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/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