authorizer 0.0.2 → 0.0.3
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/README.rdoc +9 -6
- data/lib/authorizer.rb +1 -1
- data/lib/authorizer/base.rb +95 -64
- data/lib/authorizer/object_observer.rb +24 -0
- metadata +10 -13
data/README.rdoc
CHANGED
@@ -100,9 +100,11 @@ Optional:
|
|
100
100
|
|
101
101
|
== INSTALL:
|
102
102
|
|
103
|
-
1. sudo gem install authorizer
|
104
|
-
|
105
|
-
|
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
|
-
|
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
|
|
data/lib/authorizer.rb
CHANGED
data/lib/authorizer/base.rb
CHANGED
@@ -11,28 +11,36 @@ require 'authorizer/application_controller'
|
|
11
11
|
|
12
12
|
module Authorizer
|
13
13
|
class Base < ApplicationController
|
14
|
-
|
15
|
-
#
|
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
|
-
#
|
18
|
-
|
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
|
-
|
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
|
-
#
|
52
|
-
#
|
53
|
-
#
|
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
|
-
#
|
76
|
-
#
|
77
|
-
#
|
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
|
-
#
|
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
|
-
#
|
118
|
-
|
119
|
-
#
|
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
|
-
|
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
|
-
#
|
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
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
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
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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-
|
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:
|
44
|
+
hash: 27
|
46
45
|
segments:
|
47
46
|
- 2
|
48
|
-
-
|
49
|
-
|
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.
|
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
|