aclatraz 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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