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,455 @@
1
+ require File.expand_path("../../../spec_helper", __FILE__)
2
+
3
+ require 'fileutils'
4
+
5
+ module Aker::Authorities
6
+ describe Static do
7
+ before do
8
+ @s = Static.new
9
+ end
10
+
11
+ describe "initialization" do
12
+ it "will accept an argument" do
13
+ lambda { Static.new('ignored') }.should_not raise_error
14
+ end
15
+
16
+ it "does not require an argument" do
17
+ lambda { Static.new }.should_not raise_error
18
+ end
19
+ end
20
+
21
+ describe "setting and checking credentials" do
22
+ describe ":user" do
23
+ before do
24
+ @s.valid_credentials!(:user, "jo", "50-50")
25
+ end
26
+
27
+ it "gives the user for a valid combination" do
28
+ @s.valid_credentials?(:user, "jo", "50-50").username.should == "jo"
29
+ end
30
+
31
+ it "gives nil for the wrong password" do
32
+ @s.valid_credentials?(:user, "jo", "40-60").should be_nil
33
+ end
34
+
35
+ it "gives nil for an unknown user" do
36
+ @s.valid_credentials?(:user, "joe", "50-50").should be_nil
37
+ end
38
+
39
+ describe "with duplicate passwords" do
40
+ before do
41
+ @s.valid_credentials!(:user, "joe", "50-50")
42
+ end
43
+
44
+ it "authenticates the first user" do
45
+ @s.valid_credentials?(:user, "jo", "50-50").username.should == "jo"
46
+ end
47
+
48
+ it "authenticates the second user" do
49
+ @s.valid_credentials?(:user, "joe", "50-50").username.should == "joe"
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "other kinds" do
55
+ before do
56
+ @s.valid_credentials!(:magic, "jo", "abracadabra")
57
+ end
58
+
59
+ it "gives the user for a valid key" do
60
+ @s.valid_credentials?(:magic, "abracadabra").username.should == "jo"
61
+ end
62
+
63
+ it "gives nil for an unknown key" do
64
+ @s.valid_credentials?(:magic, "shazam").should be_nil
65
+ end
66
+
67
+ it "gives nil for an unknown kind" do
68
+ @s.valid_credentials?(:radar, "abracadabra").should be_nil
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "accessing users" do
74
+ it "reuses a user added with valid_credentials!" do
75
+ @s.valid_credentials!(:user, "jo", "123")
76
+ @s.user("jo").object_id.should == @s.valid_credentials?(:user, "jo", "123").object_id
77
+ end
78
+
79
+ it "creates a user on first reference" do
80
+ @s.user("jo").username.should == "jo"
81
+ end
82
+
83
+ it "reuses user across multiple calls" do
84
+ @s.user("jo").object_id.should == @s.user("jo").object_id
85
+ end
86
+
87
+ it "yields the user to a block, if given" do
88
+ @s.user("jo") do |u|
89
+ u.first_name = "Josephine"
90
+ end
91
+
92
+ @s.user("jo").first_name.should == "Josephine"
93
+ end
94
+ end
95
+
96
+ describe "#amplify!" do
97
+ before do
98
+ @s.user("jo") do |u|
99
+ u.first_name = "Josephine"
100
+ u.last_name = "Mueller"
101
+ u.portals += [:ENU, :NOTIS]
102
+ u.group_memberships(:ENU) << Aker::GroupMembership.new(Aker::Group.new("User"))
103
+ end
104
+
105
+ @outside_jo = Aker::User.new("jo")
106
+ end
107
+
108
+ def actual
109
+ @s.amplify!(@outside_jo)
110
+ end
111
+
112
+ it "does nothing for an unknown user" do
113
+ lambda { @s.amplify!(Aker::User.new("joe")) }.should_not raise_error
114
+ end
115
+
116
+ describe "on a blank instance" do
117
+ it "copies simple attributes" do
118
+ actual.first_name.should == "Josephine"
119
+ end
120
+
121
+ it "copies portals" do
122
+ actual.portals.should == [:ENU, :NOTIS]
123
+ end
124
+
125
+ it "copies group memberships" do
126
+ actual.group_memberships(:ENU).size.should == 1
127
+ end
128
+ end
129
+
130
+ describe "for portals" do
131
+ before do
132
+ @outside_jo.portals += [:ENU, :SQLSubmit]
133
+ end
134
+
135
+ it "only includes each portal once" do
136
+ actual.portals.size.should == 3
137
+ end
138
+
139
+ it "retains portals that are in both lists" do
140
+ actual.may_access?(:ENU).should be_true
141
+ end
142
+
143
+ it "adds portals from the static authority" do
144
+ actual.may_access?(:NOTIS).should be_true
145
+ end
146
+
147
+ it "retains portals that are only in the pre-amplified user" do
148
+ actual.may_access?(:SQLSubmit).should be_true
149
+ end
150
+ end
151
+
152
+ describe "for group memberships" do
153
+ it "copies group memberships for an otherwise unknown portal" do
154
+ @outside_jo.group_memberships(:NOTIS) <<
155
+ Aker::GroupMembership.new(Aker::Group.new("Admin"))
156
+
157
+ actual.group_memberships(:ENU).size.should == 1
158
+ end
159
+
160
+ it "leaves alone group memberships for a known portal" do
161
+ @outside_jo.group_memberships(:ENU) <<
162
+ Aker::GroupMembership.new(Aker::Group.new("Developer"))
163
+
164
+ actual.group_memberships(:ENU).include?("Developer").should be_true
165
+ actual.group_memberships(:ENU).include?("User").should be_false
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "#find_users" do
171
+ before do
172
+ @s.user('alpha') do |u|
173
+ u.first_name = 'A'
174
+ u.last_name = 'Pha'
175
+ u.middle_name = 'L.'
176
+ end
177
+
178
+ @s.user('epsilon') do |u|
179
+ u.first_name = 'Epsi'
180
+ u.last_name = 'On'
181
+ u.middle_name = 'L.'
182
+ end
183
+ end
184
+
185
+ describe "with a username" do
186
+ it "returns the sole matching user" do
187
+ @s.find_users("alpha").collect(&:first_name).should == %w(A)
188
+ end
189
+
190
+ it "returns an empty list for no users" do
191
+ @s.find_users("gamma").should == []
192
+ end
193
+ end
194
+
195
+ describe "with a hash of criteria" do
196
+ it "matches on user attributes" do
197
+ @s.find_users(:middle_name => 'L.').size.should == 2
198
+ end
199
+
200
+ it "ignores unknown attributes" do
201
+ @s.find_users(:username => 'epsilon', :frob => 'yelp').size.should == 1
202
+ end
203
+
204
+ it "returns nothing if the criteria contains no known attributes" do
205
+ @s.find_users(:frob => 'hork').size.should == 0
206
+ end
207
+
208
+ it "combines attributes with AND" do
209
+ @s.find_users(:first_name => 'A', :last_name => 'Pha').size.should == 1
210
+ @s.find_users(:first_name => 'A', :last_name => 'On').size.should == 0
211
+ end
212
+ end
213
+
214
+ describe "with a list" do
215
+ describe "of usernames" do
216
+ it "returns the correct users" do
217
+ @s.find_users("epsilon", "gamma", "alpha").
218
+ collect(&:first_name).sort.should == %w(A Epsi)
219
+ end
220
+ end
221
+
222
+ describe "of criteria hashes" do
223
+ it "returns all matching users" do
224
+ @s.find_users({ :first_name => 'A' }, { :last_name => 'On' }).should have(2).users
225
+ end
226
+
227
+ it "does not include duplicates" do
228
+ @s.find_users({ :first_name => 'A' }, { :last_name => 'Pha' }).should have(1).user
229
+ end
230
+ end
231
+
232
+ describe "of both" do
233
+ it "returns the correct matches" do
234
+ @s.find_users({ :last_name => 'Pha' }, 'epsilon').collect(&:username).sort.
235
+ should == %w(alpha epsilon)
236
+ end
237
+ end
238
+ end
239
+ end
240
+
241
+ describe "#load!" do
242
+ it "does not fail with an empty yaml doc" do
243
+ lambda { @s.load!(StringIO.new("")) }.should_not raise_error
244
+ end
245
+
246
+ it "does not fail with just users" do
247
+ lambda { @s.load!(StringIO.new("users: {}")) }.should_not raise_error
248
+ end
249
+
250
+ it "does not fail with just groups" do
251
+ lambda { @s.load!(StringIO.new("groups: {}")) }.should_not raise_error
252
+ end
253
+
254
+ it "returns self" do
255
+ @s.load!(StringIO.new).object_id.should == @s.object_id
256
+ end
257
+
258
+ describe "from YAML" do
259
+ before do
260
+ @s.load!(StringIO.new(<<-YAML))
261
+ users:
262
+ jo:
263
+ password: qofhearts
264
+ first_name: "Jo"
265
+ middle_name: "Middle"
266
+ last_name: "Last"
267
+ title: "Queen"
268
+ business_phone: "(706)634-5789"
269
+ fax: "(706) 867-5309"
270
+ email: "jo@test.com"
271
+ address: "123 Fake St"
272
+ city: "Chicago"
273
+ state: "Illinois"
274
+ country: "USA"
275
+ identifiers:
276
+ personnel_id: 1
277
+ nu_employee_id: 2
278
+ portals:
279
+ - SQLSubmit
280
+ - ENU:
281
+ - User
282
+ - Developer
283
+ - NOTIS:
284
+ - Auditor
285
+ - Manager: [20, 30]
286
+ groups:
287
+ NOTIS:
288
+ - Admin:
289
+ - Manager:
290
+ - User:
291
+ - Viewer
292
+ - Auditor
293
+ YAML
294
+ end
295
+
296
+ it "associates the password" do
297
+ @s.valid_credentials?(:user, "jo", "qofhearts").should be_true
298
+ end
299
+
300
+ describe "user attributes" do
301
+ before do
302
+ @jo = @s.user("jo")
303
+ end
304
+
305
+ describe "other user attributes" do
306
+ it "includes personnel_id" do
307
+ @jo.identifiers[:personnel_id].should == 1
308
+ end
309
+
310
+ it "includes first_name" do
311
+ @jo.first_name.should == "Jo"
312
+ end
313
+
314
+ it "includes middle_name" do
315
+ @jo.middle_name.should == "Middle"
316
+ end
317
+
318
+ it "includes last_name" do
319
+ @jo.last_name.should == "Last"
320
+ end
321
+
322
+ it "includes title" do
323
+ @jo.title.should == "Queen"
324
+ end
325
+
326
+ it "includes business_phone" do
327
+ @jo.business_phone.should == "(706)634-5789"
328
+ end
329
+
330
+ it "includes fax" do
331
+ @jo.fax.should == "(706) 867-5309"
332
+ end
333
+
334
+ it "includes email" do
335
+ @jo.email.should == "jo@test.com"
336
+ end
337
+
338
+ it "includes address" do
339
+ @jo.address.should == "123 Fake St"
340
+ end
341
+
342
+ it "includes city" do
343
+ @jo.city.should == "Chicago"
344
+ end
345
+
346
+ it "includes state" do
347
+ @jo.state.should == "Illinois"
348
+ end
349
+
350
+ it "includes country" do
351
+ @jo.country.should == "USA"
352
+ end
353
+
354
+ it "includes nu_employee_id" do
355
+ @jo.identifiers[:nu_employee_id].should == 2
356
+ end
357
+ end
358
+
359
+ describe "portals" do
360
+ it "includes groupless portals" do
361
+ @jo.may_access?(:SQLSubmit).should be_true
362
+ end
363
+
364
+ it "includes portals with simple groups" do
365
+ @jo.may_access?(:ENU).should be_true
366
+ end
367
+
368
+ it "includes portals with affiliate-based groups" do
369
+ @jo.may_access?(:NOTIS).should be_true
370
+ end
371
+
372
+ it "does not include other portals" do
373
+ @jo.may_access?(:foo).should be_false
374
+ end
375
+ end
376
+
377
+ it "uses the first listed portal as the default" do
378
+ @jo.default_portal.should == :SQLSubmit
379
+ end
380
+
381
+ describe "group memberships" do
382
+ it "is empty for groupless portals" do
383
+ @jo.group_memberships(:SQLSubmit).should == []
384
+ end
385
+
386
+ it "includes direct groups for flat-grouped portals" do
387
+ @jo.group_memberships(:ENU).include?("User").should be_true
388
+ end
389
+
390
+ it "includes direct groups for hierarchically-grouped portals" do
391
+ @jo.group_memberships(:NOTIS).include?("Auditor").should be_true
392
+ end
393
+
394
+ it "includes child groups for hierarchically-grouped portals" do
395
+ @jo.group_memberships(:NOTIS).include?("User").should be_true
396
+ end
397
+
398
+ it "includes affiliate matches for affiliate-restricted groups" do
399
+ @jo.group_memberships(:NOTIS).include?("Manager", 20).should be_true
400
+ @jo.group_memberships(:NOTIS).include?("Manager", 21).should be_false
401
+ end
402
+ end
403
+ end
404
+ end
405
+ end
406
+
407
+ it "can be created from a file" do
408
+ fn = '/tmp/aker.yml'
409
+ File.open(fn, 'w') do |f|
410
+ f.write <<-YAML
411
+ users:
412
+ jo:
413
+ password: q
414
+ YAML
415
+ end
416
+ new_one = Static.from_file(fn)
417
+ FileUtils.rm fn
418
+
419
+ new_one.valid_credentials?(:user, "jo", "q").should be_true
420
+ end
421
+
422
+ describe "#clear" do
423
+ before do
424
+ @s.load!(StringIO.new(<<-YAML))
425
+ users:
426
+ jo:
427
+ password: foo
428
+ portals:
429
+ - SQLSubmit
430
+ groups:
431
+ NOTIS:
432
+ - Admin
433
+ YAML
434
+ @s.clear
435
+ end
436
+
437
+ it "clears the users" do
438
+ @s.user("jo").may_access?(:SQLSubmit).should be_false
439
+ end
440
+
441
+ it "clears the groups" do
442
+ # groups aren't otherwise exposed
443
+ @s.instance_eval { @groups }.size.should == 0
444
+ end
445
+
446
+ it "clears the credentials" do
447
+ @s.valid_credentials?(:user, "jo", "foo").should be_nil
448
+ end
449
+
450
+ it "returns self" do
451
+ @s.clear.object_id.should == @s.object_id
452
+ end
453
+ end
454
+ end
455
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path('../../../../spec_helper', __FILE__)
2
+
3
+ module Aker::Authorities::Support
4
+ describe FindSoleUser do
5
+ class UserFinder
6
+ include Aker::Authorities::Support::FindSoleUser
7
+
8
+ def initialize(expected_users)
9
+ @expected_users = expected_users
10
+ end
11
+
12
+ def find_users(criteria)
13
+ @expected_users
14
+ end
15
+ end
16
+
17
+ describe "#find_user" do
18
+ it "returns a single user if only one matches" do
19
+ UserFinder.new([ Aker::User.new('jo') ]).
20
+ find_user("jo").username.should == 'jo'
21
+ end
22
+
23
+ it "returns nil if more than one user matches" do
24
+ UserFinder.new([ Aker::User.new('a'), Aker::User.new('b') ]).
25
+ find_user(:letter => :single).should be_nil
26
+ end
27
+
28
+ it "returns nil if no users match" do
29
+ UserFinder.new([]).find_user("jo").should be_nil
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Aker
4
+ describe Authorities::Slice do
5
+ let(:configuration) { Configuration.new(:slices => [Authorities::Slice.new]) }
6
+
7
+ it "registers the static authority" do
8
+ configuration.authority_aliases[:static].should be Aker::Authorities::Static
9
+ end
10
+
11
+ it "registers the automatic_access authority" do
12
+ configuration.authority_aliases[:automatic_access].
13
+ should be Aker::Authorities::AutomaticAccess
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,106 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ module Aker::Cas
4
+ describe Authority do
5
+ let(:config) do
6
+ Aker::Configuration.new do
7
+ cas_parameters :base_url => "https://cas.example.net/cas/"
8
+ end
9
+ end
10
+
11
+ let(:authority) { Authority.new(config) }
12
+
13
+ describe "initialization" do
14
+ it "accepts a configuration" do
15
+ Authority.new(config)
16
+ end
17
+
18
+ it "requires a base URL in the configuration" do
19
+ config.parameters_for(:cas)[:base_url] = nil
20
+ lambda { authority }.should raise_error(":base_url parameter is required for CAS")
21
+ end
22
+
23
+ describe "of the client" do
24
+ it "has the right base URL" do
25
+ authority.cas_url.should == "https://cas.example.net/cas/"
26
+ end
27
+ end
28
+ end
29
+
30
+ shared_examples_for "a CAS user modifier" do
31
+ describe "user modification" do
32
+ it "initializes the user with its proxy-granting ticket" do
33
+ ticket.stub!(:pgt_iou => "PGTIOU-1foo", :pgt => "PGT-1foo")
34
+
35
+ user = authority.valid_credentials?(kind, ticket, service)
36
+
37
+ user.pgt.should == "PGT-1foo"
38
+ end
39
+
40
+ it "does not initialize the user with a proxy-granting ticket when a PGT IOU is absent" do
41
+ ticket.stub!(:pgt_iou => nil)
42
+
43
+ user = authority.valid_credentials?(kind, ticket, service)
44
+
45
+ user.pgt.should be_nil
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#valid_credentials?" do
51
+ it "doesn't support username-password" do
52
+ authority.valid_credentials?(:user, "a", "b").should == :unsupported
53
+ end
54
+
55
+ describe ":cas" do
56
+ let(:kind) { :cas }
57
+ let(:service) { "https://example.org/app" }
58
+ let(:st) { "ST-bazola" }
59
+ let(:ticket) { stub.as_null_object }
60
+
61
+ before do
62
+ authority.stub!(:service_ticket => ticket)
63
+ end
64
+
65
+ it "returns a user based on the service ticket response" do
66
+ ticket.stub!(:ok? => true, :username => "jo")
67
+
68
+ authority.valid_credentials?(:cas, st, service).username.should == "jo"
69
+ end
70
+
71
+ it "returns nil if the service ticket is invalid" do
72
+ ticket.stub!(:ok? => false)
73
+
74
+ authority.valid_credentials?(:cas, st, service).should be_nil
75
+ end
76
+
77
+ it_should_behave_like "a CAS user modifier"
78
+ end
79
+
80
+ describe ":cas_proxy" do
81
+ let(:kind) { :cas_proxy }
82
+ let(:pt) { "PT-12thththhtthhhthhttp" }
83
+ let(:service) { "https://example.org/app" }
84
+ let(:ticket) { stub.as_null_object }
85
+
86
+ before do
87
+ authority.stub!(:proxy_ticket => ticket)
88
+ end
89
+
90
+ it "returns a user based on the proxy ticket response" do
91
+ ticket.stub!(:ok? => true, :username => "jo")
92
+
93
+ authority.valid_credentials?(:cas_proxy, pt, service).username.should == "jo"
94
+ end
95
+
96
+ it "returns nil if the proxy ticket is invalid" do
97
+ ticket.stub!(:ok? => false)
98
+
99
+ authority.valid_credentials?(:cas_proxy, pt, service).should be_nil
100
+ end
101
+
102
+ it_should_behave_like "a CAS user modifier"
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,92 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ module Aker::Cas
4
+ describe ConfigurationHelper do
5
+ before do
6
+ @config = Aker::Configuration.new
7
+ @config.parameters_for(:cas)[:base_url] = "https://cas.example.org/"
8
+ @actual = Class.new do
9
+ include Aker::Cas::ConfigurationHelper
10
+
11
+ attr_reader :configuration
12
+
13
+ def initialize(config)
14
+ @configuration = config
15
+ end
16
+ end.new(@config)
17
+ end
18
+
19
+ describe "#cas_login_url" do
20
+ it "is built from the base URL" do
21
+ @actual.cas_login_url.should == "https://cas.example.org/login"
22
+ end
23
+
24
+ it "preserves application mount points" do
25
+ @config.parameters_for(:cas)[:base_url] = "https://cas.example.org/cas/"
26
+ @actual.cas_login_url.should == "https://cas.example.org/cas/login"
27
+ end
28
+
29
+ it "uses an explicit one if provided" do
30
+ @config.parameters_for(:cas)[:login_url] = "https://cas.example.org/entry-point"
31
+ @actual.cas_login_url.should == "https://cas.example.org/entry-point"
32
+ end
33
+ end
34
+
35
+ describe "#cas_logout_url" do
36
+ it "is built from the base URL" do
37
+ @actual.cas_logout_url.should == "https://cas.example.org/logout"
38
+ end
39
+
40
+ it "preserves application mount points" do
41
+ @config.parameters_for(:cas)[:base_url] = "https://cas.example.org/cas/"
42
+ @actual.cas_logout_url.should == "https://cas.example.org/cas/logout"
43
+ end
44
+
45
+ it "uses an explicit one if provided" do
46
+ @config.parameters_for(:cas)[:logout_url] = "https://cas.example.org/exit-point"
47
+ @actual.cas_logout_url.should == "https://cas.example.org/exit-point"
48
+ end
49
+ end
50
+
51
+ describe "#cas_url" do
52
+ before do
53
+ @config.parameters_for(:cas)[:cas_base_url] = "https://cas2.example.org/"
54
+ end
55
+
56
+ it "is preferentially loaded from the :base_url property" do
57
+ @actual.cas_url.should == "https://cas.example.org/"
58
+ end
59
+
60
+ it "is loaded from the :cas_base_url property if that's all that's provided" do
61
+ @config.parameters_for(:cas)[:base_url] = nil
62
+ @actual.cas_url.should == "https://cas2.example.org/"
63
+ end
64
+
65
+ it "adds a terminating / to the base URL if one isn't given" do
66
+ @config.parameters_for(:cas)[:base_url] = "https://cas2.example.org"
67
+
68
+ @actual.cas_url.should == "https://cas2.example.org/"
69
+ end
70
+
71
+ it "does not add a terminating / to the base URL if one is given" do
72
+ @config.parameters_for(:cas)[:base_url] = "https://cas2.example.org/"
73
+
74
+ @actual.cas_url.should == "https://cas2.example.org/"
75
+ end
76
+ end
77
+
78
+ describe "#proxy_callback_url" do
79
+ it "is loaded from the :proxy_callback_url property" do
80
+ @config.parameters_for(:cas)[:proxy_callback_url] = "https://cas.example.net/callback/gpgt"
81
+ @actual.proxy_callback_url.should == "https://cas.example.net/callback/gpgt"
82
+ end
83
+ end
84
+
85
+ describe "#proxy_retrieval_url" do
86
+ it "is loaded from the :proxy_retrieval_url property" do
87
+ @config.parameters_for(:cas)[:proxy_retrieval_url] = "https://cas.example.net/callback/rpgt"
88
+ @actual.proxy_retrieval_url.should == "https://cas.example.net/callback/rpgt"
89
+ end
90
+ end
91
+ end
92
+ end