aclatraz 0.1.2 → 0.1.3

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,10 @@
1
+ == Version 0.1.3
2
+
3
+ * Added Cassandra store
4
+ * Optimized Riak and Redis stores
5
+ * Added benchmarks for all stores
6
+ * Migration to RSpec-2
7
+
1
8
  == Version 0.1.2
2
9
 
3
10
  * Added possibility to passing connection objects in Aclatraz#init
data/README.rdoc CHANGED
@@ -1,7 +1,7 @@
1
1
  = ACLatraz
2
2
 
3
- Extremaly fast and flexible access control mechanism inspired by *nix ACLs,
4
- powered by fast key value stores like Redis or TokyoCabinet.
3
+ Extremaly fast, flexible and intuitive access control mechanism, powered by
4
+ fast key value stores like Redis.
5
5
 
6
6
  == Installation
7
7
 
data/Rakefile CHANGED
@@ -5,35 +5,36 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "aclatraz"
8
- gem.summary = %Q{Flexible access control that doesn't sucks!}
9
- gem.description = <<-DESCR
10
- Extremaly fast and flexible access control mechanism inspired by *nix ACLs,
11
- powered by fast key value stores like Redis or TokyoCabinet.
12
- DESCR
13
8
  gem.email = "kriss.kowalik@gmail.com"
14
9
  gem.homepage = "http://github.com/nu7hatch/aclatraz"
15
10
  gem.authors = ["Kriss 'nu7hatch' Kowalik"]
16
- gem.add_development_dependency "rspec", ">= 1.2.9"
17
- gem.add_development_dependency "mocha", ">= 0.9"
11
+ gem.summary = %Q{Flexible access control that doesn't sucks!}
12
+ gem.description = <<-DESCR
13
+ Extremaly fast, flexible and intuitive access control mechanism,
14
+ powered by fast key value stores like Redis.
15
+ DESCR
16
+ gem.add_dependency "dictionary", "~> 1.0"
17
+ gem.add_development_dependency "rspec", "~> 2.0"
18
+ gem.add_development_dependency "mocha", "~> 0.9"
18
19
  gem.add_development_dependency "redis", "~> 2.0"
19
20
  gem.add_development_dependency "riak-client", "~> 0.8"
20
- gem.add_dependency "dictionary", "~> 1.0"
21
+ gem.add_development_dependency "cassandra", "~> 0.8"
21
22
  end
22
23
  Jeweler::GemcutterTasks.new
23
24
  rescue LoadError
24
25
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
25
26
  end
26
27
 
27
- require 'spec/rake/spectask'
28
- Spec::Rake::SpecTask.new(:spec) do |spec|
29
- spec.libs << 'lib' << 'spec'
30
- spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ require 'rspec/core/rake_task'
29
+ RSpec::Core::RakeTask.new(:spec) do |t|
30
+ t.pattern = 'spec/**/*_spec.rb'
31
+ t.rspec_opts = %q[--colour --backtrace]
31
32
  end
32
33
 
33
- Spec::Rake::SpecTask.new(:rcov) do |spec|
34
- spec.libs << 'lib' << 'spec'
35
- spec.pattern = 'spec/**/*_spec.rb'
36
- spec.rcov = true
34
+ RSpec::Core::RakeTask.new(:rcov) do |t|
35
+ t.rcov = true
36
+ t.rspec_opts = %q[--colour --backtrace]
37
+ t.rcov_opts = %q[--exclude "spec" --text-report]
37
38
  end
38
39
 
39
40
  task :spec => :check_dependencies
@@ -48,7 +49,21 @@ Rake::RDocTask.new do |rdoc|
48
49
  rdoc.rdoc_files.include('lib/**/*.rb')
49
50
  end
50
51
 
51
- task :benchmark do
52
+ namespace :benchmark do
53
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
52
54
  require 'benchmark'
53
- require File.dirname(__FILE__)+"/spec/alcatraz_bm"
55
+ require "aclatraz"
56
+
57
+ task :redis do
58
+ Aclatraz.init(:redis)
59
+ require File.dirname(__FILE__)+"/spec/alcatraz_bm"
60
+ end
61
+ task :cassandra do
62
+ Aclatraz.init(:cassandra, "Super1", "Keyspace1")
63
+ require File.dirname(__FILE__)+"/spec/alcatraz_bm"
64
+ end
65
+ task :riak do
66
+ Aclatraz.init(:riak, "roles")
67
+ require File.dirname(__FILE__)+"/spec/alcatraz_bm"
68
+ end
54
69
  end
data/TODO.rdoc CHANGED
@@ -4,3 +4,5 @@
4
4
  * Memcached store
5
5
  * Think that the main roles should have an impact on object/class ownerships
6
6
  * More Examples
7
+ * Rails plugin
8
+ * Rack/Sinatra/Padrino middleware or plugin
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
data/aclatraz.gemspec CHANGED
@@ -5,13 +5,13 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{aclatraz}
8
- s.version = "0.1.2"
8
+ s.version = "0.1.3"
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-19}
13
- s.description = %q{ Extremaly fast and flexible access control mechanism inspired by *nix ACLs,
14
- powered by fast key value stores like Redis or TokyoCabinet.
12
+ s.date = %q{2010-10-16}
13
+ s.description = %q{ Extremaly fast, flexible and intuitive access control mechanism,
14
+ powered by fast key value stores like Redis.
15
15
  }
16
16
  s.email = %q{kriss.kowalik@gmail.com}
17
17
  s.extra_rdoc_files = [
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "lib/aclatraz/guard.rb",
35
35
  "lib/aclatraz/helpers.rb",
36
36
  "lib/aclatraz/store.rb",
37
+ "lib/aclatraz/store/cassandra.rb",
37
38
  "lib/aclatraz/store/redis.rb",
38
39
  "lib/aclatraz/store/riak.rb",
39
40
  "lib/aclatraz/suspect.rb",
@@ -44,7 +45,6 @@ Gem::Specification.new do |s|
44
45
  "spec/aclatraz/suspect_spec.rb",
45
46
  "spec/aclatraz_spec.rb",
46
47
  "spec/alcatraz_bm.rb",
47
- "spec/spec.opts",
48
48
  "spec/spec_helper.rb"
49
49
  ]
50
50
  s.homepage = %q{http://github.com/nu7hatch/aclatraz}
@@ -69,24 +69,27 @@ Gem::Specification.new do |s|
69
69
  s.specification_version = 3
70
70
 
71
71
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
72
- s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
73
- s.add_development_dependency(%q<mocha>, [">= 0.9"])
72
+ s.add_runtime_dependency(%q<dictionary>, ["~> 1.0"])
73
+ s.add_development_dependency(%q<rspec>, ["~> 2.0"])
74
+ s.add_development_dependency(%q<mocha>, ["~> 0.9"])
74
75
  s.add_development_dependency(%q<redis>, ["~> 2.0"])
75
76
  s.add_development_dependency(%q<riak-client>, ["~> 0.8"])
76
- s.add_runtime_dependency(%q<dictionary>, ["~> 1.0"])
77
+ s.add_development_dependency(%q<cassandra>, ["~> 0.8"])
77
78
  else
78
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
79
- s.add_dependency(%q<mocha>, [">= 0.9"])
79
+ s.add_dependency(%q<dictionary>, ["~> 1.0"])
80
+ s.add_dependency(%q<rspec>, ["~> 2.0"])
81
+ s.add_dependency(%q<mocha>, ["~> 0.9"])
80
82
  s.add_dependency(%q<redis>, ["~> 2.0"])
81
83
  s.add_dependency(%q<riak-client>, ["~> 0.8"])
82
- s.add_dependency(%q<dictionary>, ["~> 1.0"])
84
+ s.add_dependency(%q<cassandra>, ["~> 0.8"])
83
85
  end
84
86
  else
85
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
86
- s.add_dependency(%q<mocha>, [">= 0.9"])
87
+ s.add_dependency(%q<dictionary>, ["~> 1.0"])
88
+ s.add_dependency(%q<rspec>, ["~> 2.0"])
89
+ s.add_dependency(%q<mocha>, ["~> 0.9"])
87
90
  s.add_dependency(%q<redis>, ["~> 2.0"])
88
91
  s.add_dependency(%q<riak-client>, ["~> 0.8"])
89
- s.add_dependency(%q<dictionary>, ["~> 1.0"])
92
+ s.add_dependency(%q<cassandra>, ["~> 0.8"])
90
93
  end
91
94
  end
92
95
 
@@ -9,8 +9,29 @@ module Aclatraz
9
9
 
10
10
  # If given object is kind of string or integer then returns it, otherwise
11
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
12
+ def suspect_id(suspect)
13
+ suspect.is_a?(String) || suspect.is_a?(Integer) ? suspect.to_s : suspect.id.to_s
14
+ end
15
+
16
+ # Unpack given permission data.
17
+ def unpack(data)
18
+ data.to_s.split("/")
19
+ end
20
+
21
+ # Pack given permission data.
22
+ #
23
+ # pack(foo) # => "foo"
24
+ # pack(foo, "FooClass") # => "foo/FooClass"
25
+ # pack(foo, FooClass.new) # => "foo/FooClass/{foo_object_ID}"
26
+ def pack(role, object=nil)
27
+ case object
28
+ when nil
29
+ [role]
30
+ when Class
31
+ [role, object.name]
32
+ else
33
+ [role, object.class.name, object.id]
34
+ end.join("/")
14
35
  end
15
36
  end # Helpers
16
37
  end # Aclatraz
@@ -2,6 +2,7 @@ module Aclatraz
2
2
  module Store
3
3
  autoload :Redis, 'aclatraz/store/redis'
4
4
  autoload :Riak, 'aclatraz/store/riak'
5
+ autoload :Cassandra, 'aclatraz/store/cassandra'
5
6
  #autoload :Memcached, 'aclatraz/store/memcached'
6
7
  #autoload :TokyoCabinet, 'aclatraz/store/tokyocabinet'
7
8
  end # Store
@@ -0,0 +1,63 @@
1
+ module Aclatraz
2
+ module Store
3
+ # List of global roles are stored in `roles => all` key. Each suspect has its
4
+ # own key, which contains list of assigned roles. Roles are stored in
5
+ # following format:
6
+ #
7
+ # roles => suspect.{:suspect_id} =>
8
+ # "role_name" => ""
9
+ # "role_name/ClassName" => ""
10
+ # "role_name/ObjectClass/object_id" => ""
11
+ class Cassandra
12
+ include Aclatraz::Helpers
13
+
14
+ ROLES_KEY = "roles"
15
+ ALL_ROLES_KEY = "all"
16
+ SUSPECT_ROLES_KEY = "suspect.%s"
17
+
18
+ def initialize(*args)
19
+ require 'cassandra' rescue raise LoadError, \
20
+ "You must install the `casssandra` gem to use Cassandra store"
21
+
22
+ @family = args.shift
23
+ @backend = if args.first.respond_to?(:keyspace)
24
+ args.first
25
+ else
26
+ ::Cassandra.new(*args)
27
+ end
28
+ end
29
+
30
+ def set(role, suspect, object=nil)
31
+ data = {}
32
+ data[ALL_ROLES_KEY] = [role.to_s] unless object
33
+ data[SUSPECT_ROLES_KEY % suspect_id(suspect)] = [pack(role.to_s, object)]
34
+ @backend.insert(@family, ROLES_KEY, data)
35
+ end
36
+
37
+ def roles(suspect=nil)
38
+ if suspect
39
+ data = @backend.get(@family, ROLES_KEY, SUSPECT_ROLES_KEY % suspect_id(suspect))
40
+ data ? data.keys.map {|role| unpack(role) }.flatten.compact.uniq : []
41
+ else
42
+ data = @backend.get(@family, ROLES_KEY, ALL_ROLES_KEY)
43
+ data ? data.keys.flatten : []
44
+ end
45
+ end
46
+
47
+ def check(role, suspect, object=nil)
48
+ @backend.exists?(@family, ROLES_KEY, SUSPECT_ROLES_KEY % suspect_id(suspect), \
49
+ pack(role.to_s, object)) or \
50
+ object && !object.is_a?(Class) ? check(role, suspect, object.class) : false
51
+ end
52
+
53
+ def delete(role, suspect, object=nil)
54
+ @backend.remove(@family, ROLES_KEY, SUSPECT_ROLES_KEY % suspect_id(suspect), \
55
+ pack(role.to_s, object))
56
+ end
57
+
58
+ def clear
59
+ @backend.remove(@family, ROLES_KEY)
60
+ end
61
+ end # Redis
62
+ end # Store
63
+ end # Aclatraz
@@ -1,88 +1,61 @@
1
- begin
2
- require 'redis'
3
- require 'redis/distributed'
4
- rescue LoadError
5
- raise "You must install the redis gem to use the Redis store"
6
- end
7
-
8
1
  module Aclatraz
9
2
  module Store
10
- # List of global roles are stored in ROLES set. Each member has its
3
+ # List of global roles are stored in ROLES set. Each suspect has its
11
4
  # own key, which contains list of assigned roles. Roles are stored in
12
5
  # following format:
13
6
  #
14
- # member.{:member_id}.roles:
7
+ # suspect.{:suspect_id}.roles:
15
8
  # "role_name"
16
9
  # "role_name/ClassName"
17
10
  # "role_name/ObjectClass/object_id"
18
11
  class Redis
19
12
  include Aclatraz::Helpers
20
13
 
21
- ROLES = "roles"
22
- MEMBER_ROLES = "member.%s.roles"
14
+ ROLES_KEY = "roles"
15
+ SUSPECT_ROLES_KEY = "suspect.%s.roles"
23
16
 
24
- def initialize(*args) # :nodoc:
25
- case args.first when ::Redis, ::Redis::Distributed
26
- @backend = args.first
17
+ def initialize(*args)
18
+ require 'redis' rescue raise LoadError, \
19
+ "You must install the `redis` gem to use Redis store"
20
+
21
+ @backend = if args.first.respond_to?(:sadd)
22
+ args.first
27
23
  else
28
- @backend = ::Redis.new(*args)
24
+ ::Redis.new(*args)
29
25
  end
30
26
  end
31
27
 
32
- def set(role, member, object=nil)
28
+ def set(role, suspect, object=nil)
33
29
  @backend.multi do
34
- @backend.sadd(ROLES, role.to_s) unless object
35
- @backend.sadd(MEMBER_ROLES % member_id(member), pack(role.to_s, object))
30
+ @backend.sadd(ROLES_KEY, role.to_s) unless object
31
+ @backend.sadd(SUSPECT_ROLES_KEY % suspect_id(suspect), pack(role.to_s, object))
36
32
  end
37
33
  end
38
34
 
39
- def roles(member=nil)
40
- if member
41
- @backend.smembers(MEMBER_ROLES % member_id(member)).map {|role|
35
+ def roles(suspect=nil)
36
+ if suspect
37
+ @backend.smembers(SUSPECT_ROLES_KEY % suspect_id(suspect)).map {|role|
42
38
  role = unpack(role)
43
39
  role[0] if role.size == 1
44
40
  }.compact.uniq
45
41
  else
46
- @backend.smembers(ROLES)
42
+ @backend.smembers(ROLES_KEY)
47
43
  end
48
44
  end
49
45
 
50
- def check(role, member, object=nil)
51
- @backend.sismember(MEMBER_ROLES % member_id(member), pack(role.to_s, object)) or begin
52
- object && !object.is_a?(Class) ? check(role, member, object.class) : false
46
+ def check(role, suspect, object=nil)
47
+ @backend.sismember(SUSPECT_ROLES_KEY % suspect_id(suspect), pack(role.to_s, object)) or begin
48
+ object && !object.is_a?(Class) ? check(role, suspect, object.class) : false
53
49
  end
54
50
  end
55
51
 
56
- def delete(role, member, object=nil)
57
- @backend.srem(MEMBER_ROLES % member_id(member), pack(role.to_s, object))
52
+ def delete(role, suspect, object=nil)
53
+ @backend.srem(SUSPECT_ROLES_KEY % suspect_id(suspect), pack(role.to_s, object))
58
54
  end
59
55
 
60
56
  def clear
61
57
  @backend.flushdb
62
58
  end
63
-
64
- private
65
-
66
- # Pack given permission data.
67
- #
68
- # pack(foo) # => "foo"
69
- # pack(foo, "FooClass") # => "foo/FooClass"
70
- # pack(foo, FooClass.new) # => "foo/FooClass/{foo_object_ID}"
71
- def pack(role, object=nil)
72
- case object
73
- when nil
74
- "#{role}"
75
- when Class
76
- "#{role}/#{object.name}"
77
- else
78
- "#{role}/#{object.class.name}/#{object.id}"
79
- end
80
- end
81
-
82
- # Unpack given permission data.
83
- def unpack(data)
84
- data.to_s.split("/")
85
- end
86
59
  end # Redis
87
60
  end # Store
88
61
  end # Aclatraz
@@ -1,11 +1,3 @@
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
1
  module Aclatraz
10
2
  module Store
11
3
  # The most optimal way to store roles in riak database is pack everything
@@ -17,41 +9,44 @@ module Aclatraz
17
9
  class Riak
18
10
  include Aclatraz::Helpers
19
11
 
20
- def initialize(bucket_name, *args) # :nodoc:
21
- case args.first when ::Riak::Client
22
- @backend = args.first.bucket(bucket_name)
12
+ def initialize(bucket_name, *args)
13
+ require "riak" rescue raise LoadError, \
14
+ "You must install the `riak-client` gem to use Riak store"
15
+
16
+ @backend = if args.first.respond_to?(:bucket)
17
+ args.first.bucket(bucket_name)
23
18
  else
24
- @backend = ::Riak::Client.new(*args).bucket(bucket_name)
19
+ ::Riak::Client.new(*args).bucket(bucket_name)
25
20
  end
26
21
  end
27
22
 
28
- def set(role, member, object=nil)
29
- obj = @backend.new(pack(role.to_s, member_id(member), object))
23
+ def set(role, suspect, object=nil)
24
+ obj = @backend.new(pack(role.to_s, suspect_id(suspect), object))
30
25
  obj.content_type = "text/plain"
31
26
  obj.data = "1"
32
27
  obj.store
33
28
  end
34
29
 
35
- def roles(member=nil)
30
+ def roles(suspect=nil)
36
31
  roles = []
37
32
  # Also this can be a little bit slow...
38
33
  @backend.keys.each do |key|
39
34
  @backend.exists?(key) ? perm = unpack(key) : next
40
- if perm.size == 2 && (!member || (member && perm[0].to_s == member_id(member)))
35
+ if perm.size == 2 && (!suspect || (suspect && perm[0].to_s == suspect_id(suspect)))
41
36
  roles.push(perm[1])
42
37
  end
43
38
  end
44
39
  roles.compact.uniq
45
40
  end
46
41
 
47
- def check(role, member, object=nil)
48
- @backend.exists?(pack(role.to_s, member_id(member), object)) or begin
49
- object && !object.is_a?(Class) ? check(role, member, object.class) : false
42
+ def check(role, suspect, object=nil)
43
+ @backend.exists?(pack(role.to_s, suspect_id(suspect), object)) or begin
44
+ object && !object.is_a?(Class) ? check(role, suspect, object.class) : false
50
45
  end
51
46
  end
52
47
 
53
- def delete(role, member, object=nil)
54
- @backend.delete(pack(role.to_s, member_id(member), object))
48
+ def delete(role, suspect, object=nil)
49
+ @backend.delete(pack(role.to_s, suspect_id(suspect), object))
55
50
  end
56
51
 
57
52
  def clear
@@ -60,27 +55,20 @@ module Aclatraz
60
55
  @backend.keys.each {|key| @backend.delete(key) }
61
56
  end
62
57
 
63
- private
64
-
65
58
  # Pack given permission data.
66
59
  #
67
60
  # pack("foo", 10) # => "10/foo"
68
61
  # pack("foo", 10, "FooClass") # => "10/foo/FooClass"
69
62
  # pack("foo", 10, FooClass.new) # => "10/foo/FooClass/{foo_object_ID}"
70
- def pack(role, member, object=nil)
63
+ def pack(role, suspect, object=nil)
71
64
  case object
72
65
  when nil
73
- "#{member}/#{role}"
66
+ [suspect, role]
74
67
  when Class
75
- "#{member}/#{role}/#{object.name}"
68
+ [suspect, role, object.name]
76
69
  else
77
- "#{member}/#{role}/#{object.class.name}/#{object.id}"
78
- end
79
- end
80
-
81
- # Unpack given permission data.
82
- def unpack(data)
83
- data.to_s.split("/")
70
+ [suspect, role, object.class.name, object.id]
71
+ end.join("/")
84
72
  end
85
73
  end # Riak
86
74
  end # Store
@@ -161,7 +161,7 @@ describe "Aclatraz guard" do
161
161
  guarded.suspect.should == bar
162
162
  end
163
163
 
164
- describe "inherited guards" do
164
+ context "inherited guards" do
165
165
  class FooParent
166
166
  include Aclatraz::Guard
167
167
 
@@ -7,4 +7,21 @@ describe "Aclatraz helpers" do
7
7
  camelize("foo_bar_bla").should == "FooBarBla"
8
8
  camelize("foo").should == "Foo"
9
9
  end
10
+
11
+ it "#suspect_id should properly resolve id of given object" do
12
+ suspect_id("1").should == "1"
13
+ suspect_id(1).should == "1"
14
+ suspect_id(StubSuspect.new).should == "10"
15
+ end
16
+
17
+ it "#unpack should properly split given string by /" do
18
+ unpack("foo/bar/10").should == %w[foo bar 10]
19
+ unpack(nil).should == []
20
+ end
21
+
22
+ it "#pack should work properly" do
23
+ pack("admin").should == "admin"
24
+ pack("admin", StubTarget).should == "admin/StubTarget"
25
+ pack("admin", StubTarget.new).should == "admin/StubTarget/10"
26
+ end
10
27
  end
@@ -55,7 +55,7 @@ describe "Aclatraz" do
55
55
  let(:owner) { StubOwner.new }
56
56
  let(:target) { StubTarget.new }
57
57
 
58
- describe "for Redis store" do
58
+ context "for Redis store" do
59
59
  subject { Aclatraz.init(:redis, "redis://localhost:6379/0") }
60
60
 
61
61
  class_eval &STORE_SPECS
@@ -69,20 +69,32 @@ describe "Aclatraz" do
69
69
 
70
70
  it "shouls respect redis hash options given in init" do
71
71
  Aclatraz.instance_variable_set("@store", nil)
72
- Aclatraz.init(:redis, :url => "redis://localhost:6379/0")
72
+ Aclatraz.init(:redis, :url => "redis://localhost:6379/2")
73
73
  Aclatraz.store.instance_variable_get('@backend').ping.should be_true
74
74
  end
75
75
  end
76
76
 
77
- describe "for Riak store" do
77
+ context "for Riak store" do
78
78
  subject { Aclatraz.init(:riak, "roles") }
79
79
 
80
80
  class_eval &STORE_SPECS
81
81
 
82
82
  it "should respect persistent connection given on initalize" do
83
83
  Aclatraz.instance_variable_set("@store", nil)
84
- Aclatraz.init(:riak, "roles", ::Riak::Client.new)
84
+ Aclatraz.init(:riak, "roles", Riak::Client.new)
85
85
  Aclatraz.store.instance_variable_get('@backend').should be_kind_of(Riak::Bucket)
86
86
  end
87
87
  end
88
+
89
+ context "for Cassandra store" do
90
+ subject { Aclatraz.init(:cassandra, "Super1", "Keyspace1") }
91
+
92
+ class_eval &STORE_SPECS
93
+
94
+ it "should respect persistent connection given on initialize" do
95
+ Aclatraz.instance_variable_set("@store", nil)
96
+ Aclatraz.init(:cassandra, "Super1", Cassandra.new("Keyspace1"))
97
+ Aclatraz.store.instance_variable_get('@backend').should be_kind_of(Cassandra)
98
+ end
99
+ end
88
100
  end
@@ -38,7 +38,7 @@ describe "Aclatraz suspect" do
38
38
  subject.roles.has?(:foobar3, target).should be_false
39
39
  end
40
40
 
41
- describe "syntactic sugars" do
41
+ context "syntactic sugars" do
42
42
  it "1: should properly set given role" do
43
43
  subject.is.foobar1!
44
44
  subject.is.foobar2_of!(StubTarget)
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Aclatraz" do
4
- describe "on init" do
4
+ context "on init" do
5
5
  it "should raise InvalidStore error when given store doesn't exists" do
6
6
  lambda { Aclatraz.init(:fooobar) }.should raise_error(Aclatraz::InvalidStore)
7
7
  end
data/spec/alcatraz_bm.rb CHANGED
@@ -1,9 +1,3 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
-
3
- require "aclatraz"
4
-
5
- Aclatraz.init :redis, "redis://localhost:6379/0"
6
-
7
1
  class Account
8
2
  include Aclatraz::Suspect
9
3
  def id; 30; end
@@ -42,12 +36,12 @@ $foo = Foo.new
42
36
  ns = [1000, 2000, 5000, 10000]
43
37
 
44
38
  ns.each do |n|
45
- puts "#{n} times:"
39
+ puts "#{n} operations:"
46
40
  Benchmark.bm(10) do |bm|
47
- bm.report("Assign:") { n.times {|x| $account.assign_role!("foo#{x}") } }
48
- bm.report("Check:") { n.times {|x| $account.has_role?("foo#{x}") } }
41
+ bm.report("Assign:") { n.times {|x| $account.roles.assign("foo#{x}") } }
42
+ bm.report("Check:") { n.times {|x| $account.roles.has?("foo#{x}") } }
49
43
  bm.report("Guard:") { n.times {|x| $foo.test } }
50
- bm.report("Delete:") { n.times {|x| $account.delete_role!("foo#{x}") } }
44
+ bm.report("Delete:") { n.times {|x| $account.roles.delete("foo#{x}") } }
51
45
  end
52
46
  puts
53
47
  end
data/spec/spec_helper.rb CHANGED
@@ -5,10 +5,9 @@ $VERBOSE = nil
5
5
 
6
6
  require 'rubygems'
7
7
  require 'aclatraz'
8
- require 'spec'
9
- require 'spec/autorun'
8
+ require 'rspec'
10
9
 
11
- Spec::Runner.configure do |config|
10
+ RSpec.configure do |config|
12
11
  config.mock_with :mocha
13
12
  end
14
13
 
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: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kriss 'nu7hatch' Kowalik
@@ -15,32 +15,46 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-19 00:00:00 +02:00
18
+ date: 2010-10-16 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: rspec
22
+ name: dictionary
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ">="
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 13
29
+ hash: 15
30
30
  segments:
31
31
  - 1
32
+ - 0
33
+ version: "1.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
32
46
  - 2
33
- - 9
34
- version: 1.2.9
47
+ - 0
48
+ version: "2.0"
35
49
  type: :development
36
- version_requirements: *id001
50
+ version_requirements: *id002
37
51
  - !ruby/object:Gem::Dependency
38
52
  name: mocha
39
53
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
54
+ requirement: &id003 !ruby/object:Gem::Requirement
41
55
  none: false
42
56
  requirements:
43
- - - ">="
57
+ - - ~>
44
58
  - !ruby/object:Gem::Version
45
59
  hash: 25
46
60
  segments:
@@ -48,11 +62,11 @@ dependencies:
48
62
  - 9
49
63
  version: "0.9"
50
64
  type: :development
51
- version_requirements: *id002
65
+ version_requirements: *id003
52
66
  - !ruby/object:Gem::Dependency
53
67
  name: redis
54
68
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
69
+ requirement: &id004 !ruby/object:Gem::Requirement
56
70
  none: false
57
71
  requirements:
58
72
  - - ~>
@@ -63,11 +77,11 @@ dependencies:
63
77
  - 0
64
78
  version: "2.0"
65
79
  type: :development
66
- version_requirements: *id003
80
+ version_requirements: *id004
67
81
  - !ruby/object:Gem::Dependency
68
82
  name: riak-client
69
83
  prerelease: false
70
- requirement: &id004 !ruby/object:Gem::Requirement
84
+ requirement: &id005 !ruby/object:Gem::Requirement
71
85
  none: false
72
86
  requirements:
73
87
  - - ~>
@@ -78,23 +92,23 @@ dependencies:
78
92
  - 8
79
93
  version: "0.8"
80
94
  type: :development
81
- version_requirements: *id004
95
+ version_requirements: *id005
82
96
  - !ruby/object:Gem::Dependency
83
- name: dictionary
97
+ name: cassandra
84
98
  prerelease: false
85
- requirement: &id005 !ruby/object:Gem::Requirement
99
+ requirement: &id006 !ruby/object:Gem::Requirement
86
100
  none: false
87
101
  requirements:
88
102
  - - ~>
89
103
  - !ruby/object:Gem::Version
90
- hash: 15
104
+ hash: 27
91
105
  segments:
92
- - 1
93
106
  - 0
94
- version: "1.0"
95
- type: :runtime
96
- version_requirements: *id005
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"
107
+ - 8
108
+ version: "0.8"
109
+ type: :development
110
+ version_requirements: *id006
111
+ description: " Extremaly fast, flexible and intuitive access control mechanism, \n powered by fast key value stores like Redis.\n"
98
112
  email: kriss.kowalik@gmail.com
99
113
  executables: []
100
114
 
@@ -119,6 +133,7 @@ files:
119
133
  - lib/aclatraz/guard.rb
120
134
  - lib/aclatraz/helpers.rb
121
135
  - lib/aclatraz/store.rb
136
+ - lib/aclatraz/store/cassandra.rb
122
137
  - lib/aclatraz/store/redis.rb
123
138
  - lib/aclatraz/store/riak.rb
124
139
  - lib/aclatraz/suspect.rb
@@ -129,7 +144,6 @@ files:
129
144
  - spec/aclatraz/suspect_spec.rb
130
145
  - spec/aclatraz_spec.rb
131
146
  - spec/alcatraz_bm.rb
132
- - spec/spec.opts
133
147
  - spec/spec_helper.rb
134
148
  has_rdoc: true
135
149
  homepage: http://github.com/nu7hatch/aclatraz
data/spec/spec.opts DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --backtrace