ucb_rails_security 2.0.7

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 (60) hide show
  1. data/CHANGELOG +6 -0
  2. data/Manifest +56 -0
  3. data/README +195 -0
  4. data/Rakefile +21 -0
  5. data/TODO +3 -0
  6. data/generators/ucb_rails_security/templates/controllers/ucb_security/base_controller.rb +17 -0
  7. data/generators/ucb_rails_security/templates/controllers/ucb_security/ldap_search_controller.rb +10 -0
  8. data/generators/ucb_rails_security/templates/controllers/ucb_security/role_users_controller.rb +27 -0
  9. data/generators/ucb_rails_security/templates/controllers/ucb_security/roles_controller.rb +52 -0
  10. data/generators/ucb_rails_security/templates/controllers/ucb_security/user_roles_controller.rb +29 -0
  11. data/generators/ucb_rails_security/templates/controllers/ucb_security/users_controller.rb +59 -0
  12. data/generators/ucb_rails_security/templates/db/migrate/xxx_create_ucb_rails_security_tables.rb +31 -0
  13. data/generators/ucb_rails_security/templates/helpers/ucb_security/base_helper.rb +23 -0
  14. data/generators/ucb_rails_security/templates/helpers/ucb_security/builder.rb +25 -0
  15. data/generators/ucb_rails_security/templates/helpers/ucb_security/roles_helper.rb +2 -0
  16. data/generators/ucb_rails_security/templates/helpers/ucb_security/users_helper.rb +2 -0
  17. data/generators/ucb_rails_security/templates/initializers/ucb_security_config.rb +20 -0
  18. data/generators/ucb_rails_security/templates/javascripts/ucb_security.js +99 -0
  19. data/generators/ucb_rails_security/templates/models/ldap_search.rb +48 -0
  20. data/generators/ucb_rails_security/templates/models/role.rb +32 -0
  21. data/generators/ucb_rails_security/templates/models/user.rb +106 -0
  22. data/generators/ucb_rails_security/templates/models/user_roles.rb +3 -0
  23. data/generators/ucb_rails_security/templates/stylesheets/ucb_security.css +347 -0
  24. data/generators/ucb_rails_security/templates/views/layouts/ucb_security/_main_navigation.html.erb +10 -0
  25. data/generators/ucb_rails_security/templates/views/layouts/ucb_security/application.html.erb +24 -0
  26. data/generators/ucb_rails_security/templates/views/ucb_security/ldap_search/index.html.erb +62 -0
  27. data/generators/ucb_rails_security/templates/views/ucb_security/role_users/_new.html.erb +11 -0
  28. data/generators/ucb_rails_security/templates/views/ucb_security/role_users/edit.html.erb +37 -0
  29. data/generators/ucb_rails_security/templates/views/ucb_security/roles/_users.html.erb +14 -0
  30. data/generators/ucb_rails_security/templates/views/ucb_security/roles/edit.html.erb +19 -0
  31. data/generators/ucb_rails_security/templates/views/ucb_security/roles/index.html.erb +34 -0
  32. data/generators/ucb_rails_security/templates/views/ucb_security/roles/new.html.erb +19 -0
  33. data/generators/ucb_rails_security/templates/views/ucb_security/roles/show.html.erb +27 -0
  34. data/generators/ucb_rails_security/templates/views/ucb_security/user_roles/edit.html.erb +17 -0
  35. data/generators/ucb_rails_security/templates/views/ucb_security/users/edit.html.erb +23 -0
  36. data/generators/ucb_rails_security/templates/views/ucb_security/users/index.html.erb +43 -0
  37. data/generators/ucb_rails_security/templates/views/ucb_security/users/new.html.erb +29 -0
  38. data/generators/ucb_rails_security/templates/views/ucb_security/users/show.html.erb +43 -0
  39. data/generators/ucb_rails_security/ucb_rails_security_generator.rb +191 -0
  40. data/init.rb +9 -0
  41. data/lib/helpers/rspec_helpers.rb +119 -0
  42. data/lib/tasks/ucb_rails_security.rake +22 -0
  43. data/lib/ucb_rails_security.rb +60 -0
  44. data/lib/ucb_rails_security_casauthentication.rb +117 -0
  45. data/lib/ucb_rails_security_logger.rb +33 -0
  46. data/lib/ucb_rs_controller_methods.rb +496 -0
  47. data/rdoc_includes/application_controller_rb.txt +9 -0
  48. data/rspec/_all_specs.rb +5 -0
  49. data/rspec/_setup.rb +36 -0
  50. data/rspec/filter_ldap_spec.rb +87 -0
  51. data/rspec/filter_role_spec.rb +56 -0
  52. data/rspec/filter_spec.rb +37 -0
  53. data/rspec/filter_user_spec.rb +55 -0
  54. data/rspec/logged_in_status_spec.rb +226 -0
  55. data/rspec/ucb_rails_security_casauthentication_spec.rb +83 -0
  56. data/rspec/ucb_rails_security_spec.rb +34 -0
  57. data/test/test_rails-2.0.x/test/test_helper.rb +38 -0
  58. data/test/test_rails-2.1.x/test/test_helper.rb +38 -0
  59. data/ucb_rails_security.gemspec +41 -0
  60. metadata +147 -0
@@ -0,0 +1,496 @@
1
+ module UCB #:nodoc:
2
+ module Rails #:nodoc:
3
+ module Security
4
+ # == Overview
5
+ # These methods are added to ActionController::Base
6
+ # so they are available to all of your application's controllers.
7
+ #
8
+ # Most of the time you will be using the various <tt>filter_*</tt>
9
+ # methods. Note that most of these methods are implemented via method_missing
10
+ # and are not explicitly listed in the "methods" section of this document.
11
+ # For details see examples below as well as method_missing, filter_ldap and
12
+ # filter_db_role.
13
+ #
14
+ # There are several methods used primarily by the filter methods, but you
15
+ # may find use for these in your controllers. Many of these methods
16
+ # are marked as "helper methods" and are available for use in your
17
+ # views (*.rhtml templates) and helpers. See ApplicationHelper for
18
+ # more information.
19
+ #
20
+ # == How Does This Work?
21
+ # Take a look at the following controller: +RAILS_ROOT/app/controllers/ucb_security/base_controller.rb+
22
+ #
23
+ # You should see the following:
24
+ #
25
+ # class UcbSecurity::BaseController < ApplicationController
26
+ # # Move this include into your ApplicationController to add security to your entire application
27
+ # include UCB::Rails::Security::ControllerMethods
28
+ #
29
+ # layout 'layouts/ucb_security/application'
30
+ # before_filter :filter_role_security, :except => [:not_authorized, :logout]
31
+ # end
32
+ #
33
+ # The +include+ line adds several methods to this base controller, many
34
+ # of which are filters. The line <tt>before_filter :filter_role_security, :except => [:not_authorized, :logout]</tt>
35
+ # tells this controller to only allow a user with the
36
+ # security role access to the actions in this controller. Since all
37
+ # of the ucb_security controllers extend this base controller, that has
38
+ # the requires the user to have the security role for all actions
39
+ # in the ucb_security module (with the exception of not_authorized and
40
+ # logout)
41
+ #
42
+ # When you add one of these filters to your controller, behind the scenes
43
+ # CAS authentication is handled for you: if the user has not yet authenticated
44
+ # they will be directed to CAS otherwise your filter will be run.
45
+ #
46
+ # You may want to add this filter to your application controller. If your
47
+ # entire site requires authentication then that is definitely the way to go.
48
+ # If only a handful of controllers require auth, then only add these filter
49
+ # methods to those specific controllers.
50
+ #
51
+ #
52
+ # ==Explicit Filters
53
+ #
54
+ # User must be logged in:
55
+ #
56
+ # class MyController < ActionController::Base
57
+ # before_filter :filter_logged_in
58
+ # end
59
+ #
60
+ # User must be in user table (assumes your application has
61
+ # a +User+ table -- see UCB::Rails::Security):
62
+ #
63
+ # class MyController < ActionController::Base
64
+ # before_filter :filter_in_user_table
65
+ # end
66
+ #
67
+ # ==LDAP Filters
68
+ #
69
+ # Any LDAP attribute can be used in a dynamic LDAP filter. More accurately, any method
70
+ # that an instance of UCB::LDAP::Person responds to can be used in a filter.
71
+ #
72
+ # To satisfy the filter, the method must return a broader-than-normal
73
+ # definition of <tt>true</tt>: strings containing only spaces and empty arrays
74
+ # are considered <tt>false</tt>.
75
+ #
76
+ # Since UCB::LDAP::Person has <tt>employee?</tt> and <tt>student?</tt> methods,
77
+ # we can do the following:
78
+ #
79
+ # class MyController < ActionController::Base
80
+ # before_filter :filter_ldap_employee?
81
+ # before_filter :filter_ldap_student?
82
+ # end
83
+ #
84
+ # You can use any valid UCB::LDAP::Person method or LDAP attribute as the
85
+ # "method" part of :filter_ldap_method. Just keep in mind what constitutes
86
+ # "true".
87
+ #
88
+ # Since there is no "bogus" attribute, the following raises a <tt>NoMethodError</tt>
89
+ # exception:
90
+ #
91
+ # class MyController < ActionController::Base
92
+ # before_filter :filter_ldap_bogus
93
+ # end
94
+ #
95
+ # You can filter based on the value of a particular attribute.
96
+ # Currently supported operators are "eq" and "ne":
97
+ #
98
+ # class MyController < ActionController::Base
99
+ # before_filter :filter_ldap_deptid__eq__JKASD
100
+ # before_filter :filter_ldap_lastname__ne__Badenov
101
+ # end
102
+ #
103
+ # === Note
104
+ #
105
+ # LDAP filters call the filter_logged_in filter.
106
+ #
107
+ # == User Filters
108
+ #
109
+ # If your application has a user table you can do controller filtering
110
+ # based on your user table:
111
+ #
112
+ # The following only allows people who can update to access the controller:
113
+ #
114
+ # class User < ActiveRecord::Base
115
+ # def can_update?
116
+ # <complicated logic>
117
+ # end
118
+ # end
119
+ #
120
+ # class UpdateController < ActionController::Base
121
+ # before_filter :filter_user_can_update?
122
+ # end
123
+ #
124
+ # Filters of the form <tt>:filter_user_method</tt> are passed/failed
125
+ # based on the return value of <tt>User#method</tt>.
126
+ #
127
+ # === Non-boolean User Filters
128
+ #
129
+ # You can filter based on the value of a particular +User+ table
130
+ # method. Currently supported operators are "eq" and "ne":
131
+ #
132
+ # class DoeNotJohnController < ActionController::Base
133
+ # before_filter :filter_user_lastname__eq__Doe
134
+ # before_filter :filter_user_firstname__ne__John
135
+ # end
136
+ #
137
+ # === Note
138
+ #
139
+ # All User filters call the filter_logged_in and filter_in_user_table filters.
140
+ #
141
+ # ==Role Filters
142
+ #
143
+ # If your application has both a user and
144
+ # a roles table (see UCB::Rails::Security)
145
+ # you can use dynamic database role filters.
146
+ #
147
+ # Your user class must repond to the "roles" message
148
+ # by returning an Array of objects that respond to the "name"
149
+ # message.
150
+ #
151
+ # The following verifies the user has the "admin" role:
152
+ #
153
+ # class MyController < ActionController::Base
154
+ # before_filter :filter_role_admin
155
+ # end
156
+ #
157
+ # In general, the ":filter_role_rolename" filter verifies that the
158
+ # user holds the "rolename" role.
159
+ #
160
+ # The following verifies the user has the "admin" <b>and</b> "super_user" roles:
161
+ #
162
+ # class MyController < ActionController::Base
163
+ # before_filter :filter_role_has_all_of_admin_and_super_user
164
+ # end
165
+ #
166
+ # The following verifies the user has either the "guest" <b>or</b> "user" roles:
167
+ #
168
+ # class MyController < ActionController::Base
169
+ # before_filter :filter_role_has_one_of_guest_or_user
170
+ # end
171
+ #
172
+ # === Note
173
+ #
174
+ # Role filters call the filter_logged_in and filter_in_user_table filters.
175
+ #
176
+ # == Helper Methods
177
+ #
178
+ # Several of the methods in this module are exposed as helper methods
179
+ # that you can use in your views (<tt>../app/views/<controller>/*.rhtml</tt>)
180
+ # and helpers (<tt>../app/helpers/<controller>_helper.rb</tt>).
181
+ #
182
+ # # in your view
183
+ #
184
+ # <% if logged_in? %>
185
+ # Logged in as: <%= "#{ldap_user.firstname} #{ldap_user.lastname}"%>
186
+ # <% end %>
187
+ #
188
+ # Or even better, used in a helper method you write:
189
+ #
190
+ # # in your view
191
+ #
192
+ # <%= logged_in_html %>
193
+ #
194
+ # # in your controller's helper
195
+ #
196
+ # def logged_in_html
197
+ # logged_in? ? "" : "Logged in as #{ldap_user.firstname} #{ldap_user.lastname}"
198
+ # end
199
+ #
200
+ # See the HELPER_METHODS constant below for a list of the methods.
201
+ #
202
+ module ControllerMethods
203
+
204
+ # These methods are available has helpers in your views and helpers.
205
+ HELPER_METHODS = [
206
+ :in_user_table?,
207
+ :ldap_user,
208
+ :logged_in,
209
+ :role_names,
210
+ :roles,
211
+ :ldap_uid,
212
+ :user_table_user,
213
+ :user_table_id,
214
+ :using_user_table?,
215
+ :logout,
216
+ ]
217
+
218
+ # Operators available for non-boolean LDAP and User filters.
219
+ OPERATOR_METHODS = {
220
+ "eq" => "==",
221
+ "ne" => "!=",
222
+ }
223
+
224
+ def not_authorized
225
+ render :text => "Not Authorized", :status => 401
226
+ end
227
+
228
+ # Logs user out of application
229
+ def logout
230
+ application_logout
231
+ protocol = request.ssl? ? 'https://' : 'http://'
232
+ url = UCB::Rails::Security::CASAuthentication.home_url
233
+ logout_url = UCB::Rails::Security::CASAuthentication.logout_url
234
+ redirect_to("#{logout_url}?url=#{protocol}#{request.host_with_port}/#{url}")
235
+ end
236
+
237
+ private unless $TESTING
238
+
239
+ def application_logout()
240
+ [ :cas_user, :ldap_user, :user_table_id, :casfilterpgt,
241
+ :casfilterreceipt, :caslastticket, :casfiltergateway ].each{ |k| session[k] = nil }
242
+ end
243
+
244
+ # CAS authentication before_filter. Use this filter to ensure
245
+ # users have logged in, i.e. authenticated with CAS.
246
+ def filter_logged_in() #:doc:
247
+ _logger.debug("In filter_logged_in")
248
+ if logged_in?
249
+ _logger.debug("\tlogged_in? returned true")
250
+ return true
251
+ elsif !UCB::Rails::Security::CASAuthentication.filter(self)
252
+ _logger.debug("\tUCB::Rails::Security::CASAuthentication.filter returned false")
253
+ return false
254
+ end
255
+ application_login
256
+ true
257
+ end
258
+
259
+ # Logs ldap_uid into application.
260
+ #
261
+ # * get LDAP entry (available via ActionController::Base#ldap_user)
262
+ # * check for user in User table (if using_user_table?)
263
+ # * update User table columns with LDAP values
264
+ #
265
+ # This happens upon successful CAS authentication. You can login
266
+ # a particular user to your application by calling this method
267
+ # with the corresponding ldap_uid.
268
+ def application_login(ldap_uid=ldap_uid) #:doc:
269
+ _logger.debug("In application_login")
270
+ UCB::LDAP::Person.include_test_entries = UCB::Rails::Security::CASAuthentication.allow_test_entries?
271
+ _logger.debug("\tLDAP test entries will #{UCB::LDAP::Person.include_test_entries? || "NOT"} be included")
272
+ _logger.debug("Looking for authenticated user in LDAP: #{ldap_uid}")
273
+ self.ldap_user = UCB::LDAP::Person.find_by_uid(ldap_uid)
274
+ if ldap_user().nil?
275
+ _logger.debug("Unable to find user in LDAP.")
276
+ redirect_to(not_authorized_url())
277
+ return false
278
+ end
279
+ _logger.debug("Found user in LDAP.")
280
+ look_for_user_in_user_table(ldap_uid) if using_user_table?
281
+ end
282
+
283
+ # Check if user is in user table. If found, update columns
284
+ # with LDAP attributes of same name.
285
+ def look_for_user_in_user_table(ldap_uid)
286
+ _logger.debug("Looking for user in user table.")
287
+ if ar_user = User.find_by_ldap_uid(ldap_uid)
288
+ _logger.debug("Found user.")
289
+ self.user_table_id = ar_user.id
290
+ update_user_table(ldap_user, ar_user)
291
+ return true
292
+ else
293
+ _logger.debug("User NOT found.")
294
+ end
295
+ end
296
+
297
+ # Update User table entry with values from UCB::LDAP::Person instance.
298
+ # This happens automatically when a user logs in and is found in
299
+ # the User table.
300
+ #
301
+ # Applications can call this to update user table entries with
302
+ # (presumably more current) LDAP information. Each column name that
303
+ # has a corresponding LDAP attribute or alias will be updated.
304
+ def update_user_table(ldap_user, ar_user) #:doc:
305
+ _logger.debug("Updating users attributes to match LDAP.")
306
+ User.content_columns.each do |col|
307
+ begin
308
+ ar_user.send("#{col.name}=", ldap_user.send(col.name.to_sym) )
309
+ rescue NoMethodError
310
+ # It's okay. Don't have LDAP attribute for given column.
311
+ end
312
+ end
313
+ ar_user.save
314
+ end
315
+
316
+ # Returns +true+ if using a User table.
317
+ # Gets value from UCB::Rails::Security::using_user_table?.
318
+ def using_user_table?() #:doc:
319
+ UCB::Rails::Security::using_user_table?
320
+ end
321
+
322
+ # Returns LDAP_UID of logged in user
323
+ def ldap_uid() #:doc:
324
+ session[:cas_user]
325
+ end
326
+
327
+ # Returns UCB::LDAP::Person instance of logged in user.
328
+ def ldap_user() #:doc:
329
+ session[:ldap_user]
330
+ end
331
+
332
+ # Returns +id+ column from User table for logged in user.
333
+ def user_table_id() #:doc:
334
+ session[:user_table_id]
335
+ end
336
+
337
+ # Returns the User table instance for the logged in user.
338
+ def user_table_user() #:doc:
339
+ user_table_id && (@user_table_user ||= User.find(user_table_id))
340
+ end
341
+
342
+ # Returns +true+ if user is logged in. Does <b>not</b>
343
+ # attempt to authenticate.
344
+ def logged_in?() #:doc:
345
+ ldap_user ? true : false
346
+ end
347
+
348
+ # Returns +true+ if user is logged in and was found in User table.
349
+ # At authentication time. Does <b>not</b> attempt to find user.
350
+ def in_user_table?() #:doc:
351
+ user_table_id ? true : false
352
+ end
353
+
354
+ # Setter for ldap_user.
355
+ def ldap_user=(ldap_user)
356
+ session[:ldap_user] = ldap_user
357
+ end
358
+
359
+ # Setter for user_table_id.
360
+ def user_table_id=(user_table_id)
361
+ session[:user_table_id] = user_table_id
362
+ end
363
+
364
+ # Setter for user_table_user.
365
+ def user_table_user=(user_table_instance)
366
+ @user_table_user = user_table_instance
367
+ end
368
+
369
+ # Dynamic filter implementation.
370
+ def method_missing(method, *args)
371
+ return super unless method.to_s =~ /^filter_(ldap|user|role)_(.+)$/
372
+
373
+ _logger.debug("#{method} dispatched to method_missing()")
374
+
375
+ _logger.debug("before filter_logged_in")
376
+ filter_logged_in or return false
377
+ _logger.debug("after filter_logged_in")
378
+
379
+ _logger.debug("Beginning Authorization")
380
+ return true if case
381
+ when $1 == "ldap": filter_ldap($2)
382
+ when $1 == "user": filter_user($2)
383
+ when $1 == "role": filter_role($2)
384
+ end
385
+
386
+ redirect_to(not_authorized_url)
387
+ _logger.debug("Authorization Failed")
388
+ return false
389
+ end
390
+
391
+ # Processes LDAP filters.
392
+ def filter_ldap(method)
393
+ _logger.debug("In filter_ldap(): processing LDAP based authorization filters")
394
+ (method =~ /(.+)__(.+)__(.+)/) ? filter_extended(ldap_user.send($1), $2, $3) : ldap_boolean(ldap_user.send(method))
395
+ end
396
+
397
+ # Implements a special definition of truth for the purposes
398
+ # of the ldap filters. Empty strings, empty arrays,
399
+ # and arrays that only have nil/empty elements are all false.
400
+ def ldap_boolean(ldap_attribute_value)
401
+ ( ldap_attribute_value && ("#{ldap_attribute_value}".strip != '') ) ? true : false
402
+ end
403
+
404
+ # +eval+ a boolean expression
405
+ def filter_extended(left, operator, right)
406
+ return eval("'#{left}' #{OPERATOR_METHODS[operator]} '#{right}'")
407
+ end
408
+
409
+ # Returns +true+ if user in user table. If not logged in, user
410
+ # is redirected to CAS authentication.
411
+ def filter_in_user_table() #:doc:
412
+ filter_logged_in or return false
413
+ user_table_id ? true : false
414
+ end
415
+
416
+ # Prcoess User-based filters
417
+ def filter_user(method)
418
+ _logger.debug("In filter_user(): processing user based authorization filters")
419
+ unless UCB::Rails::Security.using_user_table?
420
+ _logger.debug("User table not enabled.")
421
+ raise(Exception, "You must enable the user table to use user based filters")
422
+ return false
423
+ end
424
+ filter_in_user_table or return false
425
+ return filter_extended(user_table_user.send($1), $2, $3) if method =~ /(.+)__(.+)__(.+)/
426
+ user_table_user.send(method)
427
+ end
428
+
429
+ # Process Role-based filters
430
+ def filter_role(method)
431
+ _logger.debug("In filter_role(): processing role based authorization filters")
432
+ unless UCB::Rails::Security.using_user_table?
433
+ _logger.debug("User table not enabled.")
434
+ raise(Exception, "You must enable the user table to use role based filters")
435
+ return false
436
+ end
437
+ filter_in_user_table or return false
438
+ return roles_has_one_of($1) if method =~ /^has_one_of_(.+)$/
439
+ return roles_has_all_of($1) if method =~ /^has_all_of_(.+)$/
440
+ role_names.include?(method.downcase)
441
+ end
442
+
443
+ # Returns +true+ if user has one of specified roles.
444
+ #
445
+ # Called like:
446
+ #
447
+ # before_filter filter_role_has_one_of_role1_or_role2_or_role3
448
+ #
449
+ def roles_has_one_of(roles_string)
450
+ (roles_array(roles_string) & role_names).size > 0
451
+ end
452
+
453
+ # Returns +true+ if user has all specified roles.
454
+ #
455
+ # Called like:
456
+ #
457
+ # before_filter filter_role_has_all_of_role1_and_role2_and_role3
458
+ #
459
+ def roles_has_all_of(roles_string)
460
+ (roles_array(roles_string) - role_names).size == 0
461
+ end
462
+
463
+ # Parse role string.
464
+ def roles_array(roles_string)
465
+ roles_string.downcase.split(/_and_|_or_/)
466
+ end
467
+
468
+ # Returns +Array+ of +Role+ for logged in user.
469
+ def roles() #:doc:
470
+ user_table_user && user_table_user.roles
471
+ end
472
+
473
+ # Returns +Array+ of user's role names, lowercased. Returns
474
+ # +nil+ if user is not in user table (or not logged in).
475
+ def role_names() #:doc:
476
+ roles && roles.map{|r| r.name.downcase}
477
+ end
478
+
479
+ # Returns url where user is redirected upon failed authorization.
480
+ def not_authorized_url() #:doc:
481
+ UCB::Rails::Security.not_authorized_url
482
+ end
483
+
484
+ # Add HELPER_METHODS to controller classes including this module.
485
+ def self.included(base)
486
+ base.send(:helper_method, HELPER_METHODS)
487
+ end
488
+
489
+ def _logger
490
+ UCB::Rails::Security.logger
491
+ end
492
+
493
+ end
494
+ end
495
+ end
496
+ end
@@ -0,0 +1,9 @@
1
+
2
+ You also neet to <tt>include<tt> UCB::Rails::Security::ControllerMethods</tt>
3
+ in your controller class. This can be done in each controller, but should probably be done in <tt>application.rb</tt>:
4
+
5
+ # ../app/controllers/application.rb
6
+
7
+ class ApplicationController < ActionController::Base
8
+ include UCB::Rails::Security::ControllerMethods
9
+ end
@@ -0,0 +1,5 @@
1
+ # Run unit tests in files ending in "*_spec.rb".
2
+ test_dir = File.dirname(__FILE__)
3
+ Dir["#{test_dir}/*_spec.rb"].each do |file|
4
+ require file
5
+ end
data/rspec/_setup.rb ADDED
@@ -0,0 +1,36 @@
1
+ $TESTING = true
2
+
3
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
4
+ require "ucb_rails_security"
5
+
6
+ # Swallow logger calls during testing
7
+ module Mock
8
+ class Logger
9
+ def debug(msg); end
10
+ def info(msg); end
11
+ end
12
+ end
13
+ UCB::Rails::Security.logger = Mock::Logger.new
14
+
15
+ def reset_cas_authentication_class()
16
+ ca = UCB::Rails::Security::CASAuthentication
17
+ ca.reset_instance_variables()
18
+ ca
19
+ end
20
+
21
+ # Mixin like a Rails application will
22
+ module ActionController
23
+ class Base
24
+ include UCB::Rails::Security::ControllerMethods
25
+ end
26
+ end
27
+
28
+ # Return new ActionController::Base
29
+ def new_controller
30
+ c = ActionController::Base.new
31
+ c.session = {}
32
+ c
33
+ end
34
+
35
+ class User
36
+ end
@@ -0,0 +1,87 @@
1
+ require "#{File.dirname(__FILE__)}/_setup.rb"
2
+
3
+ context "For an LDAP attribute" do
4
+ setup do
5
+ @controller = new_controller()
6
+ end
7
+
8
+ specify "true is true" do
9
+ @controller.ldap_boolean(true).should be_true
10
+ end
11
+
12
+ specify "a string is true" do
13
+ @controller.ldap_boolean("x").should be_true
14
+ end
15
+
16
+ specify "a number, including 0, is true" do
17
+ @controller.ldap_boolean(0).should be_true
18
+ end
19
+
20
+ specify "a populated Array is true" do
21
+ @controller.ldap_boolean(["x"]).should be_true
22
+ end
23
+
24
+ specify "false is false" do
25
+ @controller.ldap_boolean(false).should be_false
26
+ end
27
+ specify "nil is false" do
28
+ @controller.ldap_boolean(nil).should be_false
29
+ end
30
+ specify "' ' is false" do
31
+ @controller.ldap_boolean(' ').should be_false
32
+ end
33
+ specify "[] is false" do
34
+ @controller.ldap_boolean([]).should be_false
35
+ end
36
+ end
37
+
38
+ context "When a user is not logged in to the application" do
39
+ setup do
40
+ @controller = new_controller()
41
+ @controller.should_receive(:filter_logged_in)
42
+ end
43
+
44
+ specify "call to ldap_filter should call filter_logged_in" do
45
+ @controller.filter_ldap_anthing
46
+ end
47
+ end
48
+
49
+ context "When a user is logged in to the application" do
50
+ before(:all) do
51
+ RAILS_ENV = "re"
52
+ end
53
+
54
+ setup do
55
+ @ldap_uid = '42'
56
+ @ldap_user = mock("ldap_user")
57
+ UCB::LDAP::Person.stub!(:find_by_uid).and_return(@ldap_user)
58
+ User.stub!(:find_by_ldap_uid)
59
+ @controller = new_controller()
60
+ @controller.application_login(@uid)
61
+ @controller.stub!(:redirect_to)
62
+ @controller.stub!(:not_authorized_url).and_return("nal")
63
+ end
64
+
65
+ specify "filter_ldap_method returns 'true' when ldap.method does" do
66
+ @ldap_user.stub!(:attr_true).and_return(true)
67
+ @controller.filter_ldap_attr_true.should be_true
68
+ end
69
+
70
+ specify "filter_ldap_method returns 'false' when ldap.method does" do
71
+ @ldap_user.stub!(:attr_false).and_return(false)
72
+ @controller.filter_ldap_attr_false.should be_false
73
+ end
74
+
75
+ specify "filter_ldap_method__eq__value is true if ldap.method eq 'value'" do
76
+ @ldap_user.stub!(:attr).and_return("a")
77
+ @controller.filter_ldap_attr__eq__a.should be_true
78
+ @controller.filter_ldap_attr__eq__b.should be_false
79
+ end
80
+
81
+ specify "filter_ldap_method__ne__value is true if ldap.method ne 'value'" do
82
+ @ldap_user.stub!(:attr).and_return("a")
83
+ @controller.filter_ldap_attr__ne__b.should be_true
84
+ @controller.filter_ldap_attr__ne__a.should be_false
85
+ end
86
+
87
+ end
@@ -0,0 +1,56 @@
1
+ require "#{File.dirname(__FILE__)}/_setup.rb"
2
+
3
+ context "The Role filter" do
4
+ setup do
5
+ @controller = new_controller()
6
+ UCB::Rails::Security.using_user_table = true
7
+ end
8
+
9
+ specify "should call filter_logged_in when user not logged in" do
10
+ @controller.should_receive(:filter_logged_in).and_return(false)
11
+ @controller.filter_role_foo.should be_false
12
+ end
13
+
14
+ specify "should call filter_in_user_table() when user logged in" do
15
+ @controller.stub!(:filter_logged_in).and_return(true)
16
+ @controller.should_receive(:filter_in_user_table).and_return(false)
17
+ @controller.stub!(:redirect_to)
18
+ @controller.stub!(:not_authorized_url).and_return("nal")
19
+ @controller.filter_role_foo.should be_false
20
+ end
21
+ end
22
+
23
+ describe "Role filters" do
24
+ before(:each) do
25
+ @controller = new_controller()
26
+ @controller.stub!(:role_names).and_return(%w{role1 role2 role3})
27
+ @controller.stub!(:filter_logged_in).and_return(true)
28
+ @controller.stub!(:filter_in_user_table).and_return(true)
29
+ @controller.stub!(:redirect_to)
30
+ @controller.stub!(:not_authorized_url).and_return("nal")
31
+ end
32
+
33
+ it "filter_role_rolename should return true if one of user's roles is 'rolename'" do
34
+ @controller.filter_role_role1.should be_true
35
+ end
36
+
37
+ it "filter_role_rolename should return false unless one of user's roles is 'rolename'" do
38
+ @controller.filter_role_bogus.should_not be_true
39
+ end
40
+
41
+ it "filter_role_has_one_of_r1_or_r2_or_r3 returns true if user has one of the roles" do
42
+ @controller.filter_role_has_one_of_role3_or_role4.should be_true
43
+ end
44
+
45
+ it "filter_role_has_one_of_r1_or_r2_or_r3 returns false unless user has one of the roles" do
46
+ @controller.filter_role_has_one_of_role4_or_role5.should be_false
47
+ end
48
+
49
+ it "filter_role_has_all_of_r1_and_r2_and_r3 returns true if user has all of the roles" do
50
+ @controller.filter_role_has_all_of_role1_and_role2.should be_true
51
+ end
52
+
53
+ it "filter_role_has_one_of_r1_and_r2_and_r3 returns false unless user has one of the roles" do
54
+ @controller.filter_role_has_all_of_role3_and_role4.should be_false
55
+ end
56
+ end