troles 0.5.0
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/.rspec +1 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +161 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +686 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/config/database.yml +4 -0
- data/development.sqlite3 +0 -0
- data/lib/trole/adapters/active_record/config.rb +23 -0
- data/lib/trole/adapters/active_record/storage.rb +0 -0
- data/lib/trole/adapters/active_record/strategy.rb +0 -0
- data/lib/trole/adapters/active_record.rb +8 -0
- data/lib/trole/adapters/mongoid/config.rb +34 -0
- data/lib/trole/adapters/mongoid/storage.rb +0 -0
- data/lib/trole/adapters/mongoid/strategy.rb +0 -0
- data/lib/trole/adapters/mongoid.rb +0 -0
- data/lib/trole/api/cache.rb +9 -0
- data/lib/trole/api/config.rb +12 -0
- data/lib/trole/api/core.rb +20 -0
- data/lib/trole/api/event.rb +9 -0
- data/lib/trole/api/read.rb +14 -0
- data/lib/trole/api/validation.rb +9 -0
- data/lib/trole/api/write.rb +25 -0
- data/lib/trole/api.rb +41 -0
- data/lib/trole/config.rb +15 -0
- data/lib/trole/macros.rb +5 -0
- data/lib/trole/operations/read.rb +12 -0
- data/lib/trole/operations/write.rb +11 -0
- data/lib/trole/operations.rb +34 -0
- data/lib/trole/storage/base_one.rb +46 -0
- data/lib/trole/storage/bit_one.rb +43 -0
- data/lib/trole/storage/embed_one.rb +36 -0
- data/lib/trole/storage/ref_one.rb +39 -0
- data/lib/trole/storage/string_one.rb +50 -0
- data/lib/trole/storage.rb +14 -0
- data/lib/trole/strategy.rb +35 -0
- data/lib/trole.rb +10 -0
- data/lib/troles/adapters/active_record/Design Notes.textile +4 -0
- data/lib/troles/adapters/active_record/config.rb +51 -0
- data/lib/troles/adapters/active_record/storage/embed_many.rb +8 -0
- data/lib/troles/adapters/active_record/storage.rb +5 -0
- data/lib/troles/adapters/active_record/strategy.rb +11 -0
- data/lib/troles/adapters/active_record.rb +8 -0
- data/lib/troles/adapters/mongoid/Design Notes.textile +3 -0
- data/lib/troles/adapters/mongoid/config.rb +45 -0
- data/lib/troles/adapters/mongoid.rb +8 -0
- data/lib/troles/api/cache.rb +4 -0
- data/lib/troles/api/config.rb +9 -0
- data/lib/troles/api/core.rb +9 -0
- data/lib/troles/api/event.rb +4 -0
- data/lib/troles/api/read.rb +4 -0
- data/lib/troles/api/validation.rb +4 -0
- data/lib/troles/api/write.rb +4 -0
- data/lib/troles/api.rb +40 -0
- data/lib/troles/common/api/cache.rb +12 -0
- data/lib/troles/common/api/config.rb +4 -0
- data/lib/troles/common/api/core.rb +52 -0
- data/lib/troles/common/api/event.rb +39 -0
- data/lib/troles/common/api/read.rb +44 -0
- data/lib/troles/common/api/validation.rb +44 -0
- data/lib/troles/common/api/write.rb +76 -0
- data/lib/troles/common/api.rb +28 -0
- data/lib/troles/common/config/schema.rb +72 -0
- data/lib/troles/common/config/schema_helpers.rb +95 -0
- data/lib/troles/common/config/static_roles.rb +14 -0
- data/lib/troles/common/config/valid_roles.rb +21 -0
- data/lib/troles/common/config.rb +96 -0
- data/lib/troles/common/dependencies.rb +9 -0
- data/lib/troles/common/event_manager.rb +40 -0
- data/lib/troles/common/macros/configuration/base_loader.rb +40 -0
- data/lib/troles/common/macros/configuration/config_loader.rb +19 -0
- data/lib/troles/common/macros/configuration/storage_loader.rb +20 -0
- data/lib/troles/common/macros/configuration/strategy_loader.rb +38 -0
- data/lib/troles/common/macros/configuration.rb +89 -0
- data/lib/troles/common/macros/static_roles.rb +9 -0
- data/lib/troles/common/macros/strategy_options.rb +21 -0
- data/lib/troles/common/macros.rb +38 -0
- data/lib/troles/common/marshaller/bitmask.rb +43 -0
- data/lib/troles/common/marshaller/generic.rb +24 -0
- data/lib/troles/common/marshaller.rb +14 -0
- data/lib/troles/common/operations/read.rb +28 -0
- data/lib/troles/common/operations/write.rb +42 -0
- data/lib/troles/common/operations.rb +33 -0
- data/lib/troles/common/storage.rb +73 -0
- data/lib/troles/common.rb +17 -0
- data/lib/troles/config.rb +15 -0
- data/lib/troles/macros.rb +7 -0
- data/lib/troles/meta.rb +5 -0
- data/lib/troles/operations/read.rb +6 -0
- data/lib/troles/operations/write.rb +6 -0
- data/lib/troles/operations.rb +12 -0
- data/lib/troles/storage/base_many.rb +25 -0
- data/lib/troles/storage/bit_many.rb +56 -0
- data/lib/troles/storage/embed_many.rb +58 -0
- data/lib/troles/storage/ref_many.rb +44 -0
- data/lib/troles/storage/string_many.rb +41 -0
- data/lib/troles/storage.rb +13 -0
- data/lib/troles/strategy.rb +34 -0
- data/lib/troles.rb +11 -0
- data/playbox/old_rake +25 -0
- data/spec/Guide to running specs.textile +16 -0
- data/spec/active_record/migrations/many/bit_many.rb +16 -0
- data/spec/active_record/migrations/many/ref_many.rb +31 -0
- data/spec/active_record/migrations/many/string_many.rb +16 -0
- data/spec/active_record/migrations/one/bit_one.rb +14 -0
- data/spec/active_record/migrations/one/ref_one.rb +20 -0
- data/spec/active_record/migrations/one/string_one.rb +14 -0
- data/spec/active_record/models/ref_many.rb +10 -0
- data/spec/active_record/models/ref_one.rb +10 -0
- data/spec/active_record/models/role.rb +2 -0
- data/spec/active_record/models/user.rb +5 -0
- data/spec/active_record/models.rb +2 -0
- data/spec/active_record/strategies/many/bit_many_spec.rb +41 -0
- data/spec/active_record/strategies/many/ref_many_spec.rb +45 -0
- data/spec/active_record/strategies/many/string_many_spec.rb +39 -0
- data/spec/active_record/strategies/one/bit_one_spec.rb +35 -0
- data/spec/active_record/strategies/one/ref_one_spec.rb +41 -0
- data/spec/active_record/strategies/one/string_one_spec.rb +35 -0
- data/spec/active_record/strategy_helper.rb +4 -0
- data/spec/active_record_helper.rb +50 -0
- data/spec/db/database.yml +4 -0
- data/spec/dummy/Gemfile.lock +108 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/images/rails.png +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/main_controller.rb +16 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/ref_many_user.rb +7 -0
- data/spec/dummy/app/models/ref_one_user.rb +3 -0
- data/spec/dummy/app/models/role.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/main/index.html.erb +3 -0
- data/spec/dummy/config/application.rb +54 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +24 -0
- data/spec/dummy/config/environments/production.rb +52 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/troles.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +60 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/01_create_roles.rb +14 -0
- data/spec/dummy/db/migrate/02_create_ref_many_users.rb +20 -0
- data/spec/dummy/db/schema.rb +32 -0
- data/spec/dummy/db/seeds.rb +4 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy_spec_helper.rb +33 -0
- data/spec/factories.rb +8 -0
- data/spec/generic/models/accounts/admin_account.rb +7 -0
- data/spec/generic/models/accounts/blogger_account.rb +7 -0
- data/spec/generic/models/accounts/user_account.rb +7 -0
- data/spec/generic/models/accounts.rb +1 -0
- data/spec/generic/models/base_user.rb +27 -0
- data/spec/generic/models/role.rb +37 -0
- data/spec/generic/models/user.rb +7 -0
- data/spec/generic/models.rb +3 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/integration/troles/Running dummy tests.textile +35 -0
- data/spec/integration/troles/navigation_spec.rb +49 -0
- data/spec/mongoid/models/ref_many.rb +15 -0
- data/spec/mongoid/models/ref_one.rb +15 -0
- data/spec/mongoid/models/role.rb +5 -0
- data/spec/mongoid/models/user.rb +9 -0
- data/spec/mongoid/models.rb +2 -0
- data/spec/mongoid/strategies/many/bit_many_spec.rb +35 -0
- data/spec/mongoid/strategies/many/ref_many_spec.rb +35 -0
- data/spec/mongoid/strategies/many/string_many_spec.rb +30 -0
- data/spec/mongoid/strategies/one/bit_one_spec.rb +26 -0
- data/spec/mongoid/strategies/one/ref_one_spec.rb +31 -0
- data/spec/mongoid/strategies/one/string_one_spec.rb +26 -0
- data/spec/mongoid/strategy_helper.rb +4 -0
- data/spec/mongoid_helper.rb +19 -0
- data/spec/playbox/rspec_examples.rb +381 -0
- data/spec/support/shared_examples.rb +1 -0
- data/spec/trole/Trole Design.textile +4 -0
- data/spec/trole/api/cache_api_spec.rb +2 -0
- data/spec/trole/api/core_api_spec.rb +4 -0
- data/spec/trole/api/event_api.rb +2 -0
- data/spec/trole/api/operations_api_spec.rb +2 -0
- data/spec/trole/api/read_api_spec.rb +5 -0
- data/spec/trole/api/validation_api_spec.rb +2 -0
- data/spec/trole/api/write_api_spec.rb +2 -0
- data/spec/trole/api_spec.rb +60 -0
- data/spec/trole/multi_roles_spec.rb +163 -0
- data/spec/trole/operations/read_spec.rb +18 -0
- data/spec/trole/operations/write_spec.rb +0 -0
- data/spec/trole/playbox/shared_examples.rb +107 -0
- data/spec/trole/strategies/bit_one_spec.rb +22 -0
- data/spec/trole/strategies/embed_one_spec.rb +32 -0
- data/spec/trole/strategies/ref_one_spec.rb +29 -0
- data/spec/trole/strategies/string_one_spec.rb +26 -0
- data/spec/trole/strategy_helper.rb +3 -0
- data/spec/trole/two_roles_spec.rb +76 -0
- data/spec/trole_spec.rb +12 -0
- data/spec/trole_spec_helper.rb +20 -0
- data/spec/troles/api/cache_api_spec.rb +2 -0
- data/spec/troles/api/core_api_spec.rb +4 -0
- data/spec/troles/api/event_api.rb +2 -0
- data/spec/troles/api/read_api_spec.rb +2 -0
- data/spec/troles/api/validation_api_spec.rb +2 -0
- data/spec/troles/api/write_api_spec.rb +2 -0
- data/spec/troles/api_spec.rb +41 -0
- data/spec/troles/common/api/cache_api_spec.rb +31 -0
- data/spec/troles/common/api/config_api.rb +0 -0
- data/spec/troles/common/api/core_api_spec.rb +14 -0
- data/spec/troles/common/api/event_api_spec.rb +9 -0
- data/spec/troles/common/api/operations_api_spec.rb +55 -0
- data/spec/troles/common/api/read_api_spec.rb +23 -0
- data/spec/troles/common/api/validation_api_spec.rb +46 -0
- data/spec/troles/common/api/write_api_spec.rb +81 -0
- data/spec/troles/common/api_spec.rb +101 -0
- data/spec/troles/common/config_spec.rb +11 -0
- data/spec/troles/common/multi_roles_spec.rb +142 -0
- data/spec/troles/marshaller/bitmask_spec.rb +14 -0
- data/spec/troles/operations/read_ops_spec.rb +0 -0
- data/spec/troles/operations/write_ops_spec.rb +0 -0
- data/spec/troles/playbox/shared_examples.rb +68 -0
- data/spec/troles/strategies/bit_many_spec.rb +30 -0
- data/spec/troles/strategies/embed_many_spec.rb +35 -0
- data/spec/troles/strategies/ref_many_spec.rb +36 -0
- data/spec/troles/strategies/string_many_spec.rb +32 -0
- data/spec/troles/strategy_helper.rb +3 -0
- data/spec/troles_spec.rb +10 -0
- data/troles.gemspec +325 -0
- metadata +469 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
module Troles::ActiveRecord
|
2
|
+
class Config < Troles::Common::Config
|
3
|
+
|
4
|
+
attr_accessor :role_join_model
|
5
|
+
|
6
|
+
def initialize clazz, options = {}
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def configure_relation
|
11
|
+
case strategy
|
12
|
+
when :ref_many
|
13
|
+
return configure_join_model if role_join_model
|
14
|
+
has_and_belongs_many clazz, role_model, :key => :accounts
|
15
|
+
when :embed_many
|
16
|
+
raise "Embed many configuration not yet implemented for ActiveRecord"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# AR sets this up ont its own using DB Table info
|
21
|
+
def configure_field
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def join_key
|
27
|
+
make_key role_join_model
|
28
|
+
end
|
29
|
+
|
30
|
+
def join_model
|
31
|
+
# UserAccount
|
32
|
+
# has_many :troles, :class_name => 'Role', :through => :users_roles
|
33
|
+
has_many_for clazz, role_model, :through => join_key
|
34
|
+
# has_many :user_roles, :class_name => 'UserRole'
|
35
|
+
has_many_for clazz, role_join_model, :key => join_key
|
36
|
+
|
37
|
+
# UserRole (custom join class name)
|
38
|
+
# belongs_to :user, :class_name => 'UserAccount'
|
39
|
+
belongs_to_for role_join_model, clazz
|
40
|
+
# belongs_to :role, :class_name => 'Role'
|
41
|
+
belongs_to_for role_join_model, role_model
|
42
|
+
|
43
|
+
# Role
|
44
|
+
# has_many :accounts, :class_name => 'User', :through => :user_roles
|
45
|
+
has_many_for role, clazz, :through => join_key, :key => :accounts
|
46
|
+
|
47
|
+
# has_many :user_roles, :class_name => 'UserRole'
|
48
|
+
has_many_for role, role_join_model, :key => join_key
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Troles::ActiveRecord
|
2
|
+
module Strategy
|
3
|
+
module BaseMany
|
4
|
+
# @param [Class] the role subject class for which to include the Role strategy (fx User Account)
|
5
|
+
#
|
6
|
+
def self.included(base)
|
7
|
+
base.send :include, Troles::Strategy::BaseMany
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module Troles
|
2
|
+
module ActiveRecord
|
3
|
+
autoload :Config, 'troles/adapters/active_record/config'
|
4
|
+
# autoload :Api, 'troles/adapters/active_record/api'
|
5
|
+
autoload :Storage, 'troles/adapters/active_record/storage'
|
6
|
+
autoload :Strategy, 'troles/adapters/active_record/strategy'
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Troles::Mongoid
|
2
|
+
class Config < Troles::Common::Config
|
3
|
+
|
4
|
+
def initialize clazz, options = {}
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
# more likely, strategy should be part of configuration options directly when Config object is created!
|
9
|
+
def configure_relation
|
10
|
+
case strategy
|
11
|
+
when :ref_many
|
12
|
+
has_many_for clazz, :role, :through => join_key
|
13
|
+
|
14
|
+
belongs_to_for join_model, :user
|
15
|
+
belongs_to_for join_model, :role
|
16
|
+
|
17
|
+
has_many_for role, :user, :through => join_key
|
18
|
+
|
19
|
+
when :embed_many
|
20
|
+
embeds_many clazz, :role
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure_field
|
25
|
+
type = case strategy
|
26
|
+
when :bit_many
|
27
|
+
Integer
|
28
|
+
when :string_many
|
29
|
+
String
|
30
|
+
end
|
31
|
+
# field :name, :type => String
|
32
|
+
clazz.send(:field, role_field, type_opts(type)) if type
|
33
|
+
end
|
34
|
+
|
35
|
+
def type_opts type
|
36
|
+
{ :type => type }
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def embeds_many from, to
|
42
|
+
make_relationship :embeds_many, from, to
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/troles/api.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# Many roles Api to be included directly on the role subject class (fx User or User Account)
|
5
|
+
#
|
6
|
+
module Troles
|
7
|
+
module Api
|
8
|
+
autoload :Core, 'troles/api/core'
|
9
|
+
autoload :Config, 'troles/api/config'
|
10
|
+
autoload :Cache, 'troles/api/cache'
|
11
|
+
|
12
|
+
autoload :Event, 'troles/api/event'
|
13
|
+
autoload :Read, 'troles/api/read'
|
14
|
+
autoload :Store, 'troles/api/store'
|
15
|
+
autoload :Validation, 'troles/api/validation'
|
16
|
+
autoload :Write, 'troles/api/write'
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
#
|
20
|
+
# When the Troles::Api is included by the Role Subject class (fx a User Account)
|
21
|
+
# first include methods from Troles Common API
|
22
|
+
# then include Troles API on top
|
23
|
+
#
|
24
|
+
# @param [Class] the role subject class (fx User or UserAccount)
|
25
|
+
#
|
26
|
+
def included(base)
|
27
|
+
base.send :include, Troles::Common::Api
|
28
|
+
self.extend Troles::Common::Api::ClassMethods # draws in the #apis method from Common Api
|
29
|
+
apis.each do |api|
|
30
|
+
begin
|
31
|
+
base.send :include, "Troles::Api::#{api.to_s.camelize}".constantize
|
32
|
+
base.extend "Troles::Api::#{api.to_s.camelize}::ClassMethods".constantize
|
33
|
+
rescue
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
extend ClassMethods
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# Core Troles API functions
|
5
|
+
#
|
6
|
+
module Troles::Common::Api
|
7
|
+
module Core
|
8
|
+
|
9
|
+
# Access to the Troles operations API
|
10
|
+
# @return [Troles::Operations] the operations API object
|
11
|
+
def roles
|
12
|
+
@roles ||= Troles::Operations.new(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Sets the roles of the subject
|
16
|
+
# (see #set_roles)
|
17
|
+
def roles= *new_roles
|
18
|
+
roles.set_roles new_roles
|
19
|
+
end
|
20
|
+
|
21
|
+
# If this role subject instance should have static (immutable) roles
|
22
|
+
# @return [true, false] defaults to false so a role subject is allowed to change roles
|
23
|
+
def static_roles?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def troles_config
|
28
|
+
self.class.troles_config
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
|
33
|
+
def valid_roles
|
34
|
+
troles_config.valid_roles
|
35
|
+
end
|
36
|
+
|
37
|
+
# # TODO: make sure alphanumeric only
|
38
|
+
# def valid_roles= *roles
|
39
|
+
# troles_config.valid_roles = *roles
|
40
|
+
# end
|
41
|
+
|
42
|
+
# If all role subjects using this strategy should have static (immutable) roles
|
43
|
+
#
|
44
|
+
# @note Should also proxy Config object?
|
45
|
+
#
|
46
|
+
# @return [true, false] if role subjects have static roles or not (default: false)
|
47
|
+
def static_roles?
|
48
|
+
troles_config.static_roles_for_class?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# Event API
|
5
|
+
#
|
6
|
+
module Troles::Common::Api
|
7
|
+
module Event
|
8
|
+
# A change to the roles of the user should be published to an event handler
|
9
|
+
# this can be used to update both the Role cache of the user and fx the RolePermit cache.
|
10
|
+
# A Role Groups listener can also subscribe to this event
|
11
|
+
def update_roles
|
12
|
+
publish_change(:roles) if role_field_changed?(troles_config.role_field)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Check if a field on the model changed
|
16
|
+
# For Rails 3, See http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
|
17
|
+
# @param [String] the field to test for change
|
18
|
+
def role_field_changed? name
|
19
|
+
begin
|
20
|
+
send :"#{name}_changed?"
|
21
|
+
rescue
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Publishes change event to the EventManager configured
|
27
|
+
# The EventManager is notied of the even type and who (which instance) sent it
|
28
|
+
# @param [Symbol] the event
|
29
|
+
def publish_change event
|
30
|
+
send :invalidate_role_cache! if event == :roles
|
31
|
+
event_manager.publish_change event, :from => self
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Trole::EventManager] The event manager singleton (class) to use to handle role events
|
35
|
+
def event_manager
|
36
|
+
Troles::Common::EventManager
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# Common Read API
|
4
|
+
#
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
module Troles::Common::Api
|
8
|
+
module Read
|
9
|
+
|
10
|
+
# Ensures that the common API methods always have a common underlying model to work on
|
11
|
+
# @note This Set should be cached and only invalidated when the user has a change of roles
|
12
|
+
# @return Array<Symbol> Set of role names
|
13
|
+
def role_list
|
14
|
+
@role_list ||= begin
|
15
|
+
store.display_roles.flatten
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Does the role subject has the role or not?
|
20
|
+
# @return [true, false]
|
21
|
+
def has_role? role
|
22
|
+
role_list.include? role.to_sym
|
23
|
+
end
|
24
|
+
|
25
|
+
# Does the role subject have ONLY that role or not?
|
26
|
+
# @return [true, false]
|
27
|
+
def is_role? role
|
28
|
+
role_list.first == role.to_sym && role_list.size == 1
|
29
|
+
end
|
30
|
+
|
31
|
+
# Checks if the role subject has any of the listed roles
|
32
|
+
# @param [Array<Symbol>]
|
33
|
+
# @return [true, false]
|
34
|
+
def has_roles? *roles
|
35
|
+
(roles.to_symbols - role_list).empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Checks if the role subject has any of the listed roles
|
39
|
+
# (see #has_roles?)
|
40
|
+
def has_any_role? *roles
|
41
|
+
!(role_list & roles.to_symbols).empty?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# Common Validation API
|
5
|
+
#
|
6
|
+
module Troles::Common::Api
|
7
|
+
module Validation
|
8
|
+
|
9
|
+
# @return [Symbol, false] returns the role if it's valid, false if not
|
10
|
+
def check_valid_role? role
|
11
|
+
return role if valid_roles.include? role.to_sym
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array<Symbol>] returns the valid roles or empty list if no valid roles
|
16
|
+
def check_valid_roles? *roles
|
17
|
+
valid_roles & roles.to_symbols
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
# Ensures the role is valid
|
23
|
+
# @param [Symbol] role name
|
24
|
+
# @return [Symbol, false, Error] a valid role name, false if invalid, or Error on some error
|
25
|
+
def make_valid_role role
|
26
|
+
raise ArgumentError, "Role to set must be a Symbol or String" if !role.kind_of_label?
|
27
|
+
check_valid_role? role.to_s.alpha_numeric
|
28
|
+
end
|
29
|
+
|
30
|
+
# Ensures the role are valid
|
31
|
+
# @param [Symbol] list of roles
|
32
|
+
# @return [Array<Symbol>] the valid roles from the list of roles given
|
33
|
+
def make_valid_roles *roles
|
34
|
+
roles = roles.to_symbols_uniq
|
35
|
+
return [] if roles.empty?
|
36
|
+
check_valid_roles? roles.map{|r| r.to_s.alpha_numeric}
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array<Symbol>] the valid roles of the role subject
|
40
|
+
def valid_roles
|
41
|
+
self.class.troles_config.valid_roles
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# @note all methods should operate on the data store via the #store
|
4
|
+
#
|
5
|
+
module Troles::Common::Api
|
6
|
+
module Write
|
7
|
+
|
8
|
+
# Do we need a static_roles! method? I think so!
|
9
|
+
def static_role! role_name
|
10
|
+
raise ArgumentError, "Take a single role name, was: #{role_name}" if !role_name || !role_name.kind_of_label?
|
11
|
+
troles_config.add_valid_roles role_name
|
12
|
+
if set_roles role_name
|
13
|
+
define_method :static_roles? do
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Add a single new role to the roles of the subject
|
20
|
+
# @param [Symbol] role to add
|
21
|
+
# @return (see #add_roles)
|
22
|
+
def add_role role_name
|
23
|
+
raise ArgumentError, "Take a single role name, was: #{role_name}" if !role_name || !role_name.kind_of_label?
|
24
|
+
add_roles role_name
|
25
|
+
end
|
26
|
+
|
27
|
+
# Remove a single role from the roles of the subject
|
28
|
+
# @param [Symbol] role to remove
|
29
|
+
# @return (see #remove_roles)
|
30
|
+
def remove_role role_name
|
31
|
+
raise ArgumentError, "Take a single role name, was: #{role_name}" if !role_name || !role_name.kind_of_label?
|
32
|
+
remove_roles role_name
|
33
|
+
end
|
34
|
+
|
35
|
+
# Adds a set of new roles to the roles of the subject
|
36
|
+
# @param [Array<Symbol>] list of roles to add
|
37
|
+
# @return [true, false, Error] true if ok, false if static or invalid, Error on some error
|
38
|
+
def add_roles *new_roles
|
39
|
+
store.set_roles (role_list | new_roles.to_symbols_uniq) # Set Union (joined set)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Removes a set of new roles to the roles of the subject
|
43
|
+
# (see #add_roles)
|
44
|
+
def remove_roles *the_roles
|
45
|
+
store.set_roles (role_list - the_roles.to_symbols_uniq)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Sets new roles for the subject
|
49
|
+
# @param [Array<Symbol>] list of role names
|
50
|
+
# @return [true, false, Error] true if set ok, false if any roles were invalid, Error on some error
|
51
|
+
def set_roles *roles
|
52
|
+
roles_to_set = make_valid_roles(*roles).flat_uniq
|
53
|
+
return false if !roles_to_set || roles_to_set.empty?
|
54
|
+
store.set_roles(roles_to_set)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Clears all the roles of the subject
|
58
|
+
# @return [true, false, Error] true if ok, false if roles are static, Error on some error
|
59
|
+
def clear_roles!
|
60
|
+
store.clear!
|
61
|
+
end
|
62
|
+
|
63
|
+
module ClassMethods
|
64
|
+
# Sets which roles are valid for the role subject class (fx User or UserAccount)
|
65
|
+
#
|
66
|
+
# @note this in effect limits what roles can be assigned to any instance of the class
|
67
|
+
#
|
68
|
+
# @param [Array<Symbol>] list of role names
|
69
|
+
def set_valid_roles *roles
|
70
|
+
roles = roles.to_symbols_uniq
|
71
|
+
raise ArgumentError, "Roles must contain Symbols or Strings" if roles.empty?
|
72
|
+
@valid_roles = roles
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Troles::Common
|
2
|
+
module Api
|
3
|
+
autoload :Core, 'troles/common/api/core'
|
4
|
+
autoload :Cache, 'troles/common/api/cache'
|
5
|
+
autoload :Config, 'troles/common/api/config'
|
6
|
+
autoload :Event, 'troles/common/api/event'
|
7
|
+
autoload :Read, 'troles/common/api/read'
|
8
|
+
autoload :Write, 'troles/common/api/write'
|
9
|
+
autoload :Validation, 'troles/common/api/validation'
|
10
|
+
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def apis
|
14
|
+
[:core, :cache, :config, :event, :read, :validation, :write]
|
15
|
+
end
|
16
|
+
|
17
|
+
def included(base)
|
18
|
+
apis.each do |api|
|
19
|
+
begin
|
20
|
+
base.include_and_extend :"#{api.to_s.camelize}"
|
21
|
+
rescue
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
extend ClassMethods
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Troles::Common
|
2
|
+
class Config
|
3
|
+
module Schema
|
4
|
+
attr_accessor :join_model
|
5
|
+
|
6
|
+
def configure_role_field
|
7
|
+
configure_generic
|
8
|
+
configure_field
|
9
|
+
configure_relation
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure_generic
|
13
|
+
clazz.send(:attr_accessor, role_field) if generic? || orm == :generic # create troles accessor
|
14
|
+
end
|
15
|
+
|
16
|
+
# Adapter should customize this as needed
|
17
|
+
def configure_field
|
18
|
+
end
|
19
|
+
|
20
|
+
# Adapter should customize this as needed
|
21
|
+
def configure_relation
|
22
|
+
end
|
23
|
+
|
24
|
+
def join_model
|
25
|
+
@join_model ||= begin
|
26
|
+
return UsersRoles if defined? UsersRoles
|
27
|
+
raise "Join model not defined"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def join_model= model_class
|
32
|
+
@join_model = model_class and return if model_class.kind_of?(Class)
|
33
|
+
raise "The role model must be a Class, was: #{model_class}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Sets the role model to use
|
37
|
+
# allows different role subject classes (fx User Accounts) to have different role schemas
|
38
|
+
# @param [Class] the model class
|
39
|
+
def role_model= model_class
|
40
|
+
@role_model = model_class.to_s and return if model_class.any_kind_of?(Class, String, Symbol)
|
41
|
+
raise "The role model must be a Class, was: #{model_class}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Gets the role model to be used
|
45
|
+
# see (#role_model=)
|
46
|
+
# @return [Class] the model class (defaults to Role)
|
47
|
+
def role_model
|
48
|
+
@role_model_found ||= begin
|
49
|
+
models = [@role_model, 'Role'].select do |class_name|
|
50
|
+
try_class(class_name.to_s)
|
51
|
+
end.compact
|
52
|
+
# puts "role models found: #{models}"
|
53
|
+
raise "No Role class defined, define Role one or set using #role_model method on config" if models.empty?
|
54
|
+
models.first.to_s.constantize
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def try_class clazz
|
61
|
+
begin
|
62
|
+
clazz = clazz.constantize if clazz.kind_of?(String)
|
63
|
+
clazz
|
64
|
+
rescue
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
include SchemaHelpers
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|