authorizer 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -100,9 +100,11 @@ Optional:
100
100
 
101
101
  == INSTALL:
102
102
 
103
- 1. sudo gem install authorizer
104
- 2. add "authorizer" to your Gemfile (I hope you've stopped using config.gem already even if you are on Rails 2.3?)
105
- 3. generate a migration for authorization objects:
103
+ Step 1. sudo gem install authorizer
104
+
105
+ Step 2. add "authorizer" to your Gemfile (I hope you've stopped using config.gem already even if you are on Rails 2.3?)
106
+
107
+ Step 3. generate a migration for authorization objects:
106
108
 
107
109
  script/generate migration CreateObjectRoles
108
110
 
@@ -123,8 +125,9 @@ Paste this code into the newly generated file:
123
125
  drop_table :object_roles
124
126
  end
125
127
 
126
- 4. run "rake db:migrate" to migrate your database
127
- 5. Add these lines to your app/controllers/application_controller.rb:
128
+ Step 4. run "rake db:migrate" to migrate your database
129
+
130
+ Step 5. Add these lines to your app/controllers/application_controller.rb:
128
131
 
129
132
  require 'authorizer/exceptions'
130
133
 
@@ -133,7 +136,7 @@ Paste this code into the newly generated file:
133
136
  render :file => "#{Rails.root}/public/403.html", :status => 403
134
137
  end
135
138
 
136
- 6. Download the file public/403.html from {authorizer_project}[https://github.com/cmdjohnson/authorizer_project] and copy it to your own app.
139
+ Step 6. Download the file public/403.html from {authorizer_project}[https://github.com/cmdjohnson/authorizer_project] and copy it to your own app.
137
140
 
138
141
  That's it!
139
142
 
@@ -3,5 +3,5 @@ $:.unshift(File.dirname(__FILE__)) unless
3
3
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
4
4
 
5
5
  module Authorizer
6
- VERSION = '0.0.2'
6
+ VERSION = '0.0.3'
7
7
  end
@@ -11,28 +11,36 @@ require 'authorizer/application_controller'
11
11
 
12
12
  module Authorizer
13
13
  class Base < ApplicationController
14
- ############################################################################
15
- # authorize_user
14
+ # Authorize the current user (retrieved by calling current_user on the object passed using the :object parameter.
15
+ # The user can also be explicly spcified using :user.
16
+ # If no :role is specified, "owner" is used.
17
+ #
18
+ # Params:
19
+ # - :user (default: current_user)
20
+ # - :object
21
+ # - :role
16
22
  #
17
- # If no user is specified, authorizes the current user.
18
- # If no role is specified, "owner" is used as role.
19
- ############################################################################
20
-
21
- def self.authorize_user(options)
22
- OptionsChecker.check(options, [ :object ])
23
-
23
+ # Example: Authorizer::Base.authorize_user :object => object
24
+ def self.authorize_user(options = {})
24
25
  ret = false
25
26
 
26
27
  object = options[:object]
27
28
  role = options[:role] || "owner"
28
29
  user = options[:user] || get_current_user
30
+
31
+ # User can specify the object using a block, too.
32
+ if block_given?
33
+ object = yield
34
+ end
29
35
 
30
36
  return false if basic_check_fails?(options)
31
37
 
32
38
  check_user(user)
33
39
  # Checks done. Let's go.
34
40
 
35
- or_ = find_object_role(object, user)
41
+ if !object.nil? && !user.nil?
42
+ or_ = find_object_role(object, user)
43
+ end
36
44
 
37
45
  # This time, we want it to be nil.
38
46
  if or_.nil? && !user.nil?
@@ -47,12 +55,10 @@ module Authorizer
47
55
  ret
48
56
  end
49
57
 
50
- ############################################################################
51
- # authorize!
52
- #
53
- # Bang version of authorize
54
- ############################################################################
55
-
58
+ # Return true if a user is authorized to act upon this object. Raises Authorizer::UserNotAuthorized upon failure.
59
+ # Params:
60
+ # - :user (default: current_user)
61
+ # - :object
56
62
  def self.authorize! options = {}
57
63
  auth_ok = user_is_authorized?(options)
58
64
 
@@ -71,12 +77,10 @@ module Authorizer
71
77
  auth_ok
72
78
  end
73
79
 
74
- ############################################################################
75
- # user_is_authorized?
76
- #
77
- # If no user is specified, current_user is used.
78
- ############################################################################
79
-
80
+ # Return true if a user is authorized to act upon this object. Return false if this is not the case.
81
+ # Params:
82
+ # - :user (default: current_user)
83
+ # - :object
80
84
  def self.user_is_authorized? options = {}
81
85
  OptionsChecker.check(options, [ :object ])
82
86
 
@@ -108,17 +112,19 @@ module Authorizer
108
112
  ret
109
113
  end
110
114
 
111
- # Could't get alias_method to work. Don't ask me why.
115
+ # Return true if a user is authorized to act upon this object. Return false if this is not the case.
116
+ # Synonym for user_is_authorized?
117
+ # Params:
118
+ # - :user (default: current_user)
119
+ # - :object
112
120
  def self.authorize(options = {})
113
- user_is_authorized?(options)
121
+ user_is_authorized?(options) # Could't get alias_method to work. Don't ask me why.
114
122
  end
115
123
 
116
- ############################################################################
117
- # remove_authorization
118
- ############################################################################
119
- # Remove authorization a user has on a certain object.
120
- ############################################################################
121
-
124
+ # Remove authorization from a certain object. Returns true upon success and false upon failure.
125
+ # Params:
126
+ # - :user (default: current_user)
127
+ # - :object
122
128
  def self.remove_authorization options = {}
123
129
  OptionsChecker.check(options, [ :object ])
124
130
 
@@ -133,7 +139,9 @@ module Authorizer
133
139
  check_user(user)
134
140
  # Checks done. Let's go.
135
141
 
136
- or_ = find_object_role(object, user)
142
+ unless user.nil?
143
+ or_ = find_object_role(object, user)
144
+ end
137
145
 
138
146
  unless or_.nil?
139
147
  Rails.logger.debug("Authorizer: removed authorization for user ID #{user.id} on #{or_.description}")
@@ -145,10 +153,26 @@ module Authorizer
145
153
 
146
154
  ret
147
155
  end
156
+
157
+ # From the entire collection of Posts in the database, return the number of Posts that belong to the current user.
158
+ # Returns nil upon failure, returns a positive integer or 0 on success.
159
+ def self.count(class_name, options = {})
160
+ ret = nil
161
+
162
+ user = options[:user] || get_current_user
163
+ find_options = options[:find_options] || {}
164
+
165
+ if !class_name.blank? && !user.blank?
166
+ begin
167
+ ret = Authorizer::Base.find(class_name, :all, find_options, { :user => user }).count
168
+ rescue => e
169
+ Rails.logger.warn("#{__FILE__}: #{__LINE__}: Failed to count objects for class_name '#{class_name}' for user #{user.inspect}. Error was: #{e}")
170
+ end
171
+ end
172
+
173
+ ret
174
+ end
148
175
 
149
- ############################################################################
150
- # find
151
- ############################################################################
152
176
  # From the entire collection of Posts, return the subset that belongs to the current user.
153
177
  #
154
178
  # Arguments:
@@ -156,8 +180,6 @@ module Authorizer
156
180
  # - what: will be passed on to the ActiveRecord find function (e.g. Post.find(what))
157
181
  # - find_options: will also be passed on (e.g. Post.find(what, find_options))
158
182
  # - authorizer_options: options for authorizer, e.g. { :user => @user }
159
- ############################################################################
160
-
161
183
  def self.find(class_name, what, find_options = {}, authorizer_options = {})
162
184
  options = { :class_name => class_name, :what => what, :find_options => find_options }
163
185
  my_options = authorizer_options.merge(options) # options overrides user-specified options.
@@ -165,20 +187,15 @@ module Authorizer
165
187
  internal_find(my_options)
166
188
  end
167
189
 
168
- ############################################################################
169
- # is_authorized?
170
- ############################################################################
171
-
190
+ # Return true if a user is authorized to act upon this object. Return false if this is not the case.
191
+ # Synonym for user_is_authorized
192
+ #
193
+ # This method's only parameter is the object to be checked for authorization so you don't have to type :object => object.
172
194
  def self.is_authorized? object
173
195
  user_is_authorized? :object => object
174
196
  end
175
197
 
176
- ############################################################################
177
- # create_ownership
178
- #
179
- # ObjectRole.create!( :klazz_name => object.class.to_s, :object_reference => object.id, :user => current_user, :role => "owner" )
180
- ############################################################################
181
-
198
+ # Shortcut for user_is_authorized. Takes the actual object as a parameter instead of a Hash.
182
199
  def self.create_ownership object
183
200
  ret = false
184
201
 
@@ -233,11 +250,19 @@ module Authorizer
233
250
  # Get the real klazz
234
251
  klazz = nil
235
252
  # Check it
236
- begin
237
- klazz = eval(class_name)
238
- rescue => e
239
- # Throw an exception if klazz is nil
240
- raise ArgumentError.new("Could not eval class '#{klazz}'. It presumably does not exist. Maybe you mistyped its name? Error was: #{e.inspect}") if klazz.nil?
253
+ # Ok, Check it ... but ...
254
+ # If no user is found, let's leave it up to the auth solution to redirect the user to a login page.
255
+ unless user.nil?
256
+ begin
257
+ klazz = eval(class_name)
258
+ rescue => e
259
+ # No need to throw this exception here. Just log the error.
260
+ # It would appear whenever Authorizer was used when a user isn't logged in.
261
+ # That just is too much ...
262
+ s = "Could not eval class '#{class_name}'. It presumably does not exist. Maybe you mistyped its name? Error was: #{e.inspect}"
263
+ #raise ArgumentError.new(s) if klazz.nil?
264
+ Rails.logger.warn("#{__FILE__}: #{__LINE__}: " + s)
265
+ end
241
266
  end
242
267
  # oooo ooo ooo ___ --- === __- --_- ++_+_ =--- +- =+=-=- =-= <--- ice beam!
243
268
  unless klazz.nil?
@@ -278,6 +303,7 @@ module Authorizer
278
303
  ret
279
304
  end
280
305
 
306
+ # Find the ObjectRole record that matches object (first argument) and user (second argument).
281
307
  def self.find_object_role(object, user)
282
308
  return nil if object.nil? || user.nil?
283
309
 
@@ -309,19 +335,24 @@ module Authorizer
309
335
 
310
336
  def self.check_user(user)
311
337
  ret = true
312
-
313
- if user.nil?
314
- raise Authorizer::RuntimeException.new "User cannot be nil. Maybe you should specify authorizer_options = { :user => user } if you are not calling from a controller?"
315
- end
316
-
317
- unless user.is_a?(ActiveRecord::Base)
318
- raise Authorizer::RuntimeException.new "User must inherit from ActiveRecord::Base"
319
-
320
- end
321
-
322
- if user.new_record?
323
- raise Authorizer::RuntimeException.new "User must be saved"
324
- end
338
+
339
+ # YES YES I know it's a good habit to check for current_user, but I've decided not to raise anything
340
+ # and make this method basically void.
341
+ # Why?
342
+ # Let the auth mechanism redirect the user if no user is present.
343
+ # I think that's the proper way to do things.
344
+
345
+ # if user.nil?
346
+ # raise Authorizer::RuntimeException.new "User cannot be nil. Maybe you should specify authorizer_options = { :user => user } if you are not calling from a controller?"
347
+ # end
348
+ #
349
+ # unless user.is_a?(ActiveRecord::Base)
350
+ # raise Authorizer::RuntimeException.new "User must inherit from ActiveRecord::Base"
351
+ # end
352
+ #
353
+ # if user.new_record?
354
+ # raise Authorizer::RuntimeException.new "User must be saved"
355
+ # end
325
356
 
326
357
  ret
327
358
  end
@@ -17,5 +17,29 @@ module Authorizer
17
17
  object_role.destroy
18
18
  end
19
19
  end
20
+
21
+ # This is a Rails only feature:
22
+ # Single Table Inheritance (STI) is implemented using the Type column.
23
+ # The 'type' column contains the name of the subclass of the table the record is in.
24
+ # For example, Dog is a subclass of Animal.
25
+ # If we have a Dog object here that changes its 'type' to Animal, the ObjectRole must be updated to reflect the new class name.
26
+ def after_update(object)
27
+ type = object.try(:read_attribute, :type)
28
+ # Big chance the object doesn't even have the 'type' attribute. In that case, do nothing.
29
+ unless type.blank?
30
+ object_class_name = object.class.to_s
31
+ # This is how we gonna detect that the type has changed:
32
+ # object_class_name should be different than type.
33
+ unless type.eql?(object_class_name)
34
+ object_roles = ObjectRole.find_all_by_object(object)
35
+ # Walk through the object roles associated with this object
36
+ for object_role in object_roles
37
+ # update it!
38
+ # it should reflect the new type.
39
+ object_role.update_attributes!( :klazz_name => type )
40
+ end
41
+ end
42
+ end
43
+ end
20
44
  end
21
45
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authorizer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease: false
4
+ hash: 25
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - CmdJohnson
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-22 00:00:00 +02:00
19
- default_executable:
18
+ date: 2011-09-27 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: options_checker
@@ -40,14 +39,13 @@ dependencies:
40
39
  requirement: &id002 !ruby/object:Gem::Requirement
41
40
  none: false
42
41
  requirements:
43
- - - ">="
42
+ - - ~>
44
43
  - !ruby/object:Gem::Version
45
- hash: 47
44
+ hash: 27
46
45
  segments:
47
46
  - 2
48
- - 8
49
- - 0
50
- version: 2.8.0
47
+ - 12
48
+ version: "2.12"
51
49
  type: :development
52
50
  version_requirements: *id002
53
51
  description: |-
@@ -110,7 +108,6 @@ files:
110
108
  - lib/authorizer/user_observer.rb
111
109
  - app/models/object_role.rb
112
110
  - rails/init.rb
113
- has_rdoc: true
114
111
  homepage: https://github.com/cmdjohnson/authorizer
115
112
  licenses: []
116
113
 
@@ -141,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
138
  requirements: []
142
139
 
143
140
  rubyforge_project: authorizer
144
- rubygems_version: 1.3.7
141
+ rubygems_version: 1.8.10
145
142
  signing_key:
146
143
  specification_version: 3
147
144
  summary: Authorizer is a gem for Ruby (in conjunction with Rails 2.3) that does authorization for you on a per-object basis