troles 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +26 -0
  3. data/Gemfile.lock +161 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.textile +686 -0
  6. data/Rakefile +48 -0
  7. data/VERSION +1 -0
  8. data/config/database.yml +4 -0
  9. data/development.sqlite3 +0 -0
  10. data/lib/trole/adapters/active_record/config.rb +23 -0
  11. data/lib/trole/adapters/active_record/storage.rb +0 -0
  12. data/lib/trole/adapters/active_record/strategy.rb +0 -0
  13. data/lib/trole/adapters/active_record.rb +8 -0
  14. data/lib/trole/adapters/mongoid/config.rb +34 -0
  15. data/lib/trole/adapters/mongoid/storage.rb +0 -0
  16. data/lib/trole/adapters/mongoid/strategy.rb +0 -0
  17. data/lib/trole/adapters/mongoid.rb +0 -0
  18. data/lib/trole/api/cache.rb +9 -0
  19. data/lib/trole/api/config.rb +12 -0
  20. data/lib/trole/api/core.rb +20 -0
  21. data/lib/trole/api/event.rb +9 -0
  22. data/lib/trole/api/read.rb +14 -0
  23. data/lib/trole/api/validation.rb +9 -0
  24. data/lib/trole/api/write.rb +25 -0
  25. data/lib/trole/api.rb +41 -0
  26. data/lib/trole/config.rb +15 -0
  27. data/lib/trole/macros.rb +5 -0
  28. data/lib/trole/operations/read.rb +12 -0
  29. data/lib/trole/operations/write.rb +11 -0
  30. data/lib/trole/operations.rb +34 -0
  31. data/lib/trole/storage/base_one.rb +46 -0
  32. data/lib/trole/storage/bit_one.rb +43 -0
  33. data/lib/trole/storage/embed_one.rb +36 -0
  34. data/lib/trole/storage/ref_one.rb +39 -0
  35. data/lib/trole/storage/string_one.rb +50 -0
  36. data/lib/trole/storage.rb +14 -0
  37. data/lib/trole/strategy.rb +35 -0
  38. data/lib/trole.rb +10 -0
  39. data/lib/troles/adapters/active_record/Design Notes.textile +4 -0
  40. data/lib/troles/adapters/active_record/config.rb +51 -0
  41. data/lib/troles/adapters/active_record/storage/embed_many.rb +8 -0
  42. data/lib/troles/adapters/active_record/storage.rb +5 -0
  43. data/lib/troles/adapters/active_record/strategy.rb +11 -0
  44. data/lib/troles/adapters/active_record.rb +8 -0
  45. data/lib/troles/adapters/mongoid/Design Notes.textile +3 -0
  46. data/lib/troles/adapters/mongoid/config.rb +45 -0
  47. data/lib/troles/adapters/mongoid.rb +8 -0
  48. data/lib/troles/api/cache.rb +4 -0
  49. data/lib/troles/api/config.rb +9 -0
  50. data/lib/troles/api/core.rb +9 -0
  51. data/lib/troles/api/event.rb +4 -0
  52. data/lib/troles/api/read.rb +4 -0
  53. data/lib/troles/api/validation.rb +4 -0
  54. data/lib/troles/api/write.rb +4 -0
  55. data/lib/troles/api.rb +40 -0
  56. data/lib/troles/common/api/cache.rb +12 -0
  57. data/lib/troles/common/api/config.rb +4 -0
  58. data/lib/troles/common/api/core.rb +52 -0
  59. data/lib/troles/common/api/event.rb +39 -0
  60. data/lib/troles/common/api/read.rb +44 -0
  61. data/lib/troles/common/api/validation.rb +44 -0
  62. data/lib/troles/common/api/write.rb +76 -0
  63. data/lib/troles/common/api.rb +28 -0
  64. data/lib/troles/common/config/schema.rb +72 -0
  65. data/lib/troles/common/config/schema_helpers.rb +95 -0
  66. data/lib/troles/common/config/static_roles.rb +14 -0
  67. data/lib/troles/common/config/valid_roles.rb +21 -0
  68. data/lib/troles/common/config.rb +96 -0
  69. data/lib/troles/common/dependencies.rb +9 -0
  70. data/lib/troles/common/event_manager.rb +40 -0
  71. data/lib/troles/common/macros/configuration/base_loader.rb +40 -0
  72. data/lib/troles/common/macros/configuration/config_loader.rb +19 -0
  73. data/lib/troles/common/macros/configuration/storage_loader.rb +20 -0
  74. data/lib/troles/common/macros/configuration/strategy_loader.rb +38 -0
  75. data/lib/troles/common/macros/configuration.rb +89 -0
  76. data/lib/troles/common/macros/static_roles.rb +9 -0
  77. data/lib/troles/common/macros/strategy_options.rb +21 -0
  78. data/lib/troles/common/macros.rb +38 -0
  79. data/lib/troles/common/marshaller/bitmask.rb +43 -0
  80. data/lib/troles/common/marshaller/generic.rb +24 -0
  81. data/lib/troles/common/marshaller.rb +14 -0
  82. data/lib/troles/common/operations/read.rb +28 -0
  83. data/lib/troles/common/operations/write.rb +42 -0
  84. data/lib/troles/common/operations.rb +33 -0
  85. data/lib/troles/common/storage.rb +73 -0
  86. data/lib/troles/common.rb +17 -0
  87. data/lib/troles/config.rb +15 -0
  88. data/lib/troles/macros.rb +7 -0
  89. data/lib/troles/meta.rb +5 -0
  90. data/lib/troles/operations/read.rb +6 -0
  91. data/lib/troles/operations/write.rb +6 -0
  92. data/lib/troles/operations.rb +12 -0
  93. data/lib/troles/storage/base_many.rb +25 -0
  94. data/lib/troles/storage/bit_many.rb +56 -0
  95. data/lib/troles/storage/embed_many.rb +58 -0
  96. data/lib/troles/storage/ref_many.rb +44 -0
  97. data/lib/troles/storage/string_many.rb +41 -0
  98. data/lib/troles/storage.rb +13 -0
  99. data/lib/troles/strategy.rb +34 -0
  100. data/lib/troles.rb +11 -0
  101. data/playbox/old_rake +25 -0
  102. data/spec/Guide to running specs.textile +16 -0
  103. data/spec/active_record/migrations/many/bit_many.rb +16 -0
  104. data/spec/active_record/migrations/many/ref_many.rb +31 -0
  105. data/spec/active_record/migrations/many/string_many.rb +16 -0
  106. data/spec/active_record/migrations/one/bit_one.rb +14 -0
  107. data/spec/active_record/migrations/one/ref_one.rb +20 -0
  108. data/spec/active_record/migrations/one/string_one.rb +14 -0
  109. data/spec/active_record/models/ref_many.rb +10 -0
  110. data/spec/active_record/models/ref_one.rb +10 -0
  111. data/spec/active_record/models/role.rb +2 -0
  112. data/spec/active_record/models/user.rb +5 -0
  113. data/spec/active_record/models.rb +2 -0
  114. data/spec/active_record/strategies/many/bit_many_spec.rb +41 -0
  115. data/spec/active_record/strategies/many/ref_many_spec.rb +45 -0
  116. data/spec/active_record/strategies/many/string_many_spec.rb +39 -0
  117. data/spec/active_record/strategies/one/bit_one_spec.rb +35 -0
  118. data/spec/active_record/strategies/one/ref_one_spec.rb +41 -0
  119. data/spec/active_record/strategies/one/string_one_spec.rb +35 -0
  120. data/spec/active_record/strategy_helper.rb +4 -0
  121. data/spec/active_record_helper.rb +50 -0
  122. data/spec/db/database.yml +4 -0
  123. data/spec/dummy/Gemfile.lock +108 -0
  124. data/spec/dummy/Rakefile +7 -0
  125. data/spec/dummy/app/assets/images/rails.png +0 -0
  126. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  127. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  128. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  129. data/spec/dummy/app/controllers/main_controller.rb +16 -0
  130. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  131. data/spec/dummy/app/mailers/.gitkeep +0 -0
  132. data/spec/dummy/app/models/.gitkeep +0 -0
  133. data/spec/dummy/app/models/ref_many_user.rb +7 -0
  134. data/spec/dummy/app/models/ref_one_user.rb +3 -0
  135. data/spec/dummy/app/models/role.rb +4 -0
  136. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  137. data/spec/dummy/app/views/main/index.html.erb +3 -0
  138. data/spec/dummy/config/application.rb +54 -0
  139. data/spec/dummy/config/boot.rb +10 -0
  140. data/spec/dummy/config/database.yml +25 -0
  141. data/spec/dummy/config/environment.rb +5 -0
  142. data/spec/dummy/config/environments/development.rb +24 -0
  143. data/spec/dummy/config/environments/production.rb +52 -0
  144. data/spec/dummy/config/environments/test.rb +39 -0
  145. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  146. data/spec/dummy/config/initializers/inflections.rb +10 -0
  147. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  148. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  149. data/spec/dummy/config/initializers/session_store.rb +8 -0
  150. data/spec/dummy/config/initializers/troles.rb +3 -0
  151. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  152. data/spec/dummy/config/locales/en.yml +5 -0
  153. data/spec/dummy/config/routes.rb +60 -0
  154. data/spec/dummy/config.ru +4 -0
  155. data/spec/dummy/db/migrate/01_create_roles.rb +14 -0
  156. data/spec/dummy/db/migrate/02_create_ref_many_users.rb +20 -0
  157. data/spec/dummy/db/schema.rb +32 -0
  158. data/spec/dummy/db/seeds.rb +4 -0
  159. data/spec/dummy/log/.gitkeep +0 -0
  160. data/spec/dummy/public/404.html +26 -0
  161. data/spec/dummy/public/422.html +26 -0
  162. data/spec/dummy/public/500.html +26 -0
  163. data/spec/dummy/public/favicon.ico +0 -0
  164. data/spec/dummy/script/rails +6 -0
  165. data/spec/dummy_spec_helper.rb +33 -0
  166. data/spec/factories.rb +8 -0
  167. data/spec/generic/models/accounts/admin_account.rb +7 -0
  168. data/spec/generic/models/accounts/blogger_account.rb +7 -0
  169. data/spec/generic/models/accounts/user_account.rb +7 -0
  170. data/spec/generic/models/accounts.rb +1 -0
  171. data/spec/generic/models/base_user.rb +27 -0
  172. data/spec/generic/models/role.rb +37 -0
  173. data/spec/generic/models/user.rb +7 -0
  174. data/spec/generic/models.rb +3 -0
  175. data/spec/integration/navigation_spec.rb +9 -0
  176. data/spec/integration/troles/Running dummy tests.textile +35 -0
  177. data/spec/integration/troles/navigation_spec.rb +49 -0
  178. data/spec/mongoid/models/ref_many.rb +15 -0
  179. data/spec/mongoid/models/ref_one.rb +15 -0
  180. data/spec/mongoid/models/role.rb +5 -0
  181. data/spec/mongoid/models/user.rb +9 -0
  182. data/spec/mongoid/models.rb +2 -0
  183. data/spec/mongoid/strategies/many/bit_many_spec.rb +35 -0
  184. data/spec/mongoid/strategies/many/ref_many_spec.rb +35 -0
  185. data/spec/mongoid/strategies/many/string_many_spec.rb +30 -0
  186. data/spec/mongoid/strategies/one/bit_one_spec.rb +26 -0
  187. data/spec/mongoid/strategies/one/ref_one_spec.rb +31 -0
  188. data/spec/mongoid/strategies/one/string_one_spec.rb +26 -0
  189. data/spec/mongoid/strategy_helper.rb +4 -0
  190. data/spec/mongoid_helper.rb +19 -0
  191. data/spec/playbox/rspec_examples.rb +381 -0
  192. data/spec/support/shared_examples.rb +1 -0
  193. data/spec/trole/Trole Design.textile +4 -0
  194. data/spec/trole/api/cache_api_spec.rb +2 -0
  195. data/spec/trole/api/core_api_spec.rb +4 -0
  196. data/spec/trole/api/event_api.rb +2 -0
  197. data/spec/trole/api/operations_api_spec.rb +2 -0
  198. data/spec/trole/api/read_api_spec.rb +5 -0
  199. data/spec/trole/api/validation_api_spec.rb +2 -0
  200. data/spec/trole/api/write_api_spec.rb +2 -0
  201. data/spec/trole/api_spec.rb +60 -0
  202. data/spec/trole/multi_roles_spec.rb +163 -0
  203. data/spec/trole/operations/read_spec.rb +18 -0
  204. data/spec/trole/operations/write_spec.rb +0 -0
  205. data/spec/trole/playbox/shared_examples.rb +107 -0
  206. data/spec/trole/strategies/bit_one_spec.rb +22 -0
  207. data/spec/trole/strategies/embed_one_spec.rb +32 -0
  208. data/spec/trole/strategies/ref_one_spec.rb +29 -0
  209. data/spec/trole/strategies/string_one_spec.rb +26 -0
  210. data/spec/trole/strategy_helper.rb +3 -0
  211. data/spec/trole/two_roles_spec.rb +76 -0
  212. data/spec/trole_spec.rb +12 -0
  213. data/spec/trole_spec_helper.rb +20 -0
  214. data/spec/troles/api/cache_api_spec.rb +2 -0
  215. data/spec/troles/api/core_api_spec.rb +4 -0
  216. data/spec/troles/api/event_api.rb +2 -0
  217. data/spec/troles/api/read_api_spec.rb +2 -0
  218. data/spec/troles/api/validation_api_spec.rb +2 -0
  219. data/spec/troles/api/write_api_spec.rb +2 -0
  220. data/spec/troles/api_spec.rb +41 -0
  221. data/spec/troles/common/api/cache_api_spec.rb +31 -0
  222. data/spec/troles/common/api/config_api.rb +0 -0
  223. data/spec/troles/common/api/core_api_spec.rb +14 -0
  224. data/spec/troles/common/api/event_api_spec.rb +9 -0
  225. data/spec/troles/common/api/operations_api_spec.rb +55 -0
  226. data/spec/troles/common/api/read_api_spec.rb +23 -0
  227. data/spec/troles/common/api/validation_api_spec.rb +46 -0
  228. data/spec/troles/common/api/write_api_spec.rb +81 -0
  229. data/spec/troles/common/api_spec.rb +101 -0
  230. data/spec/troles/common/config_spec.rb +11 -0
  231. data/spec/troles/common/multi_roles_spec.rb +142 -0
  232. data/spec/troles/marshaller/bitmask_spec.rb +14 -0
  233. data/spec/troles/operations/read_ops_spec.rb +0 -0
  234. data/spec/troles/operations/write_ops_spec.rb +0 -0
  235. data/spec/troles/playbox/shared_examples.rb +68 -0
  236. data/spec/troles/strategies/bit_many_spec.rb +30 -0
  237. data/spec/troles/strategies/embed_many_spec.rb +35 -0
  238. data/spec/troles/strategies/ref_many_spec.rb +36 -0
  239. data/spec/troles/strategies/string_many_spec.rb +32 -0
  240. data/spec/troles/strategy_helper.rb +3 -0
  241. data/spec/troles_spec.rb +10 -0
  242. data/troles.gemspec +325 -0
  243. 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
@@ -0,0 +1,15 @@
1
+ module Troles
2
+ class Config < Troles::Common::Config
3
+ def initialize clazz, options = {}
4
+ super
5
+ end
6
+
7
+ def configure_role_field
8
+ super
9
+ end
10
+
11
+ def generic?
12
+ super
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ require 'troles/common/macros'
2
+
3
+ module Troles
4
+ module Macros
5
+ end
6
+ end
7
+
@@ -0,0 +1,5 @@
1
+ class Object # http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
2
+ def meta_def name, &blk
3
+ (class << self; self; end).instance_eval { define_method name, &blk }
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module Troles
2
+ class Operations
3
+ module Read
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Troles
2
+ class Operations
3
+ module Write
4
+ end
5
+ end
6
+ end
@@ -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,16 @@
1
+ class CreateBitMany < ActiveRecord::Migration
2
+ def self.up
3
+ # down
4
+
5
+ create_table :users do |t|
6
+ t.string :name
7
+ t.integer :troles
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :users
14
+ end
15
+ end
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,16 @@
1
+ class CreateStringMany < ActiveRecord::Migration
2
+ def self.up
3
+ # down
4
+
5
+ create_table :users do |t|
6
+ t.string :name
7
+ t.string :troles
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :users
14
+ end
15
+ end
16
+
@@ -0,0 +1,14 @@
1
+ class CreateBitOne < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :name
5
+ t.boolean :trole
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :users
12
+ end
13
+ end
14
+
@@ -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
+
@@ -0,0 +1,14 @@
1
+ class CreateStringOne < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :name
5
+ t.string :trole
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :users
12
+ end
13
+ end
14
+