troles 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,42 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
module Troles::Common
|
3
|
+
class Operations
|
4
|
+
module Write
|
5
|
+
|
6
|
+
# Test roles equality
|
7
|
+
# @param [Array<Symbol>] roles list to test
|
8
|
+
def == *roles
|
9
|
+
role_subject.role_list == roles.flatten
|
10
|
+
end
|
11
|
+
alias_method :equal, :"=="
|
12
|
+
alias_method :same_as, :"=="
|
13
|
+
|
14
|
+
# Add a set of roles to the role subject
|
15
|
+
# @param [Array<Symbol>] roles list to add
|
16
|
+
# @return [true, false, Error] true if added, false if static or invalid, Error on some error
|
17
|
+
def + *roles
|
18
|
+
role_subject.add_roles roles
|
19
|
+
end
|
20
|
+
alias_method :<<, :+
|
21
|
+
alias_method :add, :+
|
22
|
+
alias_method :add!, :+
|
23
|
+
|
24
|
+
# Remove a set of roles from the role subject
|
25
|
+
# @param [Array<Symbol>] roles list to add
|
26
|
+
# @return [true, false, Error] true if removed, false if static or invalid, Error on some error
|
27
|
+
def - *roles
|
28
|
+
role_subject.remove_roles roles
|
29
|
+
end
|
30
|
+
alias_method :remove, :-
|
31
|
+
alias_method :remove!, :-
|
32
|
+
|
33
|
+
# Clear all the roles from the role subject
|
34
|
+
# @param [Array<Symbol>] roles list to add
|
35
|
+
# @return [true, false, Error] true if removed, false if static or invalid, Error on some error
|
36
|
+
def clear
|
37
|
+
role_subject.clear_roles!
|
38
|
+
end
|
39
|
+
alias_method :clear!, :clear
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# The Operations API object
|
4
|
+
#
|
5
|
+
# Usage example:
|
6
|
+
# - user.roles + :admin
|
7
|
+
# - user.roles.clear!
|
8
|
+
#
|
9
|
+
module Troles::Common
|
10
|
+
class Operations
|
11
|
+
autoload :Read, 'troles/common/operations/read'
|
12
|
+
autoload :Write, 'troles/common/operations/write'
|
13
|
+
|
14
|
+
include Read
|
15
|
+
include Write
|
16
|
+
|
17
|
+
include Enumerable
|
18
|
+
|
19
|
+
attr_reader :role_subject
|
20
|
+
|
21
|
+
# constructor
|
22
|
+
# @param [Object] the role subject, fx a User or UserAccount
|
23
|
+
def initialize role_subject
|
24
|
+
@role_subject = role_subject
|
25
|
+
end
|
26
|
+
|
27
|
+
# required method to act as enumerable
|
28
|
+
# iterates and yields all roles in the role list (Symbols)
|
29
|
+
def each
|
30
|
+
list.each { |role| yield role }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# The Common Storage API
|
4
|
+
# @note all methods potentially operate directly on values in the data store
|
5
|
+
#
|
6
|
+
module Troles::Common
|
7
|
+
class Storage
|
8
|
+
attr_reader :role_subject
|
9
|
+
|
10
|
+
# initializes storage with reference to role subject
|
11
|
+
# @param [Object] the role subject (fx a User or UserAccount)
|
12
|
+
def initialize role_subject
|
13
|
+
@role_subject = role_subject
|
14
|
+
end
|
15
|
+
|
16
|
+
# valid roles of the role subjects class (fx account - i.e the account rules!)
|
17
|
+
# @return [Array<Symbol>] the list of valid roles
|
18
|
+
def valid_roles
|
19
|
+
role_subject.class.valid_roles
|
20
|
+
end
|
21
|
+
|
22
|
+
# name/type of storage
|
23
|
+
# @return [Symbol]
|
24
|
+
def name
|
25
|
+
:generic
|
26
|
+
end
|
27
|
+
|
28
|
+
# sets the value of the role field (@trole or @troles) and persists the value (in the data store)
|
29
|
+
# @param [Object] the value to set on the role field of the role subject
|
30
|
+
def set_ds_field value
|
31
|
+
role_subject.send(:"#{ds_field_name}=", value)
|
32
|
+
persist_role_changes!
|
33
|
+
end
|
34
|
+
|
35
|
+
# the name of the role field
|
36
|
+
# @return [Symbol] the name
|
37
|
+
def ds_field_name
|
38
|
+
role_field
|
39
|
+
end
|
40
|
+
|
41
|
+
# the current value of the role field
|
42
|
+
# @return [Object] the value
|
43
|
+
def ds_field_value
|
44
|
+
role_subject.send(ds_field_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Attempts to persist the role field changes
|
48
|
+
# @return [true, false, error] true if saved, false if no save! method, Error on some error
|
49
|
+
def persist_role_changes!
|
50
|
+
return false if !role_subject.respond_to? :save!
|
51
|
+
role_subject.save!
|
52
|
+
role_subject.publish_change :roles
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def troles_config
|
58
|
+
role_subject.class.troles_config
|
59
|
+
end
|
60
|
+
|
61
|
+
def role_field
|
62
|
+
troles_config.role_field
|
63
|
+
end
|
64
|
+
|
65
|
+
def role_model
|
66
|
+
troles_config.role_model
|
67
|
+
end
|
68
|
+
|
69
|
+
def role_list
|
70
|
+
role_subject.role_list
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#
|
2
|
+
# @author Kristian Mandrup
|
3
|
+
#
|
4
|
+
# The Common (Generic) Roles API, functionality to be reused by both Trole and Troles
|
5
|
+
#
|
6
|
+
require 'troles/common/dependencies'
|
7
|
+
|
8
|
+
module Troles
|
9
|
+
module Common
|
10
|
+
autoload :Api, 'troles/common/api'
|
11
|
+
autoload :Config, 'troles/common/config'
|
12
|
+
autoload :Operations, 'troles/common/operations'
|
13
|
+
autoload :Marshaller, 'troles/common/marshaller'
|
14
|
+
autoload :Storage, 'troles/common/storage'
|
15
|
+
autoload :EventManager, 'troles/common/event_manager'
|
16
|
+
end
|
17
|
+
end
|
data/lib/troles/meta.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Troles
|
2
|
+
class Operations < Troles::Common::Operations
|
3
|
+
autoload :Read, 'troles/operations/read'
|
4
|
+
autoload :Write, 'troles/operations/write'
|
5
|
+
|
6
|
+
# constructor
|
7
|
+
# @param [Object] the role subject, fx a User or UserAccount
|
8
|
+
def initialize role_subject
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# Troles base storage for Many roles strategies
|
4
|
+
#
|
5
|
+
module Troles
|
6
|
+
module Storage
|
7
|
+
class BaseMany < Troles::Common::Storage
|
8
|
+
protected
|
9
|
+
|
10
|
+
# get matching list of Role instances
|
11
|
+
# @param [Array<Symbol>] list of role names to find Roles for
|
12
|
+
# @return [Array<Role>] references to Role instances
|
13
|
+
def find_roles *roles
|
14
|
+
role_model.where(:name => roles.flatten).all
|
15
|
+
end
|
16
|
+
|
17
|
+
# get list of embedded Role instances
|
18
|
+
# @param [Array<Symbol>] list of role names
|
19
|
+
# @return [Array<Role>] Role instances generated
|
20
|
+
def roles_to_embed *roles
|
21
|
+
raise "Must be implemented by embed storage to generate a set of roles to embed"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# Many role storage for storing roles as an Integer bitmask 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 BitMany < BaseMany
|
9
|
+
# constructor
|
10
|
+
# @param [Object] the role subject
|
11
|
+
def initialize role_subject
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
# display the roles as a list of symbols
|
16
|
+
# see Troles::Marshaller::Bitmask
|
17
|
+
# @return [Array<Symbol>] roles list
|
18
|
+
def display_roles
|
19
|
+
return [] if !ds_field_value?
|
20
|
+
bitmask.read
|
21
|
+
end
|
22
|
+
|
23
|
+
def ds_field_value?
|
24
|
+
ds_field_value == 0
|
25
|
+
end
|
26
|
+
|
27
|
+
# saves the roles for the role subject in the data store
|
28
|
+
# see Troles::Marshaller::Bitmask
|
29
|
+
# @param [Array<Symbol>] roles list
|
30
|
+
def set_roles *roles
|
31
|
+
roles = roles.to_symbols_uniq
|
32
|
+
return clear! if roles.empty?
|
33
|
+
set_ds_field bitmask.write(roles.to_symbols)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Clears the role state of the role subject
|
37
|
+
def clear!
|
38
|
+
set_ds_field 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sets role to default state
|
42
|
+
def set_default_role!
|
43
|
+
clear!
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def bitmask
|
49
|
+
@bitmask ||= bitmask_class.new role_subject
|
50
|
+
end
|
51
|
+
|
52
|
+
def bitmask_class
|
53
|
+
Troles::Common::Marshaller::Bitmask
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# Many role storage for storing (embedding) multiple Role instances in a list 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 EmbedMany < BaseMany
|
9
|
+
|
10
|
+
# constructor
|
11
|
+
# @param [Object] the role subject
|
12
|
+
def initialize role_subject
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def roles_to_embed *roles
|
17
|
+
roles.flatten.inject([]) do |res, role|
|
18
|
+
res << create_role(role)
|
19
|
+
res
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# display the roles as a list of symbols
|
24
|
+
# @return [Array<Symbol>] roles list
|
25
|
+
def display_roles
|
26
|
+
return [] if !ds_field_value?
|
27
|
+
ds_field_value.map{|role| role.name.to_sym }
|
28
|
+
end
|
29
|
+
|
30
|
+
# is it set?
|
31
|
+
def ds_field_value?
|
32
|
+
ds_field_value && !ds_field_value.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
# saves the roles for the role subject in the data store
|
36
|
+
# @param [Array<Symbol>] roles list
|
37
|
+
def set_roles *roles
|
38
|
+
# creates and embeds new Role instances from symbols
|
39
|
+
set_ds_field roles_to_embed(*roles)
|
40
|
+
end
|
41
|
+
|
42
|
+
# clears the role of the user in the data store
|
43
|
+
def clear!
|
44
|
+
set_ds_field []
|
45
|
+
end
|
46
|
+
|
47
|
+
# sets the role to its default state
|
48
|
+
def set_default_role!
|
49
|
+
clear!
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def create_role name
|
55
|
+
role_model.create name
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,44 @@
|
|
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 RefMany < BaseMany
|
9
|
+
def initialize role_subject
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
# display the roles as a list of symbols
|
14
|
+
# @return [Array<Symbol>] roles list
|
15
|
+
def display_roles
|
16
|
+
return [] if !ds_field_value?
|
17
|
+
ds_field_value.flatten.map do |role|
|
18
|
+
role.name.to_sym
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# is it set?
|
23
|
+
def ds_field_value?
|
24
|
+
ds_field_value && !ds_field_value.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
# saves the role for the user in the data store
|
28
|
+
def set_roles *roles
|
29
|
+
# finds and sets references to existing Role instances from symbols
|
30
|
+
found_roles = find_roles(*roles)
|
31
|
+
set_ds_field found_roles
|
32
|
+
end
|
33
|
+
|
34
|
+
# clears the role of the user in the data store
|
35
|
+
def clear!
|
36
|
+
set_ds_field []
|
37
|
+
end
|
38
|
+
|
39
|
+
# sets the role to default setting
|
40
|
+
def set_default_role!
|
41
|
+
clear!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# Many role storage for storing a comma ',' seperated String of roles 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 StringMany < BaseMany
|
9
|
+
def initialize role_subject
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
# display the roles as a list of symbols
|
14
|
+
# @return [Array<Symbol>] roles list
|
15
|
+
def display_roles
|
16
|
+
return [] if !ds_field_value?
|
17
|
+
ds_field_value.split(',').map{|r| r.strip }.map(&:to_sym)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ds_field_value?
|
21
|
+
ds_field_value && !ds_field_value.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
# saves the role for the user in the data store
|
25
|
+
# @param [Array<Symbol>] roles list
|
26
|
+
def set_roles *roles
|
27
|
+
value = roles.flatten.map(&:to_s).join(',')
|
28
|
+
set_ds_field value
|
29
|
+
end
|
30
|
+
|
31
|
+
# clears the role of the user in the data store
|
32
|
+
def clear!
|
33
|
+
set_ds_field ""
|
34
|
+
end
|
35
|
+
|
36
|
+
# sets the role to default setting
|
37
|
+
def set_default_role!
|
38
|
+
clear!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# @note all storage modules potentially operate directly on values in the data store
|
4
|
+
#
|
5
|
+
module Troles
|
6
|
+
module Storage
|
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 :StringMany, 'troles/storage/string_many'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# @author Kristian Mandrup
|
2
|
+
#
|
3
|
+
# Base module for Many roles strategies
|
4
|
+
#
|
5
|
+
module Troles
|
6
|
+
module Strategy
|
7
|
+
module BaseMany
|
8
|
+
#
|
9
|
+
# a Many role strategy is included by a role subject (fx a UserAccount class)
|
10
|
+
# a Many role strategy should always include BaseMany
|
11
|
+
# when BaseMany is included, it ensures that the complete
|
12
|
+
# Troles API is also included into the role subject
|
13
|
+
#
|
14
|
+
# @note the Trole::Api also includes the Troles::Common::Api
|
15
|
+
#
|
16
|
+
# @param [Class] the role subject class for which to include the Role strategy (fx User Account)
|
17
|
+
#
|
18
|
+
def self.included(base)
|
19
|
+
base.send :include, Troles::Api
|
20
|
+
end
|
21
|
+
|
22
|
+
# The storage to use
|
23
|
+
# @return [Troles::Storage] a storage subclass instance matching the needs of the strategy
|
24
|
+
def store
|
25
|
+
@store ||= storage.new self
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Class] the storage strategy class
|
29
|
+
def storage
|
30
|
+
raise "Must be implemented by subclass" # Troles::Storage::BaseMany
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/troles.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'troles/common'
|
2
|
+
require 'troles/macros'
|
3
|
+
|
4
|
+
module Troles
|
5
|
+
autoload :Config, 'troles/config'
|
6
|
+
autoload :Common, 'troles/common'
|
7
|
+
autoload :Api, 'troles/api'
|
8
|
+
autoload :Operations, 'troles/operations'
|
9
|
+
autoload :Strategy, 'troles/strategy'
|
10
|
+
autoload :Storage, 'troles/storage'
|
11
|
+
end
|
data/playbox/old_rake
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rake'
|
10
|
+
require 'rake/rdoctask'
|
11
|
+
|
12
|
+
require 'rspec/core'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
task :default => :spec
|
18
|
+
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'Troles'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README.rdoc')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
h1. Guide to running specs
|
2
|
+
|
3
|
+
The specs use shared examples! See the _troles/api_spec.rb_, _trole/api_spec.rb_ and more importantly the _troles/common/api_spec.rb_.
|
4
|
+
This is where most of the goodies are defined. Each api_spec pulls in spec examples from the /api folder in the respective location.
|
5
|
+
To remove one or more APIs from the spec run, simply outcomment in the relevant _api_spec.rb_.
|
6
|
+
|
7
|
+
To run specs, I recommend running for individual strategies:
|
8
|
+
|
9
|
+
Example:
|
10
|
+
|
11
|
+
@$ rspec spec/troles/strategies/bit_many_spec.rb@
|
12
|
+
|
13
|
+
If the output is too much, remove one or more APIs from the "run" as describe above!
|
14
|
+
|
15
|
+
Happy bug hunting!
|
16
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class CreateRefMany < 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, :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,20 @@
|
|
1
|
+
class CreateRefOne < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :users do |t|
|
4
|
+
t.string :name
|
5
|
+
t.integer :role_id # a user can have ONE role
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
create_table :roles do |t|
|
10
|
+
t.string :name
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :users
|
17
|
+
drop_table :roles
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|