aker 3.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +210 -0
- data/README.md +282 -0
- data/assets/aker/form/login.css +73 -0
- data/assets/aker/form/login.html.erb +44 -0
- data/lib/aker/authorities/automatic_access.rb +36 -0
- data/lib/aker/authorities/composite.rb +301 -0
- data/lib/aker/authorities/static.rb +283 -0
- data/lib/aker/authorities/support/find_sole_user.rb +24 -0
- data/lib/aker/authorities/support.rb +9 -0
- data/lib/aker/authorities.rb +46 -0
- data/lib/aker/cas/authority.rb +79 -0
- data/lib/aker/cas/configuration_helper.rb +85 -0
- data/lib/aker/cas/middleware/logout_responder.rb +49 -0
- data/lib/aker/cas/middleware/ticket_remover.rb +35 -0
- data/lib/aker/cas/middleware.rb +6 -0
- data/lib/aker/cas/proxy_mode.rb +108 -0
- data/lib/aker/cas/rack_proxy_callback.rb +188 -0
- data/lib/aker/cas/service_mode.rb +88 -0
- data/lib/aker/cas/service_url.rb +62 -0
- data/lib/aker/cas/user_ext.rb +64 -0
- data/lib/aker/cas.rb +31 -0
- data/lib/aker/central_parameters.rb +101 -0
- data/lib/aker/configuration.rb +534 -0
- data/lib/aker/deprecation.rb +105 -0
- data/lib/aker/form/custom_views_mode.rb +80 -0
- data/lib/aker/form/login_form_asset_provider.rb +56 -0
- data/lib/aker/form/middleware/custom_view_login_responder.rb +19 -0
- data/lib/aker/form/middleware/login_renderer.rb +72 -0
- data/lib/aker/form/middleware/login_responder.rb +71 -0
- data/lib/aker/form/middleware/logout_responder.rb +26 -0
- data/lib/aker/form/middleware.rb +10 -0
- data/lib/aker/form/mode.rb +118 -0
- data/lib/aker/form.rb +26 -0
- data/lib/aker/group.rb +67 -0
- data/lib/aker/group_membership.rb +162 -0
- data/lib/aker/ldap/authority.rb +392 -0
- data/lib/aker/ldap/user_ext.rb +19 -0
- data/lib/aker/ldap.rb +22 -0
- data/lib/aker/modes/base.rb +85 -0
- data/lib/aker/modes/http_basic.rb +100 -0
- data/lib/aker/modes/support/attempted_path.rb +22 -0
- data/lib/aker/modes/support/rfc_2617.rb +32 -0
- data/lib/aker/modes/support.rb +12 -0
- data/lib/aker/modes.rb +48 -0
- data/lib/aker/rack/authenticate.rb +37 -0
- data/lib/aker/rack/configuration_helper.rb +18 -0
- data/lib/aker/rack/default_logout_responder.rb +36 -0
- data/lib/aker/rack/environment_helper.rb +34 -0
- data/lib/aker/rack/facade.rb +102 -0
- data/lib/aker/rack/failure.rb +69 -0
- data/lib/aker/rack/logout.rb +63 -0
- data/lib/aker/rack/request_ext.rb +19 -0
- data/lib/aker/rack/session_timer.rb +95 -0
- data/lib/aker/rack/setup.rb +77 -0
- data/lib/aker/rack.rb +107 -0
- data/lib/aker/test/helpers.rb +22 -0
- data/lib/aker/test.rb +8 -0
- data/lib/aker/user.rb +231 -0
- data/lib/aker/version.rb +3 -0
- data/lib/aker.rb +51 -0
- data/spec/aker/aker-sample.yml +11 -0
- data/spec/aker/authorities/automatic_access_spec.rb +52 -0
- data/spec/aker/authorities/composite_spec.rb +488 -0
- data/spec/aker/authorities/nu-schema.jar +0 -0
- data/spec/aker/authorities/static_spec.rb +455 -0
- data/spec/aker/authorities/support/find_sole_user_spec.rb +33 -0
- data/spec/aker/authorities_spec.rb +16 -0
- data/spec/aker/cas/authority_spec.rb +106 -0
- data/spec/aker/cas/configuration_helper_spec.rb +92 -0
- data/spec/aker/cas/middleware/logout_responder_spec.rb +47 -0
- data/spec/aker/cas/middleware/ticket_remover_spec.rb +49 -0
- data/spec/aker/cas/proxy_mode_spec.rb +185 -0
- data/spec/aker/cas/rack_proxy_callback_spec.rb +190 -0
- data/spec/aker/cas/service_mode_spec.rb +122 -0
- data/spec/aker/cas/service_url_spec.rb +114 -0
- data/spec/aker/cas/user_ext_spec.rb +27 -0
- data/spec/aker/cas_spec.rb +19 -0
- data/spec/aker/central_parameters_spec.rb +44 -0
- data/spec/aker/configuration_spec.rb +465 -0
- data/spec/aker/deprecation_spec.rb +115 -0
- data/spec/aker/form/a_form_mode.rb +129 -0
- data/spec/aker/form/custom_views_mode_spec.rb +34 -0
- data/spec/aker/form/login_form_asset_provider_spec.rb +80 -0
- data/spec/aker/form/middleware/a_form_login_responder.rb +89 -0
- data/spec/aker/form/middleware/custom_view_login_responder_spec.rb +47 -0
- data/spec/aker/form/middleware/login_renderer_spec.rb +56 -0
- data/spec/aker/form/middleware/login_responder_spec.rb +34 -0
- data/spec/aker/form/middleware/logout_responder_spec.rb +55 -0
- data/spec/aker/form/mode_spec.rb +15 -0
- data/spec/aker/form_spec.rb +11 -0
- data/spec/aker/group_membership_spec.rb +208 -0
- data/spec/aker/group_spec.rb +66 -0
- data/spec/aker/ldap/authority_spec.rb +414 -0
- data/spec/aker/ldap/ldap-users.ldif +197 -0
- data/spec/aker/ldap_spec.rb +11 -0
- data/spec/aker/modes/a_aker_mode.rb +41 -0
- data/spec/aker/modes/http_basic_spec.rb +127 -0
- data/spec/aker/modes/support/attempted_path_spec.rb +32 -0
- data/spec/aker/modes_spec.rb +11 -0
- data/spec/aker/rack/authenticate_spec.rb +78 -0
- data/spec/aker/rack/default_logout_responder_spec.rb +67 -0
- data/spec/aker/rack/facade_spec.rb +154 -0
- data/spec/aker/rack/failure_spec.rb +151 -0
- data/spec/aker/rack/logout_spec.rb +63 -0
- data/spec/aker/rack/request_ext_spec.rb +29 -0
- data/spec/aker/rack/session_timer_spec.rb +134 -0
- data/spec/aker/rack/setup_spec.rb +87 -0
- data/spec/aker/rack_spec.rb +216 -0
- data/spec/aker/test/helpers_spec.rb +44 -0
- data/spec/aker/user_spec.rb +362 -0
- data/spec/aker_spec.rb +80 -0
- data/spec/deprecation_helper.rb +58 -0
- data/spec/java_helper.rb +5 -0
- data/spec/logger_helper.rb +17 -0
- data/spec/matchers.rb +31 -0
- data/spec/mock_builder.rb +25 -0
- data/spec/spec_helper.rb +52 -0
- 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
|