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
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "troles"
18
+ gem.homepage = "http://github.com/kristianmandrup/troles"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Complete roles solution that is easy to integrate with any Rack app, including Rails 3+}
21
+ gem.description = %Q{Ruby roles solution that has an easy to extend API, configuration and nice Adapter interface to ORMs and data stores}
22
+ gem.email = "kmandrup@gmail.com"
23
+ gem.authors = ["Kristian Mandrup"]
24
+ end
25
+ Jeweler::RubygemsDotOrgTasks.new
26
+
27
+ require 'rspec/core'
28
+ require 'rspec/core/rake_task'
29
+ RSpec::Core::RakeTask.new(:spec) do |spec|
30
+ spec.pattern = FileList['spec/**/*_spec.rb']
31
+ end
32
+
33
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
34
+ spec.pattern = 'spec/**/*_spec.rb'
35
+ spec.rcov = true
36
+ end
37
+
38
+ task :default => :spec
39
+
40
+ require 'rake/rdoctask'
41
+ Rake::RDocTask.new do |rdoc|
42
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "mongoid_geo #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.0
@@ -0,0 +1,4 @@
1
+ adapter: sqlite3
2
+ database: development.sqlite3
3
+ pool: 5
4
+ timeout: 5000
Binary file
@@ -0,0 +1,23 @@
1
+ module Trole::ActiveRecord
2
+ class Config < Troles::Common::Config
3
+
4
+ def initialize clazz, options = {}
5
+ super
6
+ end
7
+
8
+ def configure_relation
9
+ case strategy
10
+ when :ref_one
11
+ belongs_to_for clazz, role_model, :key => role_field
12
+ has_many_for role_model, clazz
13
+ when :embed_one
14
+ raise "EmbedOne is currently not supported by the Active Record adapter. It will be soon..."
15
+ #clazz.send(:embeds_many, role_model_key, :class_name => role_model_class_name)
16
+ end
17
+ end
18
+
19
+ # AR sets this up ont its own using DB Table info
20
+ def configure_field
21
+ end
22
+ end
23
+ end
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ module Trole
2
+ module ActiveRecord
3
+ autoload :Config, 'trole/adapters/active_record/config'
4
+ # autoload :Api, 'troles/adapters/active_record/api'
5
+ # autoload :Storage, 'trole/adapters/active_record/storage'
6
+ # autoload :Strategy, 'trole/adapters/active_record/strategy'
7
+ end
8
+ end
@@ -0,0 +1,34 @@
1
+ module Trole::Mongoid
2
+ class Config < Troles::Common::Config
3
+
4
+ def initialize clazz, options = {}
5
+ super
6
+ end
7
+
8
+ def configure_relation
9
+ case strategy
10
+ when :ref_one
11
+ has_one_for clazz, :role
12
+ belongs_to_for role_model, :user
13
+ when :embed_one
14
+ embeds_one clazz, :role
15
+ end
16
+ end
17
+
18
+ def configure_field
19
+ type = case strategy
20
+ when :bit_one
21
+ Boolean
22
+ when :string_one
23
+ String
24
+ end
25
+ clazz.send(:field, role_field, type) if type
26
+ end
27
+
28
+ protected
29
+
30
+ def embeds_one from, to
31
+ make_relationship :embeds_one, from, to
32
+ end
33
+ end
34
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,9 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role Cache Api
5
+ #
6
+ module Trole::Api
7
+ module Cache
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role Config Api
5
+ #
6
+ module Trole::Api
7
+ module Config
8
+ def troles_config
9
+ @troles_config ||= Trole::Config.new self
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role Core Api
5
+ #
6
+ module Trole::Api
7
+ module Core
8
+ # Access to the Trole operations API
9
+ # @return [Trole::Operations] the operations API object
10
+ def role
11
+ Trole::Operations.new(self)
12
+ end
13
+
14
+ module ClassMethods
15
+ def role_field
16
+ troles_config.role_field
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role Event Api
5
+ #
6
+ module Trole::Api
7
+ module Event
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role Read Api
5
+ #
6
+ module Trole::Api
7
+ module Read
8
+ # the role name
9
+ # @return [Symbol] the name of the role
10
+ def role_name
11
+ role_list.first
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role Validation Api
5
+ #
6
+ module Trole::Api
7
+ module Validation
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ # @author Kristian Mandrup
2
+ #
3
+ # Single role Write Api
4
+ # @note all write methods should operate on the data store via #store
5
+ #
6
+ module Trole::Api
7
+ module Write
8
+
9
+ # Set the role of the subject to a new role
10
+ # @param [Symbol] the role to set
11
+ # @return [true, false, Error] true if ok, false if not valid, Error on some error
12
+ def set_role new_role
13
+ value = make_valid_role new_role
14
+ return false if !value
15
+ store.set_role(value)
16
+ end
17
+ alias_method :role=, :set_role
18
+
19
+ # Clears the role of the user
20
+ # @return (see #set_role)
21
+ def clear_role!
22
+ store.clear!
23
+ end
24
+ end
25
+ end
data/lib/trole/api.rb ADDED
@@ -0,0 +1,41 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role Api to be included directly on the role subject class (fx User or User Account)
5
+ #
6
+ module Trole
7
+ module Api
8
+ autoload :Core, 'trole/api/core'
9
+ autoload :Config, 'trole/api/config'
10
+ autoload :Cache, 'trole/api/cache'
11
+
12
+ autoload :Event, 'trole/api/event'
13
+ autoload :Read, 'trole/api/read'
14
+ autoload :Write, 'trole/api/write'
15
+ autoload :Validation, 'trole/api/validation'
16
+
17
+ #
18
+ # When the Trole::Api is included by the Role Subject class (fx a User Account)
19
+ # first include methods from Troles Common API
20
+ # then include Trole API on top
21
+ #
22
+ # @param [Class] the role subject class (fx User or UserAccount)
23
+ #
24
+ module ClassMethods
25
+ def included(base)
26
+ base.send :include, Troles::Common::Api
27
+ self.extend Troles::Common::Api::ClassMethods # draws in the #apis method from Common Api
28
+
29
+ apis.each do |api|
30
+ begin
31
+ base.send :include, "Trole::Api::#{api.to_s.camelize}".constantize
32
+ base.extend "Trole::Api::#{api.to_s.camelize}::ClassMethods".constantize
33
+ # base.include_and_extend :"#{api.to_s.camelize}"
34
+ rescue
35
+ end
36
+ end
37
+ end
38
+ end
39
+ extend ClassMethods
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ module Trole
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,5 @@
1
+ module Trole
2
+ module Macros
3
+ end
4
+ end
5
+
@@ -0,0 +1,12 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Trole specific operations on the #role of a role subject
5
+ module Trole
6
+ class Operations
7
+ module Read
8
+ end
9
+ end
10
+ end
11
+
12
+
@@ -0,0 +1,11 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Trole specific operations on the #role of a role subject
5
+ #
6
+ module Trole
7
+ class Operations
8
+ module Write
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Trole operations object API, for performing operations on #roles
5
+ #
6
+ # Usage:
7
+ # - user.roles + :admin
8
+ # - user.roles.clear!
9
+ #
10
+ module Trole
11
+ class Operations
12
+ autoload :Read, 'trole/operations/read'
13
+ autoload :Write, 'trole/operations/write'
14
+
15
+ include Read
16
+ include Write
17
+
18
+ include Enumerable
19
+
20
+ attr_reader :role_subject
21
+
22
+ # constructor
23
+ # @param [Object] the role subject, fx a User or UserAccount
24
+ def initialize role_subject
25
+ @role_subject = role_subject
26
+ end
27
+
28
+ # required method to act as enumerable
29
+ # iterates and yields all roles in the role list (Symbols)
30
+ def each
31
+ list.each { |role| yield role }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role base storage (common, reusable functionality)
5
+ #
6
+
7
+ module Trole::Storage
8
+ class BaseOne < Troles::Common::Storage
9
+
10
+ # constructor
11
+ # @param [Symbol] the role subject
12
+ def initialize role_subject
13
+ super
14
+ end
15
+
16
+ # get Role instance by name
17
+ # @param [Symbol] list of role names to find Roles for
18
+ # @return [Role] reference to Role instances
19
+ def find_role role
20
+ raise ArgumentError, "Must be a role label" if !role.kind_of_label?
21
+ role_model.where(:name => role.to_s)
22
+ end
23
+
24
+ # get embedded Role instances
25
+ # @param [Array<Symbol>] list of role names
26
+ # @return [Array<Role>] Role instances generated
27
+ def role_to_embed
28
+ raise "Must be implemented by embed storage to generate a set of roles to embed"
29
+ end
30
+
31
+ def role_model
32
+ role_subject.class.troles_config.role_model
33
+ end
34
+
35
+ # saves the role for the user in the data store
36
+ def set_roles *roles
37
+ raise ArgumentError, "A single role strategy can only allow setting a single role, was: #{roles}" if (roles.size > 1)
38
+ set_role roles.flat_uniq.first
39
+ end
40
+
41
+ # sets the role to its default state
42
+ def set_default_role!
43
+ clear!
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ require 'troles/common/marshaller'
2
+
3
+ #
4
+ # @author Kristian Mandrup
5
+ #
6
+ # Single role storage that stores role as a boolean value (false, true)
7
+ #
8
+ module Trole::Storage
9
+ class BitOne < BaseOne
10
+
11
+ # constructor
12
+ # @param [Symbol] the role subject
13
+ def initialize role_subject
14
+ super
15
+ end
16
+
17
+ # display the role as a list of one symbol
18
+ # see Troles::Marshaller::Bitmask
19
+ # @return [Array<Symbol>] roles list
20
+ def display_roles
21
+ raise "BitOne requires exactly two valid roles, was: #{valid_roles}" if !(valid_roles.size == 2)
22
+ [bitmask.read].flatten
23
+ end
24
+
25
+ # saves the role for the role subject in the data store
26
+ # @param [Symbol] role name
27
+ def set_role role
28
+ num = bitmask.write role
29
+ set_ds_field(num == 1 ? false : true) # boolean field in Data store
30
+ end
31
+
32
+ # Clears the role state of the role subject
33
+ def clear!
34
+ set_ds_field false
35
+ end
36
+
37
+ protected
38
+
39
+ def bitmask
40
+ @bitmask ||= Troles::Common::Marshaller::Bitmask.new role_subject
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Single role storage that stores role as an embedded Role instance
5
+ #
6
+ module Trole::Storage
7
+ class EmbedOne < BaseOne
8
+
9
+ # constructor
10
+ # @param [Symbol] the role subject
11
+ def initialize api
12
+ super
13
+ end
14
+
15
+ # display the role as a list of one symbol
16
+ # @return [Array<Symbol>] roles list
17
+ def display_roles
18
+ return [] if !ds_field_value?
19
+ [ds_field_value.first.name.to_sym]
20
+ end
21
+
22
+ def ds_field_value?
23
+ ds_field_value && !ds_field_value.empty?
24
+ end
25
+
26
+ # saves the role for the user in the data store
27
+ def set_role role
28
+ set_ds_field Role.create :name => role
29
+ end
30
+
31
+ # Clears the role state of the role subject
32
+ def clear!
33
+ set_ds_field []
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Sngle role storage that stores a role as a Role instance reference
5
+ #
6
+ module Trole::Storage
7
+ class RefOne < BaseOne
8
+
9
+ # constructor
10
+ # @param [Symbol] the role subject
11
+ def initialize role_subject
12
+ super
13
+ end
14
+
15
+ # display the role as a list of one symbol
16
+ # @return [Array<Symbol>] roles list
17
+ def display_roles
18
+ return [] if !ds_field_value?
19
+ [ds_field_value.name.to_sym]
20
+ end
21
+
22
+ # is it set?
23
+ def ds_field_value?
24
+ ds_field_value
25
+ end
26
+
27
+ # saves the role of the role subject in the data store
28
+ # @param [Symbol] the role name
29
+ def set_role role
30
+ role_to_set = role_model.where(:name => role).first
31
+ set_ds_field role_to_set
32
+ end
33
+
34
+ # Clears the role state of the role subject
35
+ def clear!
36
+ set_ds_field nil
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,50 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Storage that stores role as a single String
5
+ #
6
+ module Trole::Storage
7
+ class StringOne < BaseOne
8
+
9
+ # constructor
10
+ # @param [Symbol] the role subject
11
+ def initialize role_subject
12
+ super
13
+ end
14
+
15
+ # display the role as a list of one symbol
16
+ # see Troles::Marshaller::Bitmask
17
+ # @return [Array<Symbol>] roles list
18
+ # display the role as a list of one symbol
19
+ # @return [Array<Symbol>] roles list
20
+ def display_roles
21
+ return [] if ds_field_value?
22
+ [ds_field_value.to_sym]
23
+ end
24
+
25
+ # is it set?
26
+ def ds_field_value?
27
+ ds_field_value && !!ds_field_value.empty?
28
+ end
29
+
30
+ # saves the roles for the role subject in the data store
31
+ # see Troles::Marshaller::Bitmask
32
+ # @param [Array<Symbol>] roles list
33
+ def set_roles *roles
34
+ roles = roles.flatten
35
+ raise ArgumentError, "For a single role strategy you can only set one role, was: #{roles.flatten}" if roles.empty? || (roles.size > 1)
36
+ set_role roles.first
37
+ end
38
+
39
+ # saves the role of the role subject in the data store
40
+ # @param [Symbol] the role name
41
+ def set_role role
42
+ set_ds_field role.to_s
43
+ end
44
+
45
+ # Clears the role state of the role subject
46
+ def clear!
47
+ set_ds_field ""
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,14 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Container for Single role Storages
5
+ #
6
+ module Trole
7
+ module Storage
8
+ autoload :BaseOne, 'trole/storage/base_one'
9
+ autoload :BitOne, 'trole/storage/bit_one'
10
+ autoload :EmbedOne, 'trole/storage/embed_one'
11
+ autoload :RefOne, 'trole/storage/ref_one'
12
+ autoload :StringOne, 'trole/storage/string_one'
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ #
2
+ # @author Kristian Mandrup
3
+ #
4
+ # Base module for Single role strategies
5
+ #
6
+ module Trole::Strategy
7
+ module BaseOne
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
+ # Trole 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
+ #
19
+ def self.included(base)
20
+ base.send :include, Trole::Api
21
+ end
22
+
23
+ # The storage to use
24
+ # @return [Troles::Storage] a storage subclass instance matching the needs of the strategy
25
+ def store
26
+ @store ||= storage.new self
27
+ end
28
+
29
+ # The storage strategy class
30
+ # @return [Class] a storage subclass
31
+ def storage
32
+ Trole::Storage::BaseOne
33
+ end
34
+ end
35
+ end
data/lib/trole.rb ADDED
@@ -0,0 +1,10 @@
1
+ # require 'troles'
2
+ require 'troles/common'
3
+
4
+ module Trole
5
+ autoload :Config, 'trole/config'
6
+ autoload :Api, 'trole/api'
7
+ autoload :Operations, 'trole/operations'
8
+ autoload :Strategy, 'trole/strategy'
9
+ autoload :Storage, 'trole/storage'
10
+ end
@@ -0,0 +1,4 @@
1
+ h1. Design Notes for Active Record adapter
2
+
3
+ The generic strategies and storages should expect a basic Active Model interface for the models, so no need to redefine these for Active Record.
4
+ Only the embed strategy has to be handles specifically, since Relation DBs don't naturally support the concept of embedding.