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.
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
+