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 +7 -0
- data/README.rdoc +2 -2
- data/Rakefile +33 -18
- data/TODO.rdoc +2 -0
- data/VERSION +1 -1
- data/aclatraz.gemspec +17 -14
- data/lib/aclatraz/helpers.rb +23 -2
- data/lib/aclatraz/store.rb +1 -0
- data/lib/aclatraz/store/cassandra.rb +63 -0
- data/lib/aclatraz/store/redis.rb +23 -50
- data/lib/aclatraz/store/riak.rb +21 -33
- data/spec/aclatraz/guard_spec.rb +1 -1
- data/spec/aclatraz/helpers_spec.rb +17 -0
- data/spec/aclatraz/stores_spec.rb +16 -4
- data/spec/aclatraz/suspect_spec.rb +1 -1
- data/spec/aclatraz_spec.rb +1 -1
- data/spec/alcatraz_bm.rb +4 -10
- data/spec/spec_helper.rb +2 -3
- metadata +40 -26
- data/spec/spec.opts +0 -2
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= ACLatraz
|
2
2
|
|
3
|
-
Extremaly fast and
|
4
|
-
|
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.
|
17
|
-
gem.
|
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.
|
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 '
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
52
|
+
namespace :benchmark do
|
53
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
52
54
|
require 'benchmark'
|
53
|
-
require
|
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
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
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.
|
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-
|
13
|
-
s.description = %q{ Extremaly fast and
|
14
|
-
powered by fast key value stores like Redis
|
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.
|
73
|
-
s.add_development_dependency(%q<
|
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.
|
77
|
+
s.add_development_dependency(%q<cassandra>, ["~> 0.8"])
|
77
78
|
else
|
78
|
-
s.add_dependency(%q<
|
79
|
-
s.add_dependency(%q<
|
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<
|
84
|
+
s.add_dependency(%q<cassandra>, ["~> 0.8"])
|
83
85
|
end
|
84
86
|
else
|
85
|
-
s.add_dependency(%q<
|
86
|
-
s.add_dependency(%q<
|
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<
|
92
|
+
s.add_dependency(%q<cassandra>, ["~> 0.8"])
|
90
93
|
end
|
91
94
|
end
|
92
95
|
|
data/lib/aclatraz/helpers.rb
CHANGED
@@ -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
|
13
|
-
|
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
|
data/lib/aclatraz/store.rb
CHANGED
@@ -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
|
data/lib/aclatraz/store/redis.rb
CHANGED
@@ -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
|
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
|
-
#
|
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
|
-
|
22
|
-
|
14
|
+
ROLES_KEY = "roles"
|
15
|
+
SUSPECT_ROLES_KEY = "suspect.%s.roles"
|
23
16
|
|
24
|
-
def initialize(*args)
|
25
|
-
|
26
|
-
|
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
|
-
|
24
|
+
::Redis.new(*args)
|
29
25
|
end
|
30
26
|
end
|
31
27
|
|
32
|
-
def set(role,
|
28
|
+
def set(role, suspect, object=nil)
|
33
29
|
@backend.multi do
|
34
|
-
@backend.sadd(
|
35
|
-
@backend.sadd(
|
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(
|
40
|
-
if
|
41
|
-
@backend.smembers(
|
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(
|
42
|
+
@backend.smembers(ROLES_KEY)
|
47
43
|
end
|
48
44
|
end
|
49
45
|
|
50
|
-
def check(role,
|
51
|
-
@backend.sismember(
|
52
|
-
object && !object.is_a?(Class) ? check(role,
|
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,
|
57
|
-
@backend.srem(
|
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
|
data/lib/aclatraz/store/riak.rb
CHANGED
@@ -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)
|
21
|
-
|
22
|
-
|
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
|
-
|
19
|
+
::Riak::Client.new(*args).bucket(bucket_name)
|
25
20
|
end
|
26
21
|
end
|
27
22
|
|
28
|
-
def set(role,
|
29
|
-
obj = @backend.new(pack(role.to_s,
|
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(
|
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 && (!
|
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,
|
48
|
-
@backend.exists?(pack(role.to_s,
|
49
|
-
object && !object.is_a?(Class) ? check(role,
|
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,
|
54
|
-
@backend.delete(pack(role.to_s,
|
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,
|
63
|
+
def pack(role, suspect, object=nil)
|
71
64
|
case object
|
72
65
|
when nil
|
73
|
-
|
66
|
+
[suspect, role]
|
74
67
|
when Class
|
75
|
-
|
68
|
+
[suspect, role, object.name]
|
76
69
|
else
|
77
|
-
|
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
|
data/spec/aclatraz/guard_spec.rb
CHANGED
@@ -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
|
-
|
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/
|
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
|
-
|
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",
|
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
|
-
|
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)
|
data/spec/aclatraz_spec.rb
CHANGED
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}
|
39
|
+
puts "#{n} operations:"
|
46
40
|
Benchmark.bm(10) do |bm|
|
47
|
-
bm.report("Assign:") { n.times {|x| $account.
|
48
|
-
bm.report("Check:") { n.times {|x| $account.
|
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.
|
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
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:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
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-
|
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:
|
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:
|
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
|
-
-
|
34
|
-
version:
|
47
|
+
- 0
|
48
|
+
version: "2.0"
|
35
49
|
type: :development
|
36
|
-
version_requirements: *
|
50
|
+
version_requirements: *id002
|
37
51
|
- !ruby/object:Gem::Dependency
|
38
52
|
name: mocha
|
39
53
|
prerelease: false
|
40
|
-
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: *
|
65
|
+
version_requirements: *id003
|
52
66
|
- !ruby/object:Gem::Dependency
|
53
67
|
name: redis
|
54
68
|
prerelease: false
|
55
|
-
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: *
|
80
|
+
version_requirements: *id004
|
67
81
|
- !ruby/object:Gem::Dependency
|
68
82
|
name: riak-client
|
69
83
|
prerelease: false
|
70
|
-
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: *
|
95
|
+
version_requirements: *id005
|
82
96
|
- !ruby/object:Gem::Dependency
|
83
|
-
name:
|
97
|
+
name: cassandra
|
84
98
|
prerelease: false
|
85
|
-
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:
|
104
|
+
hash: 27
|
91
105
|
segments:
|
92
|
-
- 1
|
93
106
|
- 0
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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