troles 0.5.0 → 0.5.1
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/Gemfile.lock +1 -1
- data/README.textile +75 -16
- data/VERSION +1 -1
- data/lib/trole/adapters/active_record/config.rb +3 -3
- data/lib/trole/adapters/mongoid/config.rb +5 -5
- data/lib/trole/config.rb +2 -2
- data/lib/trole_groups.rb +10 -0
- data/lib/trole_groups/READ THIS.textile +4 -0
- data/lib/trole_groups/Rolegroups design.textile +218 -0
- data/lib/trole_groups/adapters/active_record.rb +8 -0
- data/lib/trole_groups/adapters/active_record/config.rb +0 -0
- data/lib/trole_groups/adapters/active_record/storage.rb +0 -0
- data/lib/trole_groups/adapters/active_record/strategy.rb +11 -0
- data/lib/trole_groups/adapters/mongoid.rb +8 -0
- data/lib/trole_groups/adapters/mongoid/config.rb +0 -0
- data/lib/trole_groups/api.rb +29 -0
- data/lib/trole_groups/api/cache.rb +13 -0
- data/lib/trole_groups/api/config.rb +4 -0
- data/lib/trole_groups/api/core.rb +50 -0
- data/lib/trole_groups/api/event.rb +29 -0
- data/lib/trole_groups/api/read.rb +56 -0
- data/lib/trole_groups/api/validation.rb +44 -0
- data/lib/trole_groups/api/write.rb +60 -0
- data/lib/trole_groups/config.rb +134 -0
- data/lib/trole_groups/config/schema.rb +65 -0
- data/lib/trole_groups/config/schema/helpers.rb +11 -0
- data/lib/trole_groups/config/schema/role_group_helpers.rb +11 -0
- data/lib/trole_groups/config/valid_role_groups.rb +21 -0
- data/lib/trole_groups/macros.rb +42 -0
- data/lib/trole_groups/macros/configuration.rb +89 -0
- data/lib/trole_groups/macros/configuration/base_loader.rb +35 -0
- data/lib/trole_groups/macros/configuration/config_loader.rb +19 -0
- data/lib/trole_groups/macros/configuration/storage_loader.rb +20 -0
- data/lib/trole_groups/macros/configuration/strategy_loader.rb +38 -0
- data/lib/trole_groups/macros/static_roles.rb +9 -0
- data/lib/trole_groups/macros/strategy_options.rb +21 -0
- data/lib/trole_groups/operations.rb +25 -0
- data/lib/trole_groups/operations/read.rb +36 -0
- data/lib/trole_groups/operations/write.rb +42 -0
- data/lib/trole_groups/storage.rb +27 -0
- data/lib/trole_groups/storage/base_many.rb +93 -0
- data/lib/trole_groups/storage/embed_many.rb +58 -0
- data/lib/trole_groups/storage/ref_many.rb +47 -0
- data/lib/trole_groups/strategy.rb +30 -0
- data/lib/troles/adapters/active_record/config.rb +32 -9
- data/lib/troles/adapters/mongoid/config.rb +7 -7
- data/lib/troles/common/api/core.rb +1 -1
- data/lib/troles/common/config.rb +49 -14
- data/lib/troles/common/config/schema.rb +17 -23
- data/lib/troles/common/config/schema/helpers.rb +77 -0
- data/lib/troles/common/config/schema/role_helpers.rb +27 -0
- data/lib/troles/common/config/static_roles.rb +4 -4
- data/lib/troles/common/macros.rb +4 -4
- data/lib/troles/common/macros/configuration.rb +8 -8
- data/lib/troles/common/macros/strategy_options.rb +4 -4
- data/lib/troles/common/storage.rb +1 -0
- data/lib/troles/config.rb +2 -2
- data/lib/troles/storage/ref_many.rb +2 -3
- data/spec/active_record/models/ref_many.rb +3 -0
- data/spec/active_record/strategies/many/ref_many_spec.rb +2 -1
- data/spec/generic/models/role.rb +2 -1
- data/spec/trole_groups/api/core_api_spec.rb +14 -0
- data/spec/trole_groups/api/read_api_spec.rb +36 -0
- data/spec/trole_groups/api/write_api_spec.rb +19 -0
- data/spec/trole_groups/api_spec.rb +27 -0
- data/spec/trole_groups/generic/models.rb +3 -0
- data/spec/trole_groups/generic/models/role_group.rb +44 -0
- data/spec/trole_groups/generic/models/user.rb +9 -0
- data/spec/trole_groups/strategies/ref_many.rb +51 -0
- data/spec/trole_groups/strategy_helper.rb +9 -0
- data/spec/trole_groups_spec.rb +11 -0
- data/spec/trole_spec_helper.rb +9 -0
- data/spec/troles/api_spec.rb +12 -18
- data/troles.gemspec +52 -4
- metadata +85 -37
- data/development.sqlite3 +0 -0
- data/lib/troles/common/config/schema_helpers.rb +0 -95
@@ -0,0 +1,65 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
class Config
|
3
|
+
module Schema
|
4
|
+
autoload :Helpers, 'trole_groups/config/schema/helpers'
|
5
|
+
autoload :RoleGroupHelpers, 'trole_groups/config/schema/role_group_helpers'
|
6
|
+
|
7
|
+
def configure_models
|
8
|
+
configure_generic
|
9
|
+
configure_field if auto_config?(:fields)
|
10
|
+
configure_relation if auto_config?(:relations)
|
11
|
+
end
|
12
|
+
|
13
|
+
def configure_generic
|
14
|
+
subject_class.send(:attr_accessor, role_field) if generic? || orm == :generic # create troles accessor
|
15
|
+
end
|
16
|
+
|
17
|
+
# Adapter should customize this as needed
|
18
|
+
def configure_field
|
19
|
+
end
|
20
|
+
|
21
|
+
# Adapter should customize this as needed
|
22
|
+
def configure_relation
|
23
|
+
end
|
24
|
+
|
25
|
+
# Sets the role model to use
|
26
|
+
# allows different role subject classes (fx User Accounts) to have different role schemas
|
27
|
+
# @param [Class] the model class
|
28
|
+
def rolegroup_model= model_class
|
29
|
+
@rolegroup_model = model_class.to_s and return if model_class.any_kind_of?(Class, String, Symbol)
|
30
|
+
raise "The rolegroup model must be a Class, was: #{model_class}"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Gets the role model to be used
|
34
|
+
# see (#role_model=)
|
35
|
+
# @return [Class] the model class (defaults to Role)
|
36
|
+
def rolegroup_model
|
37
|
+
@rolegroup_model_found ||= begin
|
38
|
+
models = [@rolegroup_model, role_group_class_name].select do |class_name|
|
39
|
+
try_class(class_name.to_s.camelize)
|
40
|
+
end.compact
|
41
|
+
raise "No #{role_group_class_name} class defined, define a #{role_group_class_name} class or set which class to use, using the :rolegroup_model option on configuration" if models.empty?
|
42
|
+
models.first.to_s.constantize
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def role_group_class_name
|
49
|
+
'RoleGroup'
|
50
|
+
end
|
51
|
+
|
52
|
+
def try_class clazz
|
53
|
+
begin
|
54
|
+
clazz = clazz.constantize if clazz.kind_of?(String)
|
55
|
+
clazz
|
56
|
+
rescue
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
include Helpers
|
62
|
+
include RoleGroupHelpers
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
class Config
|
3
|
+
module ValidRoleGroups
|
4
|
+
def add_valid_rolegroups *rolegroups
|
5
|
+
valid_rolegroups =valid_rolegroups & rolegroups
|
6
|
+
end
|
7
|
+
|
8
|
+
def valid_rolegroups= *rolegroups
|
9
|
+
vrs = rolegroups.flatten.map{|r| r.to_s.alpha_numeric}.map(&:to_sym).uniq
|
10
|
+
raise ArgumentError, "The #{strategy} strategy can only accept 2 valid rolegroups" if (vrs.size > 2) && strategy == :bit_one
|
11
|
+
raise ArgumentError, "The rolegroup names you want to be valid are not valid rolegroup names. Must be alphanumeric, was: #{rolegroups.flatten}" if vrs.empty?
|
12
|
+
@valid_rolegroups ||= vrs
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_rolegroups
|
16
|
+
raise "No valid rolegroups defined" if !@valid_rolegroups || @valid_rolegroups.empty?
|
17
|
+
@valid_rolegroups
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# Macros that can be used directly on the role subject class
|
5
|
+
# These methods are added to the ruby core 'Module' module
|
6
|
+
#
|
7
|
+
# Usage:
|
8
|
+
# class User
|
9
|
+
# troles_strategy :bit_many
|
10
|
+
#
|
11
|
+
|
12
|
+
# puts "TroleGroups macros enabled!"
|
13
|
+
|
14
|
+
module TroleGroups
|
15
|
+
module Macros
|
16
|
+
autoload :Configuration, 'trole_groups/macros/configuration'
|
17
|
+
|
18
|
+
def trolegroups_strategy strategy, options = {}, &block
|
19
|
+
configuration = Configuration.new self, strategy, options
|
20
|
+
|
21
|
+
configuration.load_adapter
|
22
|
+
# puts "strategy module: #{configuration.strategy_module}"
|
23
|
+
begin
|
24
|
+
self.send :include, configuration.strategy_module
|
25
|
+
rescue
|
26
|
+
puts "error loading strategy: #{configuration.strategy_module}"
|
27
|
+
end
|
28
|
+
|
29
|
+
configuration.define_hooks
|
30
|
+
configuration.apply_strategy_options!
|
31
|
+
|
32
|
+
if strategy == :bit_one
|
33
|
+
trolegroups_config.valid_roles = [:user, :admin] # default binary roles
|
34
|
+
end
|
35
|
+
|
36
|
+
yield trolegroups_config if block_given?
|
37
|
+
trolegroups_config
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Module.send :include, TroleGroups::Macros
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
module Macros
|
3
|
+
class Configuration
|
4
|
+
autoload :BaseLoader, 'trole_groups/macros/configuration/base_loader'
|
5
|
+
autoload :ConfigLoader, 'trole_groups/macros/configuration/config_loader'
|
6
|
+
autoload :StrategyLoader, 'trole_groups/macros/configuration/strategy_loader'
|
7
|
+
autoload :StorageLoader, 'trole_groups/macros/configuration/storage_loader'
|
8
|
+
|
9
|
+
attr_reader :strategy, :singularity, :orm, :auto_load, :options, :subject_class
|
10
|
+
|
11
|
+
def initialize subject_class, strategy, options = {}
|
12
|
+
@subject_class = subject_class
|
13
|
+
@strategy = strategy
|
14
|
+
@orm = options[:orm] || Troles::Config.default_orm
|
15
|
+
@auto_load = options[:auto_load] || Troles::Config.auto_load?
|
16
|
+
options[:strategy] = strategy
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def strategy_module
|
21
|
+
strategy_loader.strategy_module
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_adapter
|
25
|
+
return false if !auto_load?
|
26
|
+
|
27
|
+
path = "#{namespace}/adapters/#{orm.to_s.underscore}"
|
28
|
+
begin
|
29
|
+
require path
|
30
|
+
rescue
|
31
|
+
raise "Adapter for :#{orm} could not be found at: #{path}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def apply_strategy_options!
|
36
|
+
trolegroups_config.apply_options! options
|
37
|
+
|
38
|
+
# StrategyOptions.new(subject_class)
|
39
|
+
# extract_macros(options).each{|m| apply_macro m}
|
40
|
+
end
|
41
|
+
|
42
|
+
def trolegroups_config
|
43
|
+
subject_class.trolegroups_config
|
44
|
+
end
|
45
|
+
|
46
|
+
def define_hooks
|
47
|
+
storage_class = storage_loader.storage_class
|
48
|
+
# puts "storage_class: #{storage_class}"
|
49
|
+
subject_class.send :define_method, :group_storage do
|
50
|
+
@group_storage ||= storage_class
|
51
|
+
end
|
52
|
+
|
53
|
+
config_class = config_loader.config_class
|
54
|
+
puts "config_class: #{config_class}" if Troles::Config.log_on
|
55
|
+
subject_class.singleton_class.class_eval %{
|
56
|
+
def trolegroups_config
|
57
|
+
@trolegroups_config ||= #{config_class}.new #{subject_class}, #{options.inspect}
|
58
|
+
end
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
def namespace
|
65
|
+
'trole_groups'
|
66
|
+
end
|
67
|
+
|
68
|
+
def storage_loader
|
69
|
+
@storage_loader ||= StorageLoader.new strategy, orm
|
70
|
+
end
|
71
|
+
|
72
|
+
def config_loader
|
73
|
+
@config_loader ||= ConfigLoader.new strategy, orm
|
74
|
+
end
|
75
|
+
|
76
|
+
def strategy_loader
|
77
|
+
@strategy_loader ||= StrategyLoader.new strategy, orm
|
78
|
+
end
|
79
|
+
|
80
|
+
def auto_load?
|
81
|
+
(auto_load && orm) || false
|
82
|
+
end
|
83
|
+
|
84
|
+
# def extract_macros options = {}
|
85
|
+
# [:static_role].select {|o| options[o]}
|
86
|
+
# end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module TroleGroups::Macros
|
2
|
+
class Configuration
|
3
|
+
class BaseLoader
|
4
|
+
attr_reader :strategy, :orm
|
5
|
+
|
6
|
+
def initialize strategy, orm
|
7
|
+
@strategy = strategy
|
8
|
+
@orm = orm || Troles::Config.default_orm
|
9
|
+
end
|
10
|
+
|
11
|
+
def try_module full_name
|
12
|
+
begin
|
13
|
+
full_name.constantize
|
14
|
+
true
|
15
|
+
rescue
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def base_class
|
21
|
+
"BaseMany"
|
22
|
+
end
|
23
|
+
|
24
|
+
def namespace
|
25
|
+
'TroleGroups'
|
26
|
+
end
|
27
|
+
|
28
|
+
def orm_namespace
|
29
|
+
ns = namespace
|
30
|
+
ns << "::#{orm.to_s.camelize}" if orm
|
31
|
+
ns
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module TroleGroups::Macros
|
2
|
+
class Configuration
|
3
|
+
class ConfigLoader < BaseLoader
|
4
|
+
|
5
|
+
def initialize strategy, orm
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def config_class
|
10
|
+
begin
|
11
|
+
"#{orm_namespace}::Config".constantize
|
12
|
+
rescue
|
13
|
+
# use generic if no ORM specific strategy found!
|
14
|
+
"#{namespace}::Config".constantize
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TroleGroups::Macros
|
2
|
+
class Configuration
|
3
|
+
class StorageLoader < BaseLoader
|
4
|
+
|
5
|
+
def initialize strategy, orm
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def storage_class
|
10
|
+
begin
|
11
|
+
"#{orm_namespace}::Storage::#{strategy.to_s.camelize}".constantize
|
12
|
+
rescue
|
13
|
+
# use generic if no ORM specific strategy found!
|
14
|
+
"#{namespace}::Storage::#{strategy.to_s.camelize}".constantize
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module TroleGroups::Macros
|
2
|
+
class Configuration
|
3
|
+
class StrategyLoader < BaseLoader
|
4
|
+
|
5
|
+
def initialize strategy, orm
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def strategy_module
|
10
|
+
@strategy_module ||= orm_strategy_module || generic_strategy_module
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def orm_strategy_module
|
16
|
+
@orm_strategy_module ||= begin
|
17
|
+
mods_found = ["#{orm_namespace}::Strategy::#{strategy.to_s.camelize}", "#{namespace}::Strategy::#{base_class}"].select do |full_name|
|
18
|
+
try_module(full_name)
|
19
|
+
end
|
20
|
+
!mods_found.empty? ? mods_found.first.constantize : nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def generic_strategy_module strategy_name, options
|
25
|
+
@generic_module ||= begin
|
26
|
+
base_class = base_name(strategy_name)
|
27
|
+
|
28
|
+
# use generic if no ORM specific strategy found!
|
29
|
+
ns = namespace(strategy_name, options)
|
30
|
+
mods_found = ["#{namespace}::Strategy::#{strategy.to_s.camelize}", "#{namespace}::Strategy::#{base_class}"].select do |full_name|
|
31
|
+
try_module(full_name)
|
32
|
+
end
|
33
|
+
!mods_found.empty? ? mods_found.first.constantize : nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Troles
|
2
|
+
module Macros
|
3
|
+
class StrategyOptions
|
4
|
+
attr_reader :subject_class
|
5
|
+
|
6
|
+
def initialize subject_class
|
7
|
+
@subject_class = subject_class
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param [Symbol] name of the macro to run
|
11
|
+
def apply_macro name
|
12
|
+
# overrides default method that returns false
|
13
|
+
begin
|
14
|
+
subject_class.send :include, "Troles::Macros::#{strategy_name.to_s.camelize}".constantize
|
15
|
+
rescue
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
class Operations # < Troles::Common::Operations
|
3
|
+
autoload :Read, 'trole_groups/operations/read'
|
4
|
+
autoload :Write, 'trole_groups/operations/write'
|
5
|
+
|
6
|
+
include Read
|
7
|
+
include Write
|
8
|
+
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
attr_reader :rolegroup_subject
|
12
|
+
|
13
|
+
# constructor
|
14
|
+
# @param [Object] the role subject, fx a User or UserAccount
|
15
|
+
def initialize rolegroup_subject
|
16
|
+
@rolegroup_subject = rolegroup_subject
|
17
|
+
end
|
18
|
+
|
19
|
+
# required method to act as enumerable
|
20
|
+
# iterates and yields all roles in the role list (Symbols)
|
21
|
+
def each
|
22
|
+
list.each { |rolegroup| yield rolegroup }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module TroleGroups
|
2
|
+
class Operations
|
3
|
+
module Read
|
4
|
+
def roles
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
def roles_for *names
|
9
|
+
rolegroup_subject.roles_for *names
|
10
|
+
end
|
11
|
+
|
12
|
+
# The roles list of the role subject
|
13
|
+
# @return [Array<Symbol>] the list of roles
|
14
|
+
def list
|
15
|
+
rolegroup_subject.rolegroup_list
|
16
|
+
end
|
17
|
+
|
18
|
+
# Test if the role subject has exactly the given roles
|
19
|
+
# @param [Array<Symbol>] role list to test
|
20
|
+
# @return [true, false] true if role subject has exactly those roles, false otherwise
|
21
|
+
def has? *rolegroups
|
22
|
+
list == rolegroups.to_symbols_uniq
|
23
|
+
end
|
24
|
+
|
25
|
+
# Which of the given roles are used by the role subject
|
26
|
+
# @param [Array<Symbol>] roles to test for inclusion
|
27
|
+
#
|
28
|
+
# Usage:
|
29
|
+
# - user.roles.used(:admin, :editor).include? :editor
|
30
|
+
#
|
31
|
+
def used *rolegroups
|
32
|
+
list & rolegroups.to_symbols_uniq
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|