ucb_rails_security 2.0.7

Sign up to get free protection for your applications and to get access to all the features.
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