aker 3.0.0.pre

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