rolify 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - ruby-head
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,14 @@
1
+ = 1.0
2
+ * added a new parameter to disable dynamic shortcut methods due to potential incompatibility with other gems using method_missing with the same pattern
3
+ * add <tt>Rolify.dynamic_shortcuts = false</tt> in the initializer file or
4
+ * use the generator command with a third parameter:
5
+ * <tt>rails g rolify:role Role User false</tt>
6
+ * removed the railtie as it created more problems than it solved
7
+ * code refactoring to do some speed improvements and code clean up
8
+ * added a lot of specs to improve tests coverage
9
+ * wrote a tutorial showing how to use rolify with CanCan and Devise
10
+ * rolify is now on travis-ci
11
+
1
12
  = 0.7
2
13
  * added a method_missing to catch newly created role outside the current ruby process (i.e. dynamic shortcut methods are not defined within this process)
3
14
  * dynamic shortcut is created on the fly in the method_missing to avoid extra method_missing for the same dynamic shortcut
data/Gemfile CHANGED
@@ -8,4 +8,5 @@ gemspec
8
8
  group :test do
9
9
  gem "sqlite3"
10
10
  gem "rspec"
11
- end
11
+ gem "rake"
12
+ end
data/README.rdoc CHANGED
@@ -1,5 +1,4 @@
1
- = rolify
2
-
1
+ = rolify http://travis-ci.org/EppO/rolify.png
3
2
  Very simple Roles library without any authorization enforcement supporting scope on resource object.
4
3
 
5
4
  Let's see an example:
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ task :default => :spec
5
+
6
+ desc "Run all specs"
7
+ task "spec" do
8
+ exec "bundle exec rspec spec"
9
+ end
@@ -8,6 +8,7 @@ module Rolify
8
8
  source_root File.expand_path('../templates', __FILE__)
9
9
  argument :role_cname, :type => :string, :default => "Role"
10
10
  argument :user_cname, :type => :string, :default => "User"
11
+ class_option :dynamic_shortcuts, :type => :boolean, :default => true
11
12
 
12
13
  desc "Generates a model with the given NAME and a migration file."
13
14
 
@@ -15,7 +16,7 @@ module Rolify
15
16
  template "role.rb", "app/models/#{role_cname.downcase}.rb"
16
17
  inject_into_class(model_path, user_cname.camelize) do
17
18
  " include Rolify::Roles\n" +
18
- " extend Rolify::Reloaded\n" +
19
+ "#{" extend Rolify::Reloaded\n" if options[:dynamic_shortcuts]}" +
19
20
  " has_and_belongs_to_many :roles#{", :class_name => \"" + role_cname.camelize + "\"" if role_cname != "Role"}, :join_table => :#{user_cname.tableize + "_" + role_cname.tableize}\n"
20
21
  end
21
22
  end
@@ -1,2 +1,3 @@
1
1
  Rolify.user_cname = <%= user_cname.camelize %>
2
2
  Rolify.role_cname = <%= role_cname.camelize %>
3
+ Rolify.dynamic_shortcuts = <%= options[:dynamic_shortcuts].to_s %> if ARGV[0] != "db:migrate"
data/lib/rolify.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'active_record'
2
2
 
3
3
  require 'rolify/role'
4
- require 'rolify/rolify_railtie.rb' if defined?(Rails)
5
4
 
data/lib/rolify/role.rb CHANGED
@@ -16,6 +16,14 @@ module Rolify
16
16
  @@user_cname = user_cname
17
17
  end
18
18
 
19
+ def self.dynamic_shortcuts
20
+ @@dynamic_shortcuts || false
21
+ end
22
+
23
+ def self.dynamic_shortcuts=(is_dynamic)
24
+ @@dynamic_shortcuts = is_dynamic
25
+ Rolify.user_cname.load_dynamic_methods if is_dynamic
26
+ end
19
27
 
20
28
  module Roles
21
29
 
@@ -24,7 +32,7 @@ module Rolify
24
32
  :resource_type => (resource.class.name if resource),
25
33
  :resource_id => (resource.id if resource))
26
34
  if !roles.include?(role)
27
- self.class.define_dynamic_method role_name, resource
35
+ self.class.define_dynamic_method(role_name, resource) if Rolify.dynamic_shortcuts
28
36
  self.roles << role
29
37
  end
30
38
  end
@@ -35,8 +43,6 @@ module Rolify
35
43
  end
36
44
 
37
45
  def has_all_roles?(*args)
38
- conditions = []
39
- values = []
40
46
  args.each do |arg|
41
47
  if arg.is_a? Hash
42
48
  return false if !self.has_role?(arg[:name], arg[:resource])
@@ -50,19 +56,7 @@ module Rolify
50
56
  end
51
57
 
52
58
  def has_any_role?(*args)
53
- conditions = []
54
- values = []
55
- args.each do |arg|
56
- if arg.is_a? Hash
57
- a, v = build_query(arg[:name], arg[:resource])
58
- elsif arg.is_a? String
59
- a, v = build_query(arg)
60
- else
61
- raise ArgumentError, "Invalid argument type: only hash or string allowed"
62
- end
63
- conditions << a
64
- values += v
65
- end
59
+ conditions, values = sql_conditions(args)
66
60
  self.roles.where([ conditions.join(' OR '), *values ]).size > 0
67
61
  end
68
62
 
@@ -82,13 +76,31 @@ module Rolify
82
76
  if Rolify.role_cname.where(:name => $1).count > 0
83
77
  resource = args.first
84
78
  self.class.define_dynamic_method $1, resource
85
- has_role?("#{$1}", resource)
79
+ return has_role?("#{$1}", resource)
86
80
  end
87
- end
81
+ end unless !Rolify.dynamic_shortcuts
82
+ super
88
83
  end
89
84
 
90
85
  private
91
86
 
87
+ def sql_conditions(args)
88
+ conditions = []
89
+ values = []
90
+ args.each do |arg|
91
+ if arg.is_a? Hash
92
+ a, v = build_query(arg[:name], arg[:resource])
93
+ elsif arg.is_a? String
94
+ a, v = build_query(arg)
95
+ else
96
+ raise ArgumentError, "Invalid argument type: only hash or string allowed"
97
+ end
98
+ conditions << a
99
+ values += v
100
+ end
101
+ [ conditions, values ]
102
+ end
103
+
92
104
  def build_query(role, resource = nil)
93
105
  query = "((name = ?) AND (resource_type IS NULL) AND (resource_id IS NULL))"
94
106
  values = [ role ]
@@ -1,3 +1,3 @@
1
1
  module Rolify
2
- VERSION = "0.7.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,10 +1,12 @@
1
1
  require "spec_helper"
2
2
 
3
- shared_examples_for "Rolify module" do
3
+ shared_examples_for "Rolify module" do |dynamic|
4
4
  context "in a Instance level" do
5
5
  before(:all) do
6
6
  Rolify.user_cname = user_cname
7
7
  Rolify.role_cname = role_cname
8
+ Rolify.dynamic_shortcuts = dynamic_shortcuts
9
+ Rolify.role_cname.destroy_all
8
10
  @admin = Rolify.user_cname.first
9
11
  @admin.has_role "admin"
10
12
  @admin.has_role "moderator", Forum.first
@@ -35,23 +37,28 @@ shared_examples_for "Rolify module" do
35
37
  @admin.should respond_to(:has_no_role).with(2).arguments
36
38
  end
37
39
 
38
- it "should respond to dynamic methods" do
40
+ it "should respond to dynamic methods", :if => dynamic do
39
41
  @admin.should respond_to(:is_admin?).with(0).arguments
40
42
  @admin.should respond_to(:is_moderator_of?).with(1).arguments
41
43
  end
42
44
 
43
- it "should not respond to any unknown methods" do
45
+ it "should not respond to any unknown methods", :if => dynamic do
44
46
  @admin.should_not respond_to(:is_god?)
45
47
  end
46
48
 
47
- it "should create a new dynamic method if role exists in database" do
49
+ it "should create a new dynamic method if role exists in database", :if => dynamic do
48
50
  Rolify.role_cname.create(:name => "superman")
49
- @admin.is_superman?.should be(false)
50
51
  @admin.should respond_to(:is_superman?).with(0).arguments
52
+ @admin.is_superman?.should be(false)
51
53
  Rolify.role_cname.create(:name => "batman", :resource => Forum.first)
52
- @admin.is_batman_of?(Forum.first).should be(false)
53
54
  @admin.should respond_to(:is_batman_of?).with(1).arguments
54
55
  @admin.should respond_to(:is_batman?).with(0).arguments
56
+ @admin.is_batman_of?(Forum.first).should be(false)
57
+ end
58
+
59
+ it "should not have any dynamic methods if dynamic_shortcuts is disabled", :if => dynamic == false do
60
+ @admin.should_not respond_to(:is_admin?)
61
+ @admin.should_not respond_to(:is_moderator_of?)
55
62
  end
56
63
  end
57
64
 
@@ -79,7 +86,7 @@ shared_examples_for "Rolify module" do
79
86
  @admin.has_role?("admin").should be(true)
80
87
  end
81
88
 
82
- it "should be able to use dynamic shortcut" do
89
+ it "should be able to use dynamic shortcut", :if => dynamic do
83
90
  @admin.is_admin?.should be(true)
84
91
  end
85
92
 
@@ -102,13 +109,14 @@ shared_examples_for "Rolify module" do
102
109
  end
103
110
 
104
111
  it "should check if user has all of a global roles set" do
105
- @admin.has_role?("staff").should be(true)
112
+ @admin.has_all_roles?("staff").should be(true)
106
113
  @admin.has_all_roles?("admin", "staff").should be(true)
107
114
  @admin.has_all_roles?("admin", "dummy").should be(false)
108
115
  @admin.has_all_roles?("dummy", "dumber").should be(false)
109
116
  end
110
117
 
111
118
  it "should check if user has any of a global roles set" do
119
+ @admin.has_any_role?("staff").should be(true)
112
120
  @admin.has_any_role?("admin", "staff").should be(true)
113
121
  @admin.has_any_role?("admin", "moderator").should be(true)
114
122
  @admin.has_any_role?("dummy", "dumber").should be(false)
@@ -155,7 +163,7 @@ shared_examples_for "Rolify module" do
155
163
  @moderator.has_role?("moderator", Forum.first).should be(true)
156
164
  end
157
165
 
158
- it "should be able to use dynamic shortcut" do
166
+ it "should be able to use dynamic shortcut", :if => dynamic do
159
167
  @moderator.is_moderator?.should be(false)
160
168
  @moderator.is_moderator_of?(Forum.first).should be(true)
161
169
  @moderator.is_moderator_of?(Forum.last).should be(false)
@@ -181,6 +189,7 @@ shared_examples_for "Rolify module" do
181
189
  end
182
190
 
183
191
  it "should check if user has all of a scoped roles set" do
192
+ @moderator.has_all_roles?({ :name => "visitor", :resource => Forum.last }).should be(true)
184
193
  @moderator.has_all_roles?({ :name => "moderator", :resource => Forum.first },
185
194
  { :name => "visitor", :resource => Forum.last }).should be(true)
186
195
  @moderator.has_all_roles?({ :name => "moderator", :resource => Forum.first },
@@ -190,6 +199,7 @@ shared_examples_for "Rolify module" do
190
199
  end
191
200
 
192
201
  it "should check if user has any of a scoped roles set" do
202
+ @moderator.has_any_role?( { :name => "visitor", :resource => Forum.last }).should be(true)
193
203
  @moderator.has_any_role?( { :name => "moderator", :resource => Forum.first },
194
204
  { :name => "visitor", :resource => Forum.last }).should be(true)
195
205
  @moderator.has_any_role?( { :name => "moderator", :resource => Forum.first },
@@ -235,12 +245,14 @@ shared_examples_for "Rolify module" do
235
245
  it "should check if user has all of a mix of global and scoped roles set" do
236
246
  @user.has_all_roles?("admin", { :name => "moderator", :resource => Forum.first }).should be(true)
237
247
  @user.has_all_roles?("admin", { :name => "moderator", :resource => Forum.last }).should be(false)
248
+ @user.has_all_roles?({ :name => "admin", :resource => Forum.first }, { :name => "moderator", :resource => Forum.first }).should be(true)
238
249
  @user.has_all_roles?("dummy", { :name => "dumber", :resource => Forum.last }).should be(false)
239
250
  end
240
251
 
241
252
  it "should check if user has any of a mix of global and scoped roles set" do
242
253
  @user.has_any_role?("admin", { :name => "moderator", :resource => Forum.first }).should be(true)
243
254
  @user.has_any_role?("admin", { :name => "moderator", :resource => Forum.last }).should be(true)
255
+ @user.has_any_role?({ :name => "admin", :resource => Forum.first }, { :name => "moderator", :resource => Forum.last }).should be(true)
244
256
  @user.has_any_role?("dummy", { :name => "dumber", :resource => Forum.last }).should be(false)
245
257
  end
246
258
  end
@@ -248,17 +260,35 @@ shared_examples_for "Rolify module" do
248
260
  end
249
261
 
250
262
  describe Rolify do
251
- context "using default Role and User class names" do
263
+ context "using default Role and User class names with dynamic shortcuts", true do
264
+ it_behaves_like "Rolify module" do
265
+ let(:user_cname) { User }
266
+ let(:role_cname) { Role }
267
+ let(:dynamic_shortcuts) { true }
268
+ end
269
+ end
270
+
271
+ context "using default Role and User class names without dynamic shortcuts", false do
252
272
  it_behaves_like "Rolify module" do
253
273
  let(:user_cname) { User }
254
274
  let(:role_cname) { Role }
275
+ let(:dynamic_shortcuts) { false }
276
+ end
277
+ end
278
+
279
+ context "using custom User and Role class names with dynamic shortcuts", true do
280
+ it_behaves_like "Rolify module" do
281
+ let(:user_cname) { Customer }
282
+ let(:role_cname) { Privilege }
283
+ let(:dynamic_shortcuts) { true }
255
284
  end
256
- end
285
+ end
257
286
 
258
- context "using custom User and Role class names" do
287
+ context "using custom User and Role class names without dynamic shortcuts", false do
259
288
  it_behaves_like "Rolify module" do
260
289
  let(:user_cname) { Customer }
261
290
  let(:role_cname) { Privilege }
291
+ let(:dynamic_shortcuts) { false }
262
292
  end
263
293
  end
264
294
  end
metadata CHANGED
@@ -1,50 +1,49 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rolify
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
4
5
  prerelease:
5
- version: 0.7.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Florent Monbillard
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-06-21 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2011-08-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: sqlite3
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &79887380 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
24
22
  type: :development
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: activerecord
28
23
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *79887380
25
+ - !ruby/object:Gem::Dependency
26
+ name: activerecord
27
+ requirement: &79887130 !ruby/object:Gem::Requirement
30
28
  none: false
31
- requirements:
29
+ requirements:
32
30
  - - ~>
33
- - !ruby/object:Gem::Version
31
+ - !ruby/object:Gem::Version
34
32
  version: 3.1.0.rc1
35
33
  type: :runtime
36
- version_requirements: *id002
37
- description: "Very simple Roles library without any authorization enforcement (built to use with cancan) supporting scope on resource: user.is_moderator?(Forum.first) => # return false if user is moderator of another Forum "
38
- email:
34
+ prerelease: false
35
+ version_requirements: *79887130
36
+ description: ! 'Very simple Roles library without any authorization enforcement (built
37
+ to use with cancan) supporting scope on resource: user.is_moderator?(Forum.first)
38
+ => # return false if user is moderator of another Forum '
39
+ email:
39
40
  - f.monbillard@gmail.com
40
41
  executables: []
41
-
42
42
  extensions: []
43
-
44
43
  extra_rdoc_files: []
45
-
46
- files:
44
+ files:
47
45
  - .gitignore
46
+ - .travis.yml
48
47
  - CHANGELOG.rdoc
49
48
  - Gemfile
50
49
  - LICENSE
@@ -56,7 +55,6 @@ files:
56
55
  - lib/generators/rolify/role/templates/role.rb
57
56
  - lib/rolify.rb
58
57
  - lib/rolify/role.rb
59
- - lib/rolify/rolify_railtie.rb
60
58
  - lib/rolify/version.rb
61
59
  - rolify.gemspec
62
60
  - spec/rolify/role_spec.rb
@@ -67,30 +65,26 @@ files:
67
65
  - spec/support/schema.rb
68
66
  homepage: https://github.com/EppO/rolify
69
67
  licenses: []
70
-
71
68
  post_install_message:
72
69
  rdoc_options: []
73
-
74
- require_paths:
70
+ require_paths:
75
71
  - lib
76
- required_ruby_version: !ruby/object:Gem::Requirement
72
+ required_ruby_version: !ruby/object:Gem::Requirement
77
73
  none: false
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: "0"
82
- required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
79
  none: false
84
- requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- version: "0"
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
88
84
  requirements: []
89
-
90
85
  rubyforge_project: rolify
91
- rubygems_version: 1.7.2
86
+ rubygems_version: 1.8.5
92
87
  signing_key:
93
88
  specification_version: 3
94
89
  summary: Roles library with resource scoping
95
90
  test_files: []
96
-
@@ -1,9 +0,0 @@
1
- module Rolify
2
- class RoleRailtie < ::Rails::Railtie
3
- initializer "instantiate roles methods" do
4
- ActiveSupport.on_load :active_record do
5
- Rolify.user_cname.load_dynamic_methods if defined? Rails.server
6
- end
7
- end
8
- end
9
- end