troles 0.5.1 → 0.5.2
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/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
|