troles 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Design.textile +68 -0
- data/Gemfile +9 -7
- data/Gemfile.lock +81 -76
- data/README.textile +63 -170
- data/VERSION +1 -1
- data/lib/trole.rb +2 -2
- data/lib/trole_groups/storage/base_many.rb +16 -5
- data/lib/troles/adapters/active_record/config.rb +19 -5
- data/lib/troles/api/config.rb +1 -1
- data/lib/troles/api/core.rb +4 -4
- data/lib/troles/common/api/core.rb +13 -14
- data/lib/troles/common/api/read.rb +6 -0
- data/lib/troles/common/api.rb +3 -2
- data/lib/troles/common/config/schema/helpers.rb +30 -11
- data/lib/troles/common/config/schema/role_helpers.rb +5 -5
- data/lib/troles/common/config/valid_roles.rb +4 -3
- data/lib/troles/common/dependencies.rb +1 -1
- data/lib/troles/common/storage.rb +16 -4
- data/lib/troles/common.rb +2 -2
- data/lib/troles/config.rb +4 -4
- data/lib/troles/storage/join_ref_many.rb +13 -0
- data/lib/troles/storage.rb +6 -5
- data/lib/troles.rb +3 -8
- data/spec/active_record/migrations/many/custom_join.rb +31 -0
- data/spec/active_record/migrations/many/join_ref_many.rb +31 -0
- data/spec/active_record/migrations/many/ref_many.rb +0 -8
- data/spec/active_record/models/custom_join.rb +13 -0
- data/spec/active_record/models/join_ref_many.rb +13 -0
- data/spec/active_record/models/ref_many.rb +0 -2
- data/spec/active_record/strategies/many/custom_join_spec.rb +46 -0
- data/spec/active_record/strategies/many/join_ref_many_spec.rb +46 -0
- data/spec/active_record/strategies/many/ref_many_spec.rb +2 -2
- data/spec/generic/models/base_user.rb +2 -1
- data/spec/trole/strategies/embed_one_spec.rb +1 -1
- data/spec/trole/strategies/ref_one_spec.rb +1 -1
- data/spec/trole/strategies/string_one_spec.rb +1 -1
- data/spec/troles/common/multi_roles_spec.rb +7 -13
- data/spec/troles/strategies/bit_many_spec.rb +1 -1
- data/spec/troles/strategies/embed_many_spec.rb +1 -1
- data/spec/troles/strategies/ref_many_spec.rb +1 -1
- data/spec/troles/strategies/string_many_spec.rb +1 -1
- data/spec/troles/strategy_helper.rb +1 -1
- data/troles.gemspec +38 -24
- metadata +72 -42
@@ -41,8 +41,9 @@ module Troles::Common
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def get_model_type class_name
|
44
|
-
return :
|
45
|
-
return :
|
44
|
+
return :subject if class_name == subject_class
|
45
|
+
return :object if class_name == object_model
|
46
|
+
return :join if class_name == role_join_model
|
46
47
|
raise "Not a known model: #{class_name}"
|
47
48
|
end
|
48
49
|
|
@@ -54,22 +55,40 @@ module Troles::Common
|
|
54
55
|
from_type = get_model_type from
|
55
56
|
to_type = get_model_type to
|
56
57
|
|
57
|
-
|
58
|
+
key_opts = key_options(type, to_type)
|
59
|
+
|
60
|
+
model_key = options[:key] ? options[:key] : send("#{to_type}_key", key_opts)
|
58
61
|
|
59
62
|
class_name = send "#{to_type}_class_name"
|
60
63
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
rel_options = {:class_name => class_name}
|
65
|
+
|
66
|
+
rel_options.merge!(options[:opts]) if options[:opts]
|
67
|
+
|
68
|
+
puts "#{from}.#{type} :#{model_key}, #{rel_options.inspect}" if log_on?
|
69
|
+
|
70
|
+
from.send(type, model_key, rel_options)
|
65
71
|
end
|
66
72
|
|
67
|
-
def object_key
|
68
|
-
make_key object_class_name
|
73
|
+
def object_key options = {}
|
74
|
+
make_key "#{object_class_name}", options
|
69
75
|
end
|
70
76
|
|
71
|
-
def
|
72
|
-
|
77
|
+
def key_options type, obj
|
78
|
+
return {:prefix => 't'} if (type == :has_many && obj == :object)
|
79
|
+
{}
|
80
|
+
end
|
81
|
+
|
82
|
+
def make_key name, options = {}
|
83
|
+
name = name.to_s.gsub(/::/, '__').underscore.pluralize
|
84
|
+
parts = name.split('_')
|
85
|
+
name = parts.inject([]) do |res, part|
|
86
|
+
res << (part != parts.last ? part.singularize : part)
|
87
|
+
res
|
88
|
+
end.join('_')
|
89
|
+
|
90
|
+
key = name
|
91
|
+
options[:prefix] ? "t#{key}" : key
|
73
92
|
end
|
74
93
|
end
|
75
94
|
end
|
@@ -6,16 +6,16 @@ module Troles::Common
|
|
6
6
|
subject_class.to_s
|
7
7
|
end
|
8
8
|
|
9
|
-
def subject_key
|
10
|
-
make_key subject_class_name
|
9
|
+
def subject_key options = {}
|
10
|
+
make_key subject_class_name, options
|
11
11
|
end
|
12
12
|
|
13
13
|
def join_class_name
|
14
|
-
|
14
|
+
role_join_model.to_s
|
15
15
|
end
|
16
16
|
|
17
|
-
def join_key
|
18
|
-
make_key join_class_name
|
17
|
+
def join_key options = {}
|
18
|
+
make_key join_class_name, options
|
19
19
|
end
|
20
20
|
|
21
21
|
def object_class_name
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module Troles::Common
|
2
2
|
class Config
|
3
|
-
module ValidRoles
|
3
|
+
module ValidRoles
|
4
4
|
def add_valid_roles *roles
|
5
5
|
valid_roles =valid_roles & roles
|
6
6
|
end
|
7
7
|
|
8
8
|
def valid_roles= *roles
|
9
9
|
vrs = roles.flatten.map{|r| r.to_s.alpha_numeric}.map(&:to_sym).uniq
|
10
|
+
|
10
11
|
raise ArgumentError, "The #{strategy} strategy can only accept 2 valid roles" if (vrs.size > 2) && strategy == :bit_one
|
11
12
|
raise ArgumentError, "The role names you want to be valid are not valid role names. Must be alphanumeric, was: #{roles.flatten}" if vrs.empty?
|
12
13
|
@valid_roles ||= vrs
|
@@ -14,8 +15,8 @@ module Troles::Common
|
|
14
15
|
|
15
16
|
def valid_roles
|
16
17
|
raise "No valid roles defined" if !@valid_roles || @valid_roles.empty?
|
17
|
-
@valid_roles
|
18
|
+
@valid_roles
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
21
|
-
end
|
22
|
+
end
|
@@ -29,6 +29,12 @@ module Troles::Common
|
|
29
29
|
# @param [Object] the value to set on the role field of the role subject
|
30
30
|
def set_ds_field value
|
31
31
|
return if ds_field_value == value
|
32
|
+
|
33
|
+
if Troles::Common::Config.log_on?
|
34
|
+
puts "Troles::Common::Storage.set_ds_field:"
|
35
|
+
puts "#{rolegroup_subject}.#{ds_field_name} = #{value}"
|
36
|
+
end
|
37
|
+
|
32
38
|
role_subject.send(:"#{ds_field_name}=", value)
|
33
39
|
persist_role_changes!
|
34
40
|
end
|
@@ -47,10 +53,16 @@ module Troles::Common
|
|
47
53
|
|
48
54
|
# Attempts to persist the role field changes
|
49
55
|
# @return [true, false, error] true if saved, false if no save! method, Error on some error
|
50
|
-
def persist_role_changes!
|
51
|
-
|
52
|
-
role_subject.save
|
53
|
-
|
56
|
+
def persist_role_changes!
|
57
|
+
puts "Troles::Common::Storage::BaseMany.persist_role_changes!" if Troles::Common::Config.log_on?
|
58
|
+
if !role_subject.respond_to? :save
|
59
|
+
puts "could not save since no #save method on subject: #{role_subject}" if Troles::Common::Config.log_on?
|
60
|
+
return false
|
61
|
+
else
|
62
|
+
puts "#{role_subject}.save" if Troles::Common::Config.log_on?
|
63
|
+
role_subject.save
|
64
|
+
role_subject.publish_change :roles
|
65
|
+
end
|
54
66
|
end
|
55
67
|
|
56
68
|
protected
|
data/lib/troles/common.rb
CHANGED
data/lib/troles/config.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Troles
|
2
|
-
class Config < Troles::Common::Config
|
2
|
+
class Config < Troles::Common::Config
|
3
3
|
def initialize subject_class, options = {}
|
4
4
|
super
|
5
5
|
end
|
6
6
|
|
7
7
|
def configure_models
|
8
8
|
super
|
9
|
-
end
|
10
|
-
|
9
|
+
end
|
10
|
+
|
11
11
|
def generic?
|
12
12
|
super
|
13
13
|
end
|
14
14
|
end
|
15
|
-
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# Many role storage for storing multiple Role references on the role subject
|
4
|
+
#
|
5
|
+
# @note all methods potentially operate directly on values in the data store
|
6
|
+
#
|
7
|
+
module Troles::Storage
|
8
|
+
class JoinRefMany < RefMany
|
9
|
+
def initialize role_subject
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/troles/storage.rb
CHANGED
@@ -4,10 +4,11 @@
|
|
4
4
|
#
|
5
5
|
module Troles
|
6
6
|
module Storage
|
7
|
-
autoload :BaseMany,
|
8
|
-
autoload :BitMany,
|
9
|
-
autoload :EmbedMany,
|
10
|
-
autoload :RefMany,
|
11
|
-
autoload :
|
7
|
+
autoload :BaseMany, 'troles/storage/base_many'
|
8
|
+
autoload :BitMany, 'troles/storage/bit_many'
|
9
|
+
autoload :EmbedMany, 'troles/storage/embed_many'
|
10
|
+
autoload :RefMany, 'troles/storage/ref_many'
|
11
|
+
autoload :JoinRefMany, 'troles/storage/join_ref_many'
|
12
|
+
autoload :StringMany, 'troles/storage/string_many'
|
12
13
|
end
|
13
14
|
end
|
data/lib/troles.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
require 'troles/common'
|
2
2
|
require 'troles/macros'
|
3
3
|
|
4
|
-
module Troles
|
5
|
-
|
6
|
-
|
7
|
-
autoload :Api, 'troles/api'
|
8
|
-
autoload :Operations, 'troles/operations'
|
9
|
-
autoload :Strategy, 'troles/strategy'
|
10
|
-
autoload :Storage, 'troles/storage'
|
11
|
-
end
|
4
|
+
module Troles
|
5
|
+
autoload_modules :Config, :Common, :Api, :Operations, :Strategy, :Storage
|
6
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class CreateCustomJoin < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
# down
|
4
|
+
|
5
|
+
create_table :users do |t|
|
6
|
+
# implicit user_id binds to user_id of roles_users join table
|
7
|
+
t.string :name
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
# join table
|
12
|
+
create_table :roles_users_join, :id => false do |t|
|
13
|
+
t.integer :user_id
|
14
|
+
t.integer :role_id
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
create_table :roles do |t|
|
19
|
+
# implicit role_id binds to role_id of roles_users join table
|
20
|
+
t.string :name
|
21
|
+
t.timestamps
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.down
|
26
|
+
drop_table :users
|
27
|
+
drop_table :roles
|
28
|
+
drop_table :users_roles
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class CreateJoinRefMany < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
# down
|
4
|
+
|
5
|
+
create_table :users do |t|
|
6
|
+
# implicit user_id binds to user_id of roles_users join table
|
7
|
+
t.string :name
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
# join table
|
12
|
+
create_table :users_roles, :id => false do |t|
|
13
|
+
t.integer :user_id
|
14
|
+
t.integer :role_id
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
create_table :roles do |t|
|
19
|
+
# implicit role_id binds to role_id of roles_users join table
|
20
|
+
t.string :name
|
21
|
+
t.timestamps
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.down
|
26
|
+
drop_table :users
|
27
|
+
drop_table :roles
|
28
|
+
drop_table :users_roles
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -8,13 +8,6 @@ class CreateRefMany < ActiveRecord::Migration
|
|
8
8
|
t.timestamps
|
9
9
|
end
|
10
10
|
|
11
|
-
# join table
|
12
|
-
create_table :roles_users, :id => false do |t|
|
13
|
-
t.integer :user_id
|
14
|
-
t.integer :role_id
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
11
|
create_table :roles do |t|
|
19
12
|
# implicit role_id binds to role_id of roles_users join table
|
20
13
|
t.string :name
|
@@ -25,7 +18,6 @@ class CreateRefMany < ActiveRecord::Migration
|
|
25
18
|
def self.down
|
26
19
|
drop_table :users
|
27
20
|
drop_table :roles
|
28
|
-
drop_table :users_roles
|
29
21
|
end
|
30
22
|
end
|
31
23
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "active_record/migrations/many/custom_join"
|
2
|
+
|
3
|
+
class User < ActiveRecord::Base
|
4
|
+
# has_and_belongs_to_many :troles, :class_name => 'Role'
|
5
|
+
end
|
6
|
+
|
7
|
+
class Role < ActiveRecord::Base
|
8
|
+
# has_and_belongs_to_many :accounts, :class_name => 'User'
|
9
|
+
end
|
10
|
+
|
11
|
+
class RolesUsersJoin < ActiveRecord::Base
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "active_record/migrations/many/join_ref_many"
|
2
|
+
|
3
|
+
class User < ActiveRecord::Base
|
4
|
+
# has_and_belongs_to_many :troles, :class_name => 'Role'
|
5
|
+
end
|
6
|
+
|
7
|
+
class Role < ActiveRecord::Base
|
8
|
+
# has_and_belongs_to_many :accounts, :class_name => 'User'
|
9
|
+
end
|
10
|
+
|
11
|
+
class UsersRoles < ActiveRecord::Base
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "active_record/strategy_helper"
|
2
|
+
require 'active_record/models/custom_join'
|
3
|
+
|
4
|
+
def migrate_up
|
5
|
+
CreateCustomJoin.up # run migration
|
6
|
+
Config.add_roles [:user, :admin, :editor, :blogger]
|
7
|
+
end
|
8
|
+
|
9
|
+
def migrate_down
|
10
|
+
CreateCustomJoin.down
|
11
|
+
end
|
12
|
+
|
13
|
+
User.troles_strategy :ref_many do |c|
|
14
|
+
c.valid_roles = [:user, :admin, :blogger, :editor]
|
15
|
+
# c.auto_config[:relations] = false
|
16
|
+
end.configure! :role_join_model => 'RolesUsersJoin'
|
17
|
+
|
18
|
+
module UserSetup
|
19
|
+
def find_role name
|
20
|
+
Role.where(:name => name.to_sym).first
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_no_roles_user
|
24
|
+
Factory.create :user, :name => 'no roles', :troles => []
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_user
|
28
|
+
Factory.create :user, :name => 'normal', :troles => [ find_role(:user) ]
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_admin_user
|
32
|
+
Factory.create :user, :name => 'admin', :troles => [ find_role(:admin) ]
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_complex_user
|
36
|
+
Factory.create :user, :name => 'user and admin', :troles => [ find_role(:user), find_role(:admin) ]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
require 'troles/common/api_spec' # Common API examples
|
42
|
+
|
43
|
+
describe 'Troles strategy Custom Join' do
|
44
|
+
it_should_behave_like "Common API"
|
45
|
+
# it_should_behave_like "Troles API"
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "active_record/strategy_helper"
|
2
|
+
require 'active_record/models/join_ref_many'
|
3
|
+
|
4
|
+
def migrate_up
|
5
|
+
CreateJoinRefMany.up # run migration
|
6
|
+
Config.add_roles [:user, :admin, :editor, :blogger]
|
7
|
+
end
|
8
|
+
|
9
|
+
def migrate_down
|
10
|
+
CreateJoinRefMany.down
|
11
|
+
end
|
12
|
+
|
13
|
+
User.troles_strategy :join_ref_many do |c|
|
14
|
+
c.valid_roles = [:user, :admin, :blogger, :editor]
|
15
|
+
# c.auto_config[:relations] = false
|
16
|
+
end.configure!
|
17
|
+
|
18
|
+
module UserSetup
|
19
|
+
def find_role name
|
20
|
+
Role.where(:name => name.to_sym).first
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_no_roles_user
|
24
|
+
Factory.create :user, :name => 'no roles', :troles => []
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_user
|
28
|
+
Factory.create :user, :name => 'normal', :troles => [ find_role(:user) ]
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_admin_user
|
32
|
+
Factory.create :user, :name => 'admin', :troles => [ find_role(:admin) ]
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_complex_user
|
36
|
+
Factory.create :user, :name => 'user and admin', :troles => [ find_role(:user), find_role(:admin) ]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
require 'troles/common/api_spec' # Common API examples
|
42
|
+
|
43
|
+
describe 'Troles strategy :ref_many_join' do
|
44
|
+
it_should_behave_like "Common API"
|
45
|
+
# it_should_behave_like "Troles API"
|
46
|
+
end
|
@@ -12,8 +12,8 @@ end
|
|
12
12
|
|
13
13
|
User.troles_strategy :ref_many do |c|
|
14
14
|
c.valid_roles = [:user, :admin, :blogger, :editor]
|
15
|
-
c.auto_config[:relations] = false
|
16
|
-
end.configure!
|
15
|
+
# c.auto_config[:relations] = false
|
16
|
+
end.configure!
|
17
17
|
|
18
18
|
module UserSetup
|
19
19
|
def find_role name
|
@@ -14,7 +14,7 @@ shared_examples_for "Common Write API for multiple roles" do
|
|
14
14
|
user.has_role?(:admin).should be_true
|
15
15
|
user.has_role?(:user).should be_false
|
16
16
|
user.has_any_role?(:admin, :editor).should be_true
|
17
|
-
user.has_any_role?(:
|
17
|
+
user.has_any_role?(:user).should be_false
|
18
18
|
user.has_all_roles?(:admin, :editor, :blogger).should be_true
|
19
19
|
end
|
20
20
|
|
@@ -23,7 +23,7 @@ shared_examples_for "Common Write API for multiple roles" do
|
|
23
23
|
user.has_role?(:admin).should be_true
|
24
24
|
user.has_role?(:user).should be_false
|
25
25
|
user.has_any_role?(:admin, :editor).should be_true
|
26
|
-
user.has_any_role?(:
|
26
|
+
user.has_any_role?(:user).should be_false
|
27
27
|
user.has_all_roles?(:admin, :editor, :blogger).should be_true
|
28
28
|
end
|
29
29
|
end
|
@@ -48,19 +48,12 @@ shared_examples_for "Common Write API for multiple roles" do
|
|
48
48
|
user.remove_roles :admin, :admin
|
49
49
|
expect { user.role_list }.to change{user.role_list_value}
|
50
50
|
user.has_role?(:admin).should be_false
|
51
|
-
user.roles.list.should
|
51
|
+
user.roles.list.should include(:editor, :blogger)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
describe '#static_role!' do
|
56
56
|
pending 'TODO'
|
57
|
-
|
58
|
-
it "should set set roles to :user only" do
|
59
|
-
user.static_role!(:guest)
|
60
|
-
user.has_role?(:guest).should be_true
|
61
|
-
user.valid_roles.should include(:guest)
|
62
|
-
lambda { user.set_roles(:admin) }.should raise_error
|
63
|
-
end
|
64
57
|
end
|
65
58
|
end
|
66
59
|
|
@@ -69,7 +62,8 @@ shared_examples_for "Common Operations API for multiple roles" do
|
|
69
62
|
it "should clear all roles and invalidate roles cache" do
|
70
63
|
user.set_roles :admin
|
71
64
|
user.roles << [:admin, :editor, :blogger]
|
72
|
-
user.roles.list.should
|
65
|
+
user.roles.list.should include(:admin, :editor, :blogger)
|
66
|
+
|
73
67
|
user.roles.clear!
|
74
68
|
expect { user.role_list }.to change{user.role_list_value }
|
75
69
|
user.role_list.should be_empty
|
@@ -81,7 +75,7 @@ shared_examples_for "Common Operations API for multiple roles" do
|
|
81
75
|
user.set_roles :admin
|
82
76
|
user.roles + [:admin, :editor, :blogger]
|
83
77
|
|
84
|
-
user.roles.list.should
|
78
|
+
user.roles.list.should include(:admin, :editor, :blogger)
|
85
79
|
user.has_role?(:admin).should be_true
|
86
80
|
user.has_role?(:user).should be_false
|
87
81
|
|
@@ -139,4 +133,4 @@ shared_examples_for "Common Operations API for multiple roles" do
|
|
139
133
|
lambda { user.set_roles(:admin) }.should raise_error
|
140
134
|
end
|
141
135
|
end
|
142
|
-
end
|
136
|
+
end
|