aker 3.0.0.pre

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 (118) hide show
  1. data/CHANGELOG.md +210 -0
  2. data/README.md +282 -0
  3. data/assets/aker/form/login.css +73 -0
  4. data/assets/aker/form/login.html.erb +44 -0
  5. data/lib/aker/authorities/automatic_access.rb +36 -0
  6. data/lib/aker/authorities/composite.rb +301 -0
  7. data/lib/aker/authorities/static.rb +283 -0
  8. data/lib/aker/authorities/support/find_sole_user.rb +24 -0
  9. data/lib/aker/authorities/support.rb +9 -0
  10. data/lib/aker/authorities.rb +46 -0
  11. data/lib/aker/cas/authority.rb +79 -0
  12. data/lib/aker/cas/configuration_helper.rb +85 -0
  13. data/lib/aker/cas/middleware/logout_responder.rb +49 -0
  14. data/lib/aker/cas/middleware/ticket_remover.rb +35 -0
  15. data/lib/aker/cas/middleware.rb +6 -0
  16. data/lib/aker/cas/proxy_mode.rb +108 -0
  17. data/lib/aker/cas/rack_proxy_callback.rb +188 -0
  18. data/lib/aker/cas/service_mode.rb +88 -0
  19. data/lib/aker/cas/service_url.rb +62 -0
  20. data/lib/aker/cas/user_ext.rb +64 -0
  21. data/lib/aker/cas.rb +31 -0
  22. data/lib/aker/central_parameters.rb +101 -0
  23. data/lib/aker/configuration.rb +534 -0
  24. data/lib/aker/deprecation.rb +105 -0
  25. data/lib/aker/form/custom_views_mode.rb +80 -0
  26. data/lib/aker/form/login_form_asset_provider.rb +56 -0
  27. data/lib/aker/form/middleware/custom_view_login_responder.rb +19 -0
  28. data/lib/aker/form/middleware/login_renderer.rb +72 -0
  29. data/lib/aker/form/middleware/login_responder.rb +71 -0
  30. data/lib/aker/form/middleware/logout_responder.rb +26 -0
  31. data/lib/aker/form/middleware.rb +10 -0
  32. data/lib/aker/form/mode.rb +118 -0
  33. data/lib/aker/form.rb +26 -0
  34. data/lib/aker/group.rb +67 -0
  35. data/lib/aker/group_membership.rb +162 -0
  36. data/lib/aker/ldap/authority.rb +392 -0
  37. data/lib/aker/ldap/user_ext.rb +19 -0
  38. data/lib/aker/ldap.rb +22 -0
  39. data/lib/aker/modes/base.rb +85 -0
  40. data/lib/aker/modes/http_basic.rb +100 -0
  41. data/lib/aker/modes/support/attempted_path.rb +22 -0
  42. data/lib/aker/modes/support/rfc_2617.rb +32 -0
  43. data/lib/aker/modes/support.rb +12 -0
  44. data/lib/aker/modes.rb +48 -0
  45. data/lib/aker/rack/authenticate.rb +37 -0
  46. data/lib/aker/rack/configuration_helper.rb +18 -0
  47. data/lib/aker/rack/default_logout_responder.rb +36 -0
  48. data/lib/aker/rack/environment_helper.rb +34 -0
  49. data/lib/aker/rack/facade.rb +102 -0
  50. data/lib/aker/rack/failure.rb +69 -0
  51. data/lib/aker/rack/logout.rb +63 -0
  52. data/lib/aker/rack/request_ext.rb +19 -0
  53. data/lib/aker/rack/session_timer.rb +95 -0
  54. data/lib/aker/rack/setup.rb +77 -0
  55. data/lib/aker/rack.rb +107 -0
  56. data/lib/aker/test/helpers.rb +22 -0
  57. data/lib/aker/test.rb +8 -0
  58. data/lib/aker/user.rb +231 -0
  59. data/lib/aker/version.rb +3 -0
  60. data/lib/aker.rb +51 -0
  61. data/spec/aker/aker-sample.yml +11 -0
  62. data/spec/aker/authorities/automatic_access_spec.rb +52 -0
  63. data/spec/aker/authorities/composite_spec.rb +488 -0
  64. data/spec/aker/authorities/nu-schema.jar +0 -0
  65. data/spec/aker/authorities/static_spec.rb +455 -0
  66. data/spec/aker/authorities/support/find_sole_user_spec.rb +33 -0
  67. data/spec/aker/authorities_spec.rb +16 -0
  68. data/spec/aker/cas/authority_spec.rb +106 -0
  69. data/spec/aker/cas/configuration_helper_spec.rb +92 -0
  70. data/spec/aker/cas/middleware/logout_responder_spec.rb +47 -0
  71. data/spec/aker/cas/middleware/ticket_remover_spec.rb +49 -0
  72. data/spec/aker/cas/proxy_mode_spec.rb +185 -0
  73. data/spec/aker/cas/rack_proxy_callback_spec.rb +190 -0
  74. data/spec/aker/cas/service_mode_spec.rb +122 -0
  75. data/spec/aker/cas/service_url_spec.rb +114 -0
  76. data/spec/aker/cas/user_ext_spec.rb +27 -0
  77. data/spec/aker/cas_spec.rb +19 -0
  78. data/spec/aker/central_parameters_spec.rb +44 -0
  79. data/spec/aker/configuration_spec.rb +465 -0
  80. data/spec/aker/deprecation_spec.rb +115 -0
  81. data/spec/aker/form/a_form_mode.rb +129 -0
  82. data/spec/aker/form/custom_views_mode_spec.rb +34 -0
  83. data/spec/aker/form/login_form_asset_provider_spec.rb +80 -0
  84. data/spec/aker/form/middleware/a_form_login_responder.rb +89 -0
  85. data/spec/aker/form/middleware/custom_view_login_responder_spec.rb +47 -0
  86. data/spec/aker/form/middleware/login_renderer_spec.rb +56 -0
  87. data/spec/aker/form/middleware/login_responder_spec.rb +34 -0
  88. data/spec/aker/form/middleware/logout_responder_spec.rb +55 -0
  89. data/spec/aker/form/mode_spec.rb +15 -0
  90. data/spec/aker/form_spec.rb +11 -0
  91. data/spec/aker/group_membership_spec.rb +208 -0
  92. data/spec/aker/group_spec.rb +66 -0
  93. data/spec/aker/ldap/authority_spec.rb +414 -0
  94. data/spec/aker/ldap/ldap-users.ldif +197 -0
  95. data/spec/aker/ldap_spec.rb +11 -0
  96. data/spec/aker/modes/a_aker_mode.rb +41 -0
  97. data/spec/aker/modes/http_basic_spec.rb +127 -0
  98. data/spec/aker/modes/support/attempted_path_spec.rb +32 -0
  99. data/spec/aker/modes_spec.rb +11 -0
  100. data/spec/aker/rack/authenticate_spec.rb +78 -0
  101. data/spec/aker/rack/default_logout_responder_spec.rb +67 -0
  102. data/spec/aker/rack/facade_spec.rb +154 -0
  103. data/spec/aker/rack/failure_spec.rb +151 -0
  104. data/spec/aker/rack/logout_spec.rb +63 -0
  105. data/spec/aker/rack/request_ext_spec.rb +29 -0
  106. data/spec/aker/rack/session_timer_spec.rb +134 -0
  107. data/spec/aker/rack/setup_spec.rb +87 -0
  108. data/spec/aker/rack_spec.rb +216 -0
  109. data/spec/aker/test/helpers_spec.rb +44 -0
  110. data/spec/aker/user_spec.rb +362 -0
  111. data/spec/aker_spec.rb +80 -0
  112. data/spec/deprecation_helper.rb +58 -0
  113. data/spec/java_helper.rb +5 -0
  114. data/spec/logger_helper.rb +17 -0
  115. data/spec/matchers.rb +31 -0
  116. data/spec/mock_builder.rb +25 -0
  117. data/spec/spec_helper.rb +52 -0
  118. metadata +265 -0
@@ -0,0 +1,488 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ module Aker::Authorities
4
+ describe Composite do
5
+ def actual(*auths, &block)
6
+ conf = Aker::Configuration.new
7
+
8
+ conf.logger = spec_logger
9
+ conf.enhance(&block) if block
10
+
11
+ Composite.new(conf).tap do |c|
12
+ c.authorities = auths unless auths.empty?
13
+ end
14
+ end
15
+
16
+ def actual_log
17
+ @log_io.string
18
+ end
19
+
20
+ before do
21
+ @user = Aker::User.new("jo")
22
+
23
+ @a = Object.new
24
+ @b = Object.new
25
+ @c = Object.new
26
+ @comp = actual(@a, @b, @c)
27
+ end
28
+
29
+ describe "initialization" do
30
+ it "accepts a configuration instance" do
31
+ lambda { Composite.new(Aker::Configuration.new) }.should_not raise_error
32
+ end
33
+ end
34
+
35
+ describe "#authorities" do
36
+ it "uses the authorities from the configuration" do
37
+ actual { authorities Object.new, Object.new }.authorities.size.should == 2
38
+ end
39
+
40
+ it "prefers directly set authorities" do
41
+ comp = actual { authorities :static }
42
+ comp.authorities = [Static.new.tap { |s| s.valid_credentials!(:user, "foo", "bar") }]
43
+
44
+ comp.authorities.size.should == 1
45
+ comp.authorities.first.valid_credentials?(:user, "foo", "bar").should be_true
46
+ end
47
+ end
48
+
49
+ describe "#valid_credentials?" do
50
+ it "fails if none of the authorities implement valid_credentials?" do
51
+ expected = /No authentication-providing authority is configured./
52
+ lambda { @comp.valid_credentials?(:magic, 'foo') }.should raise_error expected
53
+ end
54
+
55
+ def implement_on(authority, with_user)
56
+ (class << authority; self; end).class_eval do
57
+ define_method(:valid_credentials?) do |kind, *credentials|
58
+ with_user
59
+ end
60
+ end
61
+ end
62
+
63
+ it "returns the first user returned by any authority" do
64
+ implement_on(@a, nil)
65
+ implement_on(@b, Aker::User.new("b"))
66
+ implement_on(@c, Aker::User.new("c"))
67
+
68
+ @comp.valid_credentials?(:magic, "man").username.should == "b"
69
+ end
70
+
71
+ it "returns nil if none of the authorities return a user" do
72
+ implement_on(@a, nil)
73
+ implement_on(@b, :unsupported)
74
+
75
+ @comp.valid_credentials?(:magic, "man").should be_nil
76
+ end
77
+
78
+ it "returns nil if all the authorities return :unsupported" do
79
+ implement_on(@a, :unsupported)
80
+ implement_on(@b, :unsupported)
81
+
82
+ @comp.valid_credentials?(:magic, "man").should be_nil
83
+ end
84
+
85
+ it "returns false if any of the authorities returns false" do
86
+ implement_on(@a, @user)
87
+ implement_on(@b, false)
88
+
89
+ @comp.valid_credentials?(:magic, "man").should == false
90
+ end
91
+
92
+ it "returns false if any of the authorities veto" do
93
+ implement_on(@b, @user)
94
+ def @c.veto?(user); true; end
95
+
96
+ @comp.valid_credentials?(:magic, "man").should == false
97
+ end
98
+
99
+ it "amplifies the returned user" do
100
+ implement_on(@c, @user)
101
+ def @a.amplify!(user); user.identifiers[:personnel_id] = 17; user; end
102
+
103
+ @comp.valid_credentials?(:magic, "man").identifiers[:personnel_id].should == 17
104
+ end
105
+
106
+ describe "callbacks" do
107
+ describe "on_authentication_success" do
108
+ before do
109
+ args = {}
110
+ (class << @b; self; end).class_eval do
111
+ define_method(:on_authentication_success) do |user, kind, credentials, authority|
112
+ args.merge!(:user => user, :credentials => credentials,
113
+ :kind => kind, :authority => authority)
114
+ end
115
+ end
116
+ @args = args
117
+ end
118
+
119
+ describe "when successful" do
120
+ before do
121
+ implement_on(@a, @user)
122
+ @comp.valid_credentials?(:user, "jo", "pirate")
123
+ end
124
+
125
+ it "receives the right user" do
126
+ @args[:user].should == @user
127
+ end
128
+
129
+ it "receives the right kind" do
130
+ @args[:kind].should == :user
131
+ end
132
+
133
+ it "receives the right credentials" do
134
+ @args[:credentials].should == ["jo", "pirate"]
135
+ end
136
+
137
+ it "receives the right authority" do
138
+ @args[:authority].should == @a
139
+ end
140
+
141
+ it "logs an appropriate message" do
142
+ actual_log.should =~ /User "jo" was successfully authenticated by Object./
143
+ end
144
+ end
145
+
146
+ it "is not invoked on failure" do
147
+ implement_on(@c, nil)
148
+ @comp.valid_credentials?(:user, "jo", "pirate")
149
+ @args.should be_empty
150
+ end
151
+ end
152
+
153
+ describe "on_authentication_failure" do
154
+ before do
155
+ args = {}
156
+ (class << @b; self; end).class_eval do
157
+ define_method(:on_authentication_failure) do |user, kind, credentials, reason|
158
+ args.merge!(:user => user, :credentials => credentials,
159
+ :kind => kind, :reason => reason)
160
+ end
161
+ end
162
+ @args = args
163
+ end
164
+
165
+ it "is not invoked on success" do
166
+ implement_on(@b, @user)
167
+ @comp.valid_credentials?(:user, "jo", "pirate")
168
+ @args.should be_empty
169
+ end
170
+
171
+ describe "on failure" do
172
+ def validate
173
+ @comp.valid_credentials?(:user, "jo", "piraat")
174
+ end
175
+
176
+ before do
177
+ implement_on(@a, nil)
178
+ implement_on(@b, :unsupported)
179
+ validate
180
+ end
181
+
182
+ it "receives the right kind" do
183
+ @args[:kind].should == :user
184
+ end
185
+
186
+ it "receives the right credentials" do
187
+ @args[:credentials].should == ["jo", "piraat"]
188
+ end
189
+
190
+ describe "because of bad creds" do
191
+ it "receives the right message" do
192
+ @args[:reason].should == "invalid credentials"
193
+ end
194
+
195
+ it "receives no user" do
196
+ @args[:user].should be_nil
197
+ end
198
+
199
+ it "logs an appropriate message" do
200
+ actual_log.should =~ /Authentication attempt failed: invalid credentials./
201
+ end
202
+ end
203
+
204
+ describe "because the kind is not supported" do
205
+ before do
206
+ implement_on(@a, :unsupported)
207
+ validate
208
+ end
209
+
210
+ it "receives the right reason" do
211
+ @args[:reason].should == "no configured authorities support :user credentials"
212
+ end
213
+
214
+ it "receives no user" do
215
+ @args[:user].should be_nil
216
+ end
217
+
218
+ it "logs an appropriate message" do
219
+ actual_log.should =~ /Authentication attempt failed: no configured authorities support :user credentials./
220
+ end
221
+ end
222
+
223
+ describe "because of a valid_credentials? veto" do
224
+ before do
225
+ implement_on(@a, false)
226
+ implement_on(@b, @user)
227
+ implement_on(@c, false)
228
+ def @a.to_s; "A"; end
229
+ def @c.to_s; "C"; end
230
+ validate
231
+ end
232
+
233
+ it "receives the right reason" do
234
+ @args[:reason].should == "credentials vetoed by A, C"
235
+ end
236
+
237
+ it "receives the user" do
238
+ @args[:user].should == @user
239
+ end
240
+
241
+ it "logs an appropriate message" do
242
+ actual_log.should =~ /Authentication attempt by "jo" failed: credentials vetoed by A, C./
243
+ end
244
+ end
245
+
246
+ describe "because of a veto? veto" do
247
+ before do
248
+ implement_on(@c, @user)
249
+ def @a.veto?(user); true; end
250
+ def @b.veto?(user); true; end
251
+ def @a.to_s; "A"; end
252
+ def @b.to_s; "B"; end
253
+ validate
254
+ end
255
+
256
+ it "receives the right reason" do
257
+ @args[:reason].should == "user vetoed by A, B"
258
+ end
259
+
260
+ it "receives the user" do
261
+ @args[:user].should == @user
262
+ end
263
+ end
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+ describe "#veto?" do
270
+ it "returns false if none of the authorities implement veto?" do
271
+ @comp.veto?(@user).should be_false
272
+ end
273
+
274
+ it "returns false if all the implementors return falsy values" do
275
+ def @a.veto?(u); false; end
276
+ def @b.veto?(u); nil; end
277
+
278
+ @comp.veto?(@user).should be_false
279
+ end
280
+
281
+ it "returns true if one of the authorities returns true" do
282
+ def @a.veto?(u); true; end
283
+ def @b.veto?(u); false; end
284
+
285
+ @comp.veto?(@user).should be_true
286
+ end
287
+ end
288
+
289
+ describe "#on_authentication_success" do
290
+ it "doesn't cause an error if none of the authorities implement it" do
291
+ lambda { @comp.on_authentication_success(Aker::User.new("dc"), :dc, [:dc], :dc) }.
292
+ should_not raise_error
293
+ end
294
+
295
+ def implement_on(auth)
296
+ captured_args = {}
297
+ (class << auth; self; end).class_eval do
298
+ define_method(:on_authentication_success) do |user, kind, credentials, authority|
299
+ captured_args.merge!(:user => user, :credentials => credentials,
300
+ :kind => kind, :authority => authority)
301
+ end
302
+ end
303
+ captured_args
304
+ end
305
+
306
+ describe "invocation" do
307
+ before do
308
+ @a_args = implement_on(@a)
309
+ @b_args = implement_on(@b)
310
+ @comp.on_authentication_success(@user, :magic, ["frob"], @a)
311
+ end
312
+
313
+ { "A" => :@a_args, "B" => :@b_args }.each_pair do |name, arg_var|
314
+ describe "on #{name}" do
315
+ before do
316
+ @args = instance_variable_get(arg_var)
317
+ end
318
+
319
+ it "passes on the user" do
320
+ @args[:user].username.should == @user.username
321
+ end
322
+
323
+ it "passes on the credential kind" do
324
+ @args[:kind].should == :magic
325
+ end
326
+
327
+ it "passes on the credentials" do
328
+ @args[:credentials].should == ["frob"]
329
+ end
330
+
331
+ it "passes on the authority" do
332
+ @args[:authority].object_id.should == @a.object_id
333
+ end
334
+ end
335
+ end
336
+ end
337
+ end
338
+
339
+ describe "#on_authentication_failure" do
340
+ it "doesn't cause an error if none of the authorities implement it" do
341
+ lambda { @comp.on_authentication_failure(Aker::User.new("dc"), :dc, [:dc], :dc) }.
342
+ should_not raise_error
343
+ end
344
+
345
+ def implement_on(auth)
346
+ captured_args = {}
347
+ (class << auth; self; end).class_eval do
348
+ define_method(:on_authentication_failure) do |user, kind, credentials, reason|
349
+ captured_args.merge!(:user => user, :credentials => credentials,
350
+ :kind => kind, :reason => reason)
351
+ end
352
+ end
353
+ captured_args
354
+ end
355
+
356
+ describe "invocation" do
357
+ before do
358
+ @a_args = implement_on(@a)
359
+ @b_args = implement_on(@b)
360
+ @comp.on_authentication_failure(@user, :magic, ["frob"], "A said no")
361
+ end
362
+
363
+ { "A" => :@a_args, "B" => :@b_args }.each_pair do |name, arg_var|
364
+ describe "on #{name}" do
365
+ before do
366
+ @args = instance_variable_get(arg_var)
367
+ end
368
+
369
+ it "passes on the user" do
370
+ @args[:user].username.should == @user.username
371
+ end
372
+
373
+ it "passes on the credential kind" do
374
+ @args[:kind].should == :magic
375
+ end
376
+
377
+ it "passes on the credentials" do
378
+ @args[:credentials].should == ["frob"]
379
+ end
380
+
381
+ it "passes on the authority" do
382
+ @args[:reason].should == "A said no"
383
+ end
384
+ end
385
+ end
386
+ end
387
+ end
388
+
389
+ describe "#amplify!" do
390
+ it "adds the default portal from the configuration if there is one" do
391
+ actual { portal :ENU; authority :static }.amplify!(@user)
392
+ @user.default_portal.should == :ENU
393
+ end
394
+
395
+ it "does not cause an error if the configuration doesn't have a portal" do
396
+ lambda { actual(@a).amplify!(@user) }.should_not raise_error
397
+ end
398
+
399
+ it "doesn't cause an error if none of the authorities implement it" do
400
+ lambda { @comp.amplify!(@user) }.should_not raise_error
401
+ end
402
+
403
+ it "returns the same user that was passed in" do
404
+ @comp.amplify!(@user).object_id.should == @user.object_id
405
+ end
406
+
407
+ it "passes the user to all the authorities" do
408
+ def @a.amplify!(user); user.last_name = "Miller"; user; end
409
+ def @b.amplify!(user); user.first_name = "Jo"; user; end
410
+
411
+ @comp.amplify!(@user)
412
+
413
+ @user.first_name.should == "Jo"
414
+ @user.last_name.should == "Miller"
415
+ end
416
+
417
+ it "passes the user to all the authorities in order" do
418
+ def @a.amplify!(user); user.city = "Chicago" unless user.city; user; end
419
+ def @b.amplify!(user); user.city = "Evanston" unless user.city; user; end
420
+
421
+ @comp.amplify!(@user).city.should == "Chicago"
422
+ end
423
+ end
424
+
425
+ describe "#find_users" do
426
+ it "returns an empty array if none of the authorities implement find_users" do
427
+ @comp.find_users("wak").should == []
428
+ end
429
+
430
+ it "aggregates distinct users into a single response array" do
431
+ def @a.find_users(*options); [ Aker::User.new("fred") ]; end
432
+ def @c.find_users(*options); [ Aker::User.new("katherine") ]; end
433
+
434
+ @comp.find_users(:something => "foo").
435
+ collect { |u| u.username }.should == %w(fred katherine)
436
+ end
437
+
438
+ it "merges users with the same username in authority order" do
439
+ def @a.find_users(options)
440
+ [ Aker::User.new('jo').tap { |u| u.first_name = 'Jo'; u.city = 'Chicago'; },
441
+ Aker::User.new('alice') ]
442
+ end
443
+ def @b.find_users(options)
444
+ [ Aker::User.new('jo').tap { |u| u.last_name = 'Mueller'; u.city = 'Evanston'; },
445
+ Aker::User.new('betty') ]
446
+ end
447
+
448
+ actual = @comp.find_users('jo')
449
+ actual.size.should == 3
450
+ actual.collect { |u| u.username }.should == %w(jo alice betty)
451
+ actual.first.full_name.should == "Jo Mueller"
452
+ actual.first.city.should == "Chicago"
453
+ end
454
+
455
+ it "rejects nil authority responses" do
456
+ def @a.find_users(*options); [ nil ]; end
457
+ def @c.find_users(*options); nil; end
458
+
459
+ @comp.find_users(:etc => 'alia').should == []
460
+ end
461
+
462
+ it "splats the arguments given to the authorities" do
463
+ def @a.find_users(*options); @options = options; []; end
464
+ def @a.actual_options; @options; end
465
+
466
+ @comp.find_users(:email => 'baz')
467
+ @a.actual_options.should == [{ :email => 'baz' }]
468
+ end
469
+
470
+ it "amplifies found users" do
471
+ def @a.find_users(*options); [ Aker::User.new('jo') ]; end
472
+ def @a.amplify!(user); user.last_name = "Miller"; user; end
473
+ def @b.amplify!(user); user.first_name = "Jo"; user; end
474
+
475
+ actual = @comp.find_users('jo')
476
+ actual.size.should == 1
477
+ actual.first.full_name.should == "Jo Miller"
478
+ end
479
+ end
480
+
481
+ describe "#find_user" do
482
+ # behavior is tested in the module spec
483
+ it "exists" do
484
+ @comp.should respond_to(:find_user)
485
+ end
486
+ end
487
+ end
488
+ end
Binary file