roles_generic 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/LICENSE +20 -0
- data/README.markdown +308 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/lib/generators/roles_model/roles/roles_generator.rb +65 -0
- data/lib/roles_generic/admin_flag.rb +40 -0
- data/lib/roles_generic/base.rb +45 -0
- data/lib/roles_generic/extensions/core_ext.rb +19 -0
- data/lib/roles_generic/generic/class_methods.rb +33 -0
- data/lib/roles_generic/generic/implementation.rb +26 -0
- data/lib/roles_generic/generic/util.rb +39 -0
- data/lib/roles_generic/generic.rb +77 -0
- data/lib/roles_generic/many_roles.rb +39 -0
- data/lib/roles_generic/one_role.rb +40 -0
- data/lib/roles_generic/role/class_methods.rb +20 -0
- data/lib/roles_generic/role_string.rb +29 -0
- data/lib/roles_generic/role_strings.rb +23 -0
- data/lib/roles_generic/roles_mask.rb +48 -0
- data/lib/roles_generic/roles_string.rb +26 -0
- data/lib/roles_generic.rb +2 -0
- data/spec/generator_spec_helper.rb +12 -0
- data/spec/generators/admin_flag_generator_spec.rb +77 -0
- data/spec/generators/many_roles_generator_spec.rb +39 -0
- data/spec/generators/one_role_generator_spec.rb +39 -0
- data/spec/generators/role_string_generator_spec.rb +39 -0
- data/spec/generators/role_strings_generator_spec.rb +39 -0
- data/spec/generators/roles_mask_generator_spec.rb +39 -0
- data/spec/generators/roles_string_generator_spec.rb +39 -0
- data/spec/model/role.rb +26 -0
- data/spec/roles_generic/admin_flag_spec.rb +66 -0
- data/spec/roles_generic/many_roles_spec.rb +63 -0
- data/spec/roles_generic/one_role_spec.rb +70 -0
- data/spec/roles_generic/role_string_spec.rb +65 -0
- data/spec/roles_generic/role_strings_spec.rb +58 -0
- data/spec/roles_generic/roles_mask_spec.rb +57 -0
- data/spec/roles_generic/roles_string_spec.rb +58 -0
- data/spec/spec_helper.rb +9 -0
- metadata +182 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Kristian Mandrup
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,308 @@
|
|
1
|
+
# Roles Model base
|
2
|
+
|
3
|
+
Generic role strategies that share the same API and are easy to insert in any existing User model.
|
4
|
+
|
5
|
+
*Update: Now with a Rails 3 generator to instantly populate your user model of choice with a role strategy!*
|
6
|
+
|
7
|
+
# Install
|
8
|
+
|
9
|
+
<code>gem install roles_generic</code>
|
10
|
+
|
11
|
+
# Usage
|
12
|
+
|
13
|
+
The library comes with the following role models built-in:
|
14
|
+
|
15
|
+
* admin_flag (Boolean flag - 'admin' or not)
|
16
|
+
* role_string (String)
|
17
|
+
* roles_string (Comma separated String - note: no role name must have a comma in its name!)
|
18
|
+
* role_strings (Set of Strings)
|
19
|
+
* roles_mask (Integer mask)
|
20
|
+
* one_role (relation to a Role model instance)
|
21
|
+
* many_roles(Set of Role relationships)
|
22
|
+
|
23
|
+
Note: The following examples use RSpec to demonstrate usage scenarios.
|
24
|
+
|
25
|
+
## Example : admin_flag
|
26
|
+
|
27
|
+
Creates and uses a binary field 'admin_flag', which when true signals that this user is an administrator and otherwise a normal user.
|
28
|
+
|
29
|
+
<pre>
|
30
|
+
class User
|
31
|
+
include RoleModels::Generic
|
32
|
+
|
33
|
+
attr_accessor :name, :admin_flag
|
34
|
+
|
35
|
+
role_strategy :admin_flag, :default
|
36
|
+
|
37
|
+
roles :admin, :user
|
38
|
+
|
39
|
+
def initialize name, *new_roles
|
40
|
+
self.name = name
|
41
|
+
self.roles = new_roles
|
42
|
+
end
|
43
|
+
end
|
44
|
+
</pre>
|
45
|
+
|
46
|
+
## Example: Using an ORM
|
47
|
+
|
48
|
+
Data Mapper with persistent attributes :name and :admin_flag
|
49
|
+
|
50
|
+
<pre>
|
51
|
+
class User
|
52
|
+
include RoleModels::Generic
|
53
|
+
include DataMapper::Resource
|
54
|
+
|
55
|
+
property :name, Boolean
|
56
|
+
property :admin_flag, Boolean
|
57
|
+
|
58
|
+
role_strategy :admin_flag, :default
|
59
|
+
|
60
|
+
roles :admin, :user
|
61
|
+
|
62
|
+
def initialize name, *new_roles
|
63
|
+
self.name = name
|
64
|
+
self.roles = new_roles
|
65
|
+
end
|
66
|
+
end
|
67
|
+
</pre>
|
68
|
+
|
69
|
+
|
70
|
+
## Example : role_string
|
71
|
+
|
72
|
+
Creates and uses a single role name, a string
|
73
|
+
|
74
|
+
<pre>
|
75
|
+
class User
|
76
|
+
include RoleModels::Generic
|
77
|
+
|
78
|
+
attr_accessor :name, :role_string
|
79
|
+
|
80
|
+
role_strategy :role_string, :default
|
81
|
+
|
82
|
+
roles :admin, :user
|
83
|
+
|
84
|
+
def initialize name, *new_roles
|
85
|
+
self.name = name
|
86
|
+
self.roles = new_roles
|
87
|
+
end
|
88
|
+
end
|
89
|
+
</pre>
|
90
|
+
|
91
|
+
## Example : roles_string
|
92
|
+
|
93
|
+
Creates and uses single comma separated String of role names
|
94
|
+
|
95
|
+
<pre>
|
96
|
+
class User
|
97
|
+
include RoleModels::Generic
|
98
|
+
|
99
|
+
attr_accessor :name, :roles_string
|
100
|
+
|
101
|
+
role_strategy :roles_string, :default
|
102
|
+
|
103
|
+
roles :admin, :user
|
104
|
+
|
105
|
+
def initialize name, *new_roles
|
106
|
+
self.name = name
|
107
|
+
self.roles = new_roles
|
108
|
+
end
|
109
|
+
end
|
110
|
+
</pre>
|
111
|
+
|
112
|
+
## Example : role_strings
|
113
|
+
|
114
|
+
Creates and uses an Set of role names as strings
|
115
|
+
|
116
|
+
<pre>
|
117
|
+
class User
|
118
|
+
include RoleModels::Generic
|
119
|
+
|
120
|
+
attr_accessor :name, :role_strings
|
121
|
+
|
122
|
+
role_strategy :role_strings, :default
|
123
|
+
|
124
|
+
roles :admin, :user
|
125
|
+
|
126
|
+
def initialize name, *new_roles
|
127
|
+
self.name = name
|
128
|
+
self.roles = new_roles
|
129
|
+
end
|
130
|
+
end
|
131
|
+
</pre>
|
132
|
+
|
133
|
+
## Example : roles_mask
|
134
|
+
|
135
|
+
Creates and uses an Integer field where each on bit signifies a role
|
136
|
+
|
137
|
+
<pre>
|
138
|
+
class User
|
139
|
+
include RoleModels::Generic
|
140
|
+
|
141
|
+
attr_accessor :name, :roles_mask
|
142
|
+
|
143
|
+
role_strategy :roles_mask, :default
|
144
|
+
|
145
|
+
roles :admin, :user
|
146
|
+
|
147
|
+
def initialize name, *new_roles
|
148
|
+
self.name = name
|
149
|
+
self.roles = new_roles
|
150
|
+
end
|
151
|
+
end
|
152
|
+
</pre>
|
153
|
+
|
154
|
+
## Example : one_role
|
155
|
+
|
156
|
+
Creates and uses a single relation to a Role model for each user
|
157
|
+
|
158
|
+
<pre>
|
159
|
+
class Role
|
160
|
+
attr_accessor :name
|
161
|
+
|
162
|
+
def self.find_role role_name
|
163
|
+
roles.to_a.select{|r| r.name == role_name}.first
|
164
|
+
end
|
165
|
+
|
166
|
+
class << self
|
167
|
+
attr_accessor :roles
|
168
|
+
end
|
169
|
+
|
170
|
+
def initialize name
|
171
|
+
@name = name
|
172
|
+
self.class.roles ||= Set.new
|
173
|
+
self.class.roles << self
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
class User
|
179
|
+
include RoleModels::Generic
|
180
|
+
role_strategy :one_role, :default
|
181
|
+
|
182
|
+
role_class :role
|
183
|
+
|
184
|
+
attr_accessor :name, :one_role
|
185
|
+
|
186
|
+
roles :admin, :user
|
187
|
+
|
188
|
+
def initialize name, *new_roles
|
189
|
+
self.name = name
|
190
|
+
self.roles = new_roles
|
191
|
+
end
|
192
|
+
end
|
193
|
+
</pre>
|
194
|
+
|
195
|
+
## Example : many_roles
|
196
|
+
|
197
|
+
Creates and uses a single relation to a Role model for each user
|
198
|
+
|
199
|
+
<pre>
|
200
|
+
class Role
|
201
|
+
attr_accessor :name
|
202
|
+
|
203
|
+
def self.find_role role_name
|
204
|
+
roles.to_a.select{|r| r.name == role_name}.first
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.find_roles *role_names
|
208
|
+
result = Set.new
|
209
|
+
role_names.flatten.each do |role_name|
|
210
|
+
found_role = find_role(role_name)
|
211
|
+
result << found_role if found_role
|
212
|
+
end
|
213
|
+
result
|
214
|
+
end
|
215
|
+
|
216
|
+
class << self
|
217
|
+
attr_accessor :roles
|
218
|
+
end
|
219
|
+
|
220
|
+
def initialize name
|
221
|
+
@name = name
|
222
|
+
self.class.roles ||= Set.new
|
223
|
+
self.class.roles << self
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
class User
|
228
|
+
include RoleModels::Generic
|
229
|
+
role_strategy :many_roles, :default
|
230
|
+
|
231
|
+
role_class :role
|
232
|
+
|
233
|
+
attr_accessor :name, :many_roles
|
234
|
+
|
235
|
+
roles :admin, :user
|
236
|
+
|
237
|
+
def initialize name, *new_roles
|
238
|
+
self.name = name
|
239
|
+
self.roles = new_roles
|
240
|
+
end
|
241
|
+
end
|
242
|
+
</pre>
|
243
|
+
|
244
|
+
## Usage of API
|
245
|
+
|
246
|
+
<pre>
|
247
|
+
before :each do
|
248
|
+
@admin_user = User.new 'Admin user', :admin
|
249
|
+
@user = User.new 'User', :user
|
250
|
+
end
|
251
|
+
|
252
|
+
it "user 'Admin user' should have role :admin" do
|
253
|
+
@admin_user.role.should == :admin
|
254
|
+
@admin_user.roles.should == [:admin]
|
255
|
+
@admin_user.admin?.should be_true
|
256
|
+
|
257
|
+
@admin_user.has_role?(:user).should be_false
|
258
|
+
|
259
|
+
@admin_user.has_role?(:admin).should be_true
|
260
|
+
@admin_user.is?(:admin).should be_true
|
261
|
+
@admin_user.has_roles?(:admin).should be_true
|
262
|
+
@admin_user.has?(:admin).should be_true
|
263
|
+
end
|
264
|
+
|
265
|
+
it "user 'User' should have role :user" do
|
266
|
+
@user.roles.should == [:user]
|
267
|
+
@user.admin?.should be_false
|
268
|
+
|
269
|
+
@user.has_role?(:user).should be_true
|
270
|
+
@user.has_role?(:admin).should be_false
|
271
|
+
@user.is?(:admin).should be_false
|
272
|
+
|
273
|
+
@user.has_roles?(:user).should be_true
|
274
|
+
@user.has?(:admin).should be_false
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should set 'User' role to :admin using roles=" do
|
278
|
+
@user.roles = :admin
|
279
|
+
@user.role.should == :admin
|
280
|
+
@user.has_role?(:admin).should be_true
|
281
|
+
end
|
282
|
+
</pre>
|
283
|
+
|
284
|
+
## Future (TODO)
|
285
|
+
|
286
|
+
The following in planned to be completed before the end of August 2010.
|
287
|
+
|
288
|
+
### Clean up (DRY)
|
289
|
+
|
290
|
+
DRY up the role strategy code a lot more! There is a lot more potential for code reuse - way too much duplication now.
|
291
|
+
|
292
|
+
### Rails generator
|
293
|
+
|
294
|
+
The library will come with a Rails 3 generator that lets you populate a user model with a given role strategy
|
295
|
+
|
296
|
+
## Note on Patches/Pull Requests
|
297
|
+
|
298
|
+
* Fork the project.
|
299
|
+
* Make your feature addition or bug fix.
|
300
|
+
* Add tests for it. This is important so I don't break it in a
|
301
|
+
future version unintentionally.
|
302
|
+
* Commit, do not mess with rakefile, version, or history.
|
303
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
304
|
+
* Send me a pull request. Bonus points for topic branches.
|
305
|
+
|
306
|
+
## Copyright
|
307
|
+
|
308
|
+
Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
gem.name = "roles_generic"
|
5
|
+
gem.summary = %Q{Generic role strategies sharing the same API}
|
6
|
+
gem.description = %Q{Generic role strategies sharing the same API. Easy to insert in any model}
|
7
|
+
gem.email = "kmandrup@gmail.com"
|
8
|
+
gem.homepage = "http://github.com/kristianmandrup/roles_for_mm"
|
9
|
+
gem.authors = ["Kristian Mandrup"]
|
10
|
+
gem.add_development_dependency "rspec", ">= 2.0.0.beta.19"
|
11
|
+
gem.add_development_dependency "generator-spec", ">= 0.5.1"
|
12
|
+
gem.add_dependency "require_all", ">= 1.1.0"
|
13
|
+
gem.add_dependency "activesupport", ">= 3.0.0.rc"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
# require 'spec/rake/spectask'
|
22
|
+
# Spec::Rake::SpecTask.new(:spec) do |spec|
|
23
|
+
# spec.libs << 'lib' << 'spec'
|
24
|
+
# spec.spec_files = FileList['spec/**/*_spec.rb']
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# Spec::Rake::SpecTask.new(:rcov) do |spec|
|
28
|
+
# spec.libs << 'lib' << 'spec'
|
29
|
+
# spec.pattern = 'spec/**/*_spec.rb'
|
30
|
+
# spec.rcov = true
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# task :spec => :check_dependencies
|
34
|
+
#
|
35
|
+
# task :default => :spec
|
36
|
+
#
|
37
|
+
# require 'rake/rdoctask'
|
38
|
+
# Rake::RDocTask.new do |rdoc|
|
39
|
+
# version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
#
|
41
|
+
# rdoc.rdoc_dir = 'rdoc'
|
42
|
+
# rdoc.title = "roles_for_mm #{version}"
|
43
|
+
# rdoc.rdoc_files.include('README*')
|
44
|
+
# rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
# end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module RolesModel
|
2
|
+
module Generators
|
3
|
+
class RolesGenerator < Rails::Generators::NamedBase
|
4
|
+
include Rails::Generators::MigrationHelper
|
5
|
+
|
6
|
+
desc "Add role strategy to a model"
|
7
|
+
|
8
|
+
class_option :strategy, :type => :string, :aliases => "-s", :default => 'role_string',
|
9
|
+
:desc => "Role strategy to use (admin_flag, role_string, roles_string, role_strings, one_role, many_roles, roles_mask)"
|
10
|
+
|
11
|
+
|
12
|
+
class_option :roles, :type => :array, :aliases => "-r", :default => [], :desc => "Valid roles"
|
13
|
+
# TODO: Should detect ORM from file content instead!
|
14
|
+
class_option :orm, :type => :string, :aliases => "-o", :default => nil, :desc => "ORM of model"
|
15
|
+
|
16
|
+
|
17
|
+
# hook_for :orm
|
18
|
+
|
19
|
+
def self.source_root
|
20
|
+
@source_root ||= File.expand_path("../../templates", __FILE__)
|
21
|
+
end
|
22
|
+
|
23
|
+
def apply_role_strategy
|
24
|
+
self.class.use_orm orm if orm
|
25
|
+
insert_into_model name do
|
26
|
+
insertion_text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def strategy
|
33
|
+
options[:strategy]
|
34
|
+
end
|
35
|
+
|
36
|
+
def orm
|
37
|
+
@orm ||= options[:orm].to_s.to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
def roles
|
41
|
+
@roles ||= options[:roles].map{|r| ":#{r}" }
|
42
|
+
end
|
43
|
+
|
44
|
+
def role_strategy_statement
|
45
|
+
"role_strategy :#{strategy}\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
def roles_statement
|
49
|
+
roles ? "roles #{roles.join(',')}" : ''
|
50
|
+
end
|
51
|
+
|
52
|
+
def insertion_text
|
53
|
+
%Q{
|
54
|
+
include RoleModels::Generic
|
55
|
+
#{role_strategy_statement}
|
56
|
+
#{roles_statement}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def role_strategy
|
61
|
+
options[:role_strategy]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RoleModels::Generic
|
2
|
+
module AdminFlag
|
3
|
+
def self.default_role_attribute
|
4
|
+
:admin_flag
|
5
|
+
end
|
6
|
+
|
7
|
+
module Implementation
|
8
|
+
# assign roles
|
9
|
+
def roles=(*new_roles)
|
10
|
+
first_role = new_roles.flatten.first
|
11
|
+
self.send("#{strategy_class.roles_attribute_name}=", new_roles.flatten.first.admin?) if valid_role? first_role
|
12
|
+
end
|
13
|
+
|
14
|
+
# query assigned roles
|
15
|
+
def roles
|
16
|
+
role = self.send(strategy_class.roles_attribute_name) ? strategy_class.admin_role_key : strategy_class.default_role_key
|
17
|
+
[role]
|
18
|
+
end
|
19
|
+
alias_method :roles_list, :roles
|
20
|
+
|
21
|
+
end # Implementation
|
22
|
+
|
23
|
+
extend RoleModels::Generic::Base::Configuration
|
24
|
+
configure :num => :single
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module AdminRoleCheck
|
29
|
+
def admin?
|
30
|
+
self.to_s.downcase.to_sym == :admin
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class String
|
35
|
+
include AdminRoleCheck
|
36
|
+
end
|
37
|
+
|
38
|
+
class Symbol
|
39
|
+
include AdminRoleCheck
|
40
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'require_all'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
module RoleModels
|
5
|
+
module Generic
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module RoleModels
|
10
|
+
module Base
|
11
|
+
attr_accessor :orm_name
|
12
|
+
|
13
|
+
def roles(*roles)
|
14
|
+
strategy_class.valid_roles = Array[*roles].flatten.map { |r| r.to_sym }
|
15
|
+
end
|
16
|
+
|
17
|
+
def role_strategy strategy, options=nil
|
18
|
+
include_strategy orm_name, strategy, options
|
19
|
+
end
|
20
|
+
|
21
|
+
def include_strategy orm, strategy, options=nil
|
22
|
+
begin
|
23
|
+
constant = "RoleModels::#{orm_name.to_s.camelize}::#{strategy.to_s.camelize}".constantize
|
24
|
+
|
25
|
+
strategy_class_method = %Q{
|
26
|
+
def strategy_class
|
27
|
+
#{constant}
|
28
|
+
end
|
29
|
+
}
|
30
|
+
|
31
|
+
class_eval do
|
32
|
+
eval strategy_class_method
|
33
|
+
end
|
34
|
+
|
35
|
+
instance_eval do
|
36
|
+
eval strategy_class_method
|
37
|
+
include constant
|
38
|
+
end
|
39
|
+
rescue
|
40
|
+
raise "No Role strategy module for ORM #{orm} found for strategy #{strategy}"
|
41
|
+
end
|
42
|
+
constant.apply_options(options) if constant.respond_to? :apply_options
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# to be replaced by Zucker gem
|
2
|
+
|
3
|
+
class Object
|
4
|
+
define_method :not do
|
5
|
+
Not.new(self)
|
6
|
+
end
|
7
|
+
|
8
|
+
class Not
|
9
|
+
private *instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ }
|
10
|
+
|
11
|
+
def initialize(subject)
|
12
|
+
@subject = subject
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(sym, *args, &blk)
|
16
|
+
!@subject.send(sym,*args,&blk)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RoleModels::Generic::Base
|
2
|
+
module ClassMethods
|
3
|
+
def inherited(subclass) # :nodoc:
|
4
|
+
::RoleModels::Base::INHERITABLE_CLASS_ATTRIBUTES.each do |attribute|
|
5
|
+
instance_var = "@#{attribute}"
|
6
|
+
subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
|
7
|
+
end
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
# set the bitmask attribute role assignments will be stored in
|
12
|
+
def roles_attribute(name)
|
13
|
+
self.roles_attribute = name
|
14
|
+
end
|
15
|
+
|
16
|
+
# alternative method signature: set the bitmask attribute role assignments will be stored in
|
17
|
+
def roles_attribute=(name)
|
18
|
+
self.roles_attribute_name = name.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
# :call-seq:
|
22
|
+
# roles(:role_1, ..., :role_n)
|
23
|
+
# roles('role_1', ..., 'role_n')
|
24
|
+
# roles([:role_1, ..., :role_n])
|
25
|
+
# roles(['role_1', ..., 'role_n'])
|
26
|
+
#
|
27
|
+
# declare valid roles
|
28
|
+
def roles(*roles)
|
29
|
+
puts "roles: #{roles}"
|
30
|
+
self.valid_roles = Array[*roles].flatten.map { |r| r.to_sym }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RoleModels::Generic::Base
|
2
|
+
module Implementation
|
3
|
+
|
4
|
+
# check if a given role has been assigned
|
5
|
+
# if a list of roles: check if ALL of the given roles have been assigned
|
6
|
+
def has_roles?(*roles)
|
7
|
+
(roles_list - roles.flatten).empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
# check if any (at least ONE) of the given roles have been assigned
|
11
|
+
def has_role? *roles
|
12
|
+
(roles_list & roles.flatten).not.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_role? role
|
16
|
+
strategy_class.valid_roles.include? role.to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
def admin?
|
20
|
+
is? :admin
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :has?, :has_role?
|
24
|
+
alias_method :is?, :has_roles?
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RoleModels::Generic::Base
|
2
|
+
module Configuration
|
3
|
+
def configure(options={})
|
4
|
+
numericality = options[:num]
|
5
|
+
type = options[:type]
|
6
|
+
|
7
|
+
class_eval do
|
8
|
+
include RoleModels::Generic::Base
|
9
|
+
include RoleModels::Generic::Base::SingleRole if numericality == :single
|
10
|
+
include RoleModels::Generic::Base::RoleClass::InstanceMethods if type == :role_class
|
11
|
+
include self::Implementation
|
12
|
+
|
13
|
+
alias_method :role_symbols, :roles
|
14
|
+
end
|
15
|
+
extend RoleModels::Generic::Base::ClassMethods
|
16
|
+
extend RoleModels::Generic::Base::DefaultRoleKeys
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module SingleRole
|
21
|
+
def role
|
22
|
+
roles.first
|
23
|
+
end
|
24
|
+
|
25
|
+
def role= new_role
|
26
|
+
self.roles = new_role
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module DefaultRoleKeys
|
31
|
+
def default_role_key
|
32
|
+
valid_roles.last || :user
|
33
|
+
end
|
34
|
+
|
35
|
+
def admin_role_key
|
36
|
+
valid_roles.first || :admin
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|