crowd-stefanwille 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/History.txt +37 -0
- data/README.rdoc +122 -0
- data/Rakefile +44 -0
- data/demo/crowd_demo.rb +24 -0
- data/lib/crowd/http/request.rb +6 -0
- data/lib/crowd/http/response.rb +5 -0
- data/lib/crowd/http/sso.rb +101 -0
- data/lib/crowd/soap/SecurityServerClient.rb +844 -0
- data/lib/crowd/soap/crowd-2.0.5.wsdl +3158 -0
- data/lib/crowd/soap/default.rb +1525 -0
- data/lib/crowd/soap/driver.rb +423 -0
- data/lib/crowd/soap/mapping_registry.rb +1614 -0
- data/lib/crowd/version.rb +9 -0
- data/lib/crowd.rb +669 -0
- data/spec/crowd_spec.rb +149 -0
- data/stefanwille-crowd.gemspec +62 -0
- metadata +112 -0
data/lib/crowd.rb
ADDED
@@ -0,0 +1,669 @@
|
|
1
|
+
#
|
2
|
+
# Updated by Stefan Wille, post@stefanwille.com on 2010-07-13
|
3
|
+
# Updated by Evgeny Zislis, evgeny.zislis@gmail.con on 2008-05-15
|
4
|
+
# Created by Jason Rimmer, jrimmer@irth.net on 2007-10-16.
|
5
|
+
# I hereby place this work that I have authored into the public domain
|
6
|
+
# and in the process abandon all copyright protection.
|
7
|
+
#
|
8
|
+
require 'sha1'
|
9
|
+
require 'base64'
|
10
|
+
require 'rubygems'
|
11
|
+
gem 'soap4r'
|
12
|
+
|
13
|
+
require File.join(File.dirname(__FILE__), 'crowd', 'version')
|
14
|
+
require File.join(File.dirname(__FILE__), 'crowd', 'soap', 'driver.rb')
|
15
|
+
|
16
|
+
#
|
17
|
+
# Place 'server.wiredump_dev = STDERR' after any to see
|
18
|
+
# the raw SOAP calls and responses in a test console
|
19
|
+
#
|
20
|
+
|
21
|
+
# public static final String USERNAME = "username";
|
22
|
+
# public static final String FIRSTNAME = "givenName";
|
23
|
+
# public static final String LASTNAME = "sn";
|
24
|
+
# public static final String DISPLAYNAME = "displayName";
|
25
|
+
# public static final String EMAIL = "mail";
|
26
|
+
# public static final String ICON_LOCATION = "iconLocation";
|
27
|
+
# public static final String PASSWORD_LASTCHANGED = "passwordLastChanged";
|
28
|
+
# public static final String LAST_AUTHENTICATED = "lastAuthenticated";
|
29
|
+
# public static final String INVALID_PASSWORD_ATTEMPTS = "invalidPasswordAttempts";
|
30
|
+
# public static final String REQUIRES_PASSWORD_CHANGE = "requiresPasswordChange";
|
31
|
+
# public static final String ACTIVE = "active";
|
32
|
+
#
|
33
|
+
|
34
|
+
class Crowd
|
35
|
+
|
36
|
+
#
|
37
|
+
# shortcircuit Crowd::SOAP
|
38
|
+
#
|
39
|
+
include SOAP
|
40
|
+
|
41
|
+
#
|
42
|
+
# Class variables
|
43
|
+
#
|
44
|
+
private
|
45
|
+
|
46
|
+
@@application_token = nil
|
47
|
+
@@crowd_app_name = nil
|
48
|
+
@@crowd_app_pword = nil
|
49
|
+
|
50
|
+
public
|
51
|
+
|
52
|
+
@@crowd_url = nil
|
53
|
+
|
54
|
+
def self.crowd_url=(value); @@crowd_url = value; end
|
55
|
+
def self.crowd_app_name=(value); @@crowd_app_name = value; end
|
56
|
+
def self.crowd_app_pword=(value); @@crowd_app_pword = value; end
|
57
|
+
|
58
|
+
|
59
|
+
# for testing
|
60
|
+
def self.crowd_url; @@crowd_url; end
|
61
|
+
def self.crowd_app_name; @@crowd_app_name; end
|
62
|
+
def self.crowd_app_pword; @@crowd_app_pword; end
|
63
|
+
def self.application_token; @@application_token; end
|
64
|
+
|
65
|
+
public
|
66
|
+
|
67
|
+
#
|
68
|
+
# Exceptions
|
69
|
+
#
|
70
|
+
class AuthenticationException < StandardError; end
|
71
|
+
class AuthenticationConnectionException < ::Errno::ECONNREFUSED; end
|
72
|
+
class AuthenticationInvalidCredentialException < AuthenticationException; end
|
73
|
+
class AuthenticationInvalidException < AuthenticationException; end
|
74
|
+
class AuthenticationObjectNotFoundException < AuthenticationException; end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Public methods
|
78
|
+
#
|
79
|
+
|
80
|
+
##
|
81
|
+
# Authenticates an application client to the Crowd security server.
|
82
|
+
def self.authenticate_application(validation_factors = {})
|
83
|
+
pword = PasswordCredential.new(@@crowd_app_pword, false)
|
84
|
+
aovf = helper_validation_factors(validation_factors)
|
85
|
+
ctx = ApplicationAuthenticationContext.new(pword, @@crowd_app_name, aovf)
|
86
|
+
arg = AuthenticateApplication.new(ctx)
|
87
|
+
begin
|
88
|
+
response = server.authenticateApplication(arg)
|
89
|
+
rescue Errno::ECONNREFUSED => e
|
90
|
+
raise AuthenticationConnectionException, e
|
91
|
+
end
|
92
|
+
@@application_token = response.out
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Authenticates a principal verses the calling who is in the application's assigned directory.
|
97
|
+
#
|
98
|
+
# To use SSO, set:
|
99
|
+
# validation_factors = { 'USER_AGENT' => '...', 'REMOTE_ADDRESS' => '...' }
|
100
|
+
# for proxy users { 'X_FORWARDED_FOR" => '...' } might be useful as well.
|
101
|
+
def self.authenticate_principal(username, password, validation_factors = {})
|
102
|
+
response = authenticated_connection do
|
103
|
+
pword = PasswordCredential.new(password, false)
|
104
|
+
aovf = helper_validation_factors(validation_factors)
|
105
|
+
ctx = UserAuthenticationContext.new(@@application_token.name, pword, username, aovf)
|
106
|
+
arg = AuthenticatePrincipal.new(@@application_token, ctx)
|
107
|
+
|
108
|
+
server.authenticatePrincipal(arg)
|
109
|
+
end
|
110
|
+
|
111
|
+
#evaluate the response. ideally, the authenticatePrincipal call should
|
112
|
+
#return an AuthenticationInvalidCredentialException and we can handle it more
|
113
|
+
#nicely below.
|
114
|
+
case response
|
115
|
+
when AuthenticatePrincipalResponse
|
116
|
+
return response.out
|
117
|
+
when InvalidAuthenticationException
|
118
|
+
return nil
|
119
|
+
when InactiveAccountException
|
120
|
+
return nil
|
121
|
+
when nil #no reponse
|
122
|
+
raise AuthenticationInvalidCredentialException, response
|
123
|
+
when ::AuthenticationException
|
124
|
+
raise AuthenticationInvalidCredentialException, response
|
125
|
+
else
|
126
|
+
raise AuthenticationException, response
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
##
|
132
|
+
# Authenticates a principal without validating a password.
|
133
|
+
def self.create_principal_token(username, validation_factors = {})
|
134
|
+
response = authenticated_connection do
|
135
|
+
aovf = helper_validation_factors(validation_factors)
|
136
|
+
arg = CreatePrincipalToken.new(@@application_token, username, aovf)
|
137
|
+
server.createPrincipalToken(arg)
|
138
|
+
end
|
139
|
+
response.out
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# Checks if the principal's current token is still valid.
|
144
|
+
def self.is_valid_principal_token?(principal_token, validation_factors = {})
|
145
|
+
response = authenticated_connection do
|
146
|
+
aovf = ArrayOfValidationFactor.new
|
147
|
+
validation_factors.each { |name,value| aovf << ValidationFactor.new(name, value)}
|
148
|
+
arg = IsValidPrincipalToken.new(@@application_token, principal_token, aovf)
|
149
|
+
server.isValidPrincipalToken(arg)
|
150
|
+
end
|
151
|
+
|
152
|
+
case response
|
153
|
+
when IsValidPrincipalTokenResponse
|
154
|
+
return response.out
|
155
|
+
else
|
156
|
+
raise AuthenticationException, response
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Add Principal
|
162
|
+
def self.add_principal(username, password, description, is_active, attributes)
|
163
|
+
response = authenticated_connection do
|
164
|
+
|
165
|
+
attrs = ArrayOfSOAPAttribute.new()
|
166
|
+
attributes.each do |key, val|
|
167
|
+
if (val.class == Array)
|
168
|
+
attrVal = ArrayOfString.new(val)
|
169
|
+
else
|
170
|
+
attrVal = ArrayOfString.new
|
171
|
+
attrVal << val
|
172
|
+
end
|
173
|
+
attrs << SOAPAttribute.new(key, attrVal)
|
174
|
+
end
|
175
|
+
|
176
|
+
principal = SOAPPrincipal.new(nil, is_active, attrs, nil, description, nil, nil, username)
|
177
|
+
pword = PasswordCredential.new(password, false)
|
178
|
+
arg = AddPrincipal.new(@@application_token, principal, pword)
|
179
|
+
|
180
|
+
server.addPrincipal(arg)
|
181
|
+
end
|
182
|
+
|
183
|
+
case response
|
184
|
+
when AddPrincipalResponse
|
185
|
+
return true
|
186
|
+
when InvalidCredentialException
|
187
|
+
raise AuthenticationInvalidCredentalException
|
188
|
+
when InvalidUserException
|
189
|
+
raise AuthenticationInvalidException, response
|
190
|
+
else
|
191
|
+
raise AuthenticationException, response
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
##
|
196
|
+
# Find Principal via username
|
197
|
+
def self.find_principal_by_username(username)
|
198
|
+
response = authenticated_connection do
|
199
|
+
arg = FindPrincipalByName.new(@@application_token, username)
|
200
|
+
server.findPrincipalByName(arg)
|
201
|
+
end
|
202
|
+
|
203
|
+
case response
|
204
|
+
when FindPrincipalByNameResponse
|
205
|
+
return parse_principal(response.out)
|
206
|
+
when ObjectNotFoundException
|
207
|
+
return nil
|
208
|
+
else
|
209
|
+
raise AuthenticationException, response
|
210
|
+
end
|
211
|
+
rescue AuthenticationException => e
|
212
|
+
raise AuthenticationObjectNotFoundException, e
|
213
|
+
end
|
214
|
+
|
215
|
+
##
|
216
|
+
# Find Principal via token
|
217
|
+
def self.find_principal_by_token(token)
|
218
|
+
response = authenticated_connection do
|
219
|
+
arg = FindPrincipalByToken.new(@@application_token, token)
|
220
|
+
server.findPrincipalByToken(arg)
|
221
|
+
end
|
222
|
+
case response
|
223
|
+
when FindPrincipalByTokenResponse
|
224
|
+
return parse_principal(response.out)
|
225
|
+
when ObjectNotFoundException
|
226
|
+
return nil
|
227
|
+
else
|
228
|
+
raise AuthenticationException, response
|
229
|
+
end
|
230
|
+
rescue AuthenticationObjectNotFoundException
|
231
|
+
return nil
|
232
|
+
rescue AuthenticationException => e
|
233
|
+
nil
|
234
|
+
rescue ::SOAP::FaultError => e
|
235
|
+
raise AuthenticationException, e.message
|
236
|
+
end
|
237
|
+
|
238
|
+
##
|
239
|
+
# Invalidate Principal Token
|
240
|
+
def self.invalidate_principal_token(token)
|
241
|
+
response = authenticated_connection do
|
242
|
+
arg = InvalidatePrincipalToken.new(@@application_token, token)
|
243
|
+
server.invalidatePrincipalToken(arg)
|
244
|
+
end
|
245
|
+
|
246
|
+
case response
|
247
|
+
when InvalidatePrincipalTokenResponse
|
248
|
+
return true
|
249
|
+
else
|
250
|
+
raise AuthenticationException, response
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
##
|
255
|
+
# Remove principal attribute
|
256
|
+
def self.remove_attribute_principal(username, attributes)
|
257
|
+
if(attributes.class != Array)
|
258
|
+
attributes = [attributes]
|
259
|
+
end
|
260
|
+
|
261
|
+
attributes.each do |attr|
|
262
|
+
response = authenticated_connection do
|
263
|
+
arg = RemoveAttributeFromPrincipal.new(@@application_token, username, attr)
|
264
|
+
server.removeAttributeFromPrincipal(arg)
|
265
|
+
end
|
266
|
+
|
267
|
+
case response
|
268
|
+
when RemoveAttributeFromPrincipalResponse
|
269
|
+
# Burying as this means it succeeded
|
270
|
+
when ObjectNotFoundException
|
271
|
+
raise AuthenticationObjectNotFoundException
|
272
|
+
else
|
273
|
+
raise AuthenticationException, response
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
##
|
279
|
+
# Add attribute to principal
|
280
|
+
def self.add_attribute_principal(username, attributes)
|
281
|
+
attributes.each do |key, val|
|
282
|
+
response = authenticated_connection do
|
283
|
+
if(val.class == Array)
|
284
|
+
valArray = ArrayOfString.new(val)
|
285
|
+
else
|
286
|
+
valArray = ArrayOfString.new
|
287
|
+
valArray << val
|
288
|
+
end
|
289
|
+
|
290
|
+
tuple = SOAPAttribute.new(key, valArray)
|
291
|
+
arg = AddAttributeToPrincipal.new(@@application_token, username, tuple)
|
292
|
+
|
293
|
+
server.addAttributeToPrincipal(arg)
|
294
|
+
end
|
295
|
+
|
296
|
+
case response
|
297
|
+
when AddAttributeToPrincipalResponse
|
298
|
+
# Burying it because this means it was successful
|
299
|
+
when ObjectNotFoundException
|
300
|
+
raise AuthenticationObjectNotFoundException
|
301
|
+
else
|
302
|
+
raise AuthenticationException, response
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
true
|
307
|
+
end
|
308
|
+
|
309
|
+
##
|
310
|
+
# Update attribute on principal
|
311
|
+
def self.update_attribute_principal(username, attributes)
|
312
|
+
attributes.each do |key, val|
|
313
|
+
response = authenticated_connection do
|
314
|
+
if val.is_a?(Array)
|
315
|
+
valArray = ArrayOfString.new(val)
|
316
|
+
else
|
317
|
+
valArray = ArrayOfString.new
|
318
|
+
valArray << val
|
319
|
+
end
|
320
|
+
|
321
|
+
tuple = SOAPAttribute.new(key, valArray)
|
322
|
+
arg = UpdatePrincipalAttribute.new(@@application_token, username, tuple)
|
323
|
+
|
324
|
+
server.updatePrincipalAttribute(arg)
|
325
|
+
end
|
326
|
+
|
327
|
+
case response
|
328
|
+
when UpdatePrincipalAttributeResponse
|
329
|
+
# Burying as it worked
|
330
|
+
when ObjectNotFoundException
|
331
|
+
raise AuthenticationObjectNotFoundException
|
332
|
+
else
|
333
|
+
raise AuthenticationException, response
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
true
|
338
|
+
end
|
339
|
+
|
340
|
+
##
|
341
|
+
# Remove principal
|
342
|
+
def self.remove_principal(username)
|
343
|
+
response = authenticated_connection do
|
344
|
+
arg = RemovePrincipal.new(@@application_token, username)
|
345
|
+
server.removePrincipal(arg)
|
346
|
+
end
|
347
|
+
|
348
|
+
case response
|
349
|
+
when RemovePrincipalResponse
|
350
|
+
return true
|
351
|
+
when ObjectNotFoundException
|
352
|
+
raise AuthenticationObjectNotFoundException
|
353
|
+
else
|
354
|
+
raise AuthenticationException, response
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
##
|
359
|
+
# Find all principal names
|
360
|
+
def self.find_all_principal_names
|
361
|
+
response = authenticated_connection do
|
362
|
+
arg = FindAllPrincipalNames.new(@@application_token)
|
363
|
+
server.findAllPrincipalNames(arg)
|
364
|
+
end
|
365
|
+
|
366
|
+
case response
|
367
|
+
when FindAllPrincipalNamesResponse
|
368
|
+
return response.out
|
369
|
+
when ObjectNotFoundException
|
370
|
+
return {}
|
371
|
+
else
|
372
|
+
raise AuthenticationException, response
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
##
|
377
|
+
# Find all role names
|
378
|
+
def self.find_all_role_names
|
379
|
+
response = authenticated_connection do
|
380
|
+
arg = FindAllRoleNames.new(@@application_token)
|
381
|
+
server.findAllRoleNames(arg)
|
382
|
+
end
|
383
|
+
|
384
|
+
case response
|
385
|
+
when FindAllRoleNamesResponse
|
386
|
+
return response.out
|
387
|
+
when ObjectNotFoundException
|
388
|
+
return {}
|
389
|
+
else
|
390
|
+
raise AuthenticationException, response
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
##
|
395
|
+
# Add Role
|
396
|
+
def self.add_role(name, description, is_active)
|
397
|
+
response = authenticated_connection do
|
398
|
+
role = SOAPRole.new(nil, is_active, nil, nil, description, nil, nil, nil, name)
|
399
|
+
arg = AddRole.new(@@application_token, role)
|
400
|
+
server.addRole(arg)
|
401
|
+
end
|
402
|
+
|
403
|
+
case response
|
404
|
+
when AddRoleResponse
|
405
|
+
return true
|
406
|
+
when ObjectNotFoundException
|
407
|
+
return AuthenticationObjectNotFoundException
|
408
|
+
else
|
409
|
+
raise AuthenticationException, response
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
##
|
414
|
+
# Add Principal to Role
|
415
|
+
def self.add_principal_to_role(username, role)
|
416
|
+
response = authenticated_connection do
|
417
|
+
arg = AddPrincipalToRole.new(@@application_token, username, role)
|
418
|
+
#raise arg.to_yaml
|
419
|
+
server.addPrincipalToRole(arg)
|
420
|
+
end
|
421
|
+
|
422
|
+
case response
|
423
|
+
when AddPrincipalToRoleResponse
|
424
|
+
return true
|
425
|
+
when ObjectNotFoundException
|
426
|
+
return AuthenticationObjectNotFoundException
|
427
|
+
else
|
428
|
+
raise AuthenticationException, response
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
##
|
433
|
+
# Remove Principal form Role
|
434
|
+
def self.remove_principal_from_role(username, role)
|
435
|
+
response = authenticated_connection do
|
436
|
+
arg = RemovePrincipalFromRole.new(@@application_token, username, role)
|
437
|
+
server.removePrincipalFromRole(arg)
|
438
|
+
end
|
439
|
+
|
440
|
+
case response
|
441
|
+
when RemovePrincipalFromRoleResponse
|
442
|
+
return true
|
443
|
+
when ObjectNotFoundException
|
444
|
+
return AuthenticationObjectNotFoundException
|
445
|
+
else
|
446
|
+
raise AuthenticationException, response
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
##
|
451
|
+
# Is Role Member
|
452
|
+
def self.is_role_member(username, role)
|
453
|
+
response = authenticated_connection do
|
454
|
+
arg = IsRoleMember.new(@@application_token, username, role )
|
455
|
+
server.isRoleMember(arg)
|
456
|
+
end
|
457
|
+
|
458
|
+
case response
|
459
|
+
when IsRoleMemberResponse
|
460
|
+
return response.out
|
461
|
+
when ObjectNotFoundException
|
462
|
+
return AuthenticationObjectNotFoundException
|
463
|
+
else
|
464
|
+
raise AuthenticationException, response
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
|
469
|
+
|
470
|
+
##
|
471
|
+
# Remove Role
|
472
|
+
def self.remove_role(role)
|
473
|
+
response = authenticated_connection do
|
474
|
+
arg = RemoveRole.new(@@application_token, role)
|
475
|
+
server.removeRole(arg)
|
476
|
+
end
|
477
|
+
|
478
|
+
case response
|
479
|
+
when RemoveRoleResponse
|
480
|
+
return true
|
481
|
+
when ObjectNotFoundException
|
482
|
+
return AuthenticationObjectNotFoundException
|
483
|
+
else
|
484
|
+
raise AuthenticationException, response
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
##
|
489
|
+
# Is Group Member
|
490
|
+
def self.is_group_member(username, group)
|
491
|
+
response = authenticated_connection do
|
492
|
+
arg = IsGroupMember.new(@@application_token, group, username )
|
493
|
+
server.isGroupMember(arg)
|
494
|
+
end
|
495
|
+
|
496
|
+
case response
|
497
|
+
when IsGroupMemberResponse
|
498
|
+
return response.out
|
499
|
+
when ObjectNotFoundException
|
500
|
+
return AuthenticationObjectNotFoundException
|
501
|
+
else
|
502
|
+
raise AuthenticationException, response
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
def self.find_all_group_names
|
507
|
+
response = authenticated_connection do
|
508
|
+
arg = FindAllGroupNames.new(@@application_token)
|
509
|
+
server.findAllGroupNames(arg)
|
510
|
+
end
|
511
|
+
|
512
|
+
case response
|
513
|
+
when FindAllGroupNamesResponse
|
514
|
+
return response.out
|
515
|
+
when ObjectNotFoundException
|
516
|
+
return AuthenticationObjectNotFoundException
|
517
|
+
else
|
518
|
+
raise AuthenticationException, response
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
def self.find_all_groups_for_principal(username)
|
523
|
+
response = authenticated_connection do
|
524
|
+
arg = FindGroupMemberships.new(@@application_token, username)
|
525
|
+
server.findGroupMemberships(arg)
|
526
|
+
end
|
527
|
+
|
528
|
+
case response
|
529
|
+
when FindGroupMembershipsResponse
|
530
|
+
return response.out
|
531
|
+
when ObjectNotFoundException
|
532
|
+
return AuthenticationObjectNotFoundException
|
533
|
+
else
|
534
|
+
raise AuthenticationException, response
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
def self.get_group(name)
|
539
|
+
response = authenticated_connection do
|
540
|
+
arg = FindGroupByName.new(@@application_token, name)
|
541
|
+
server.findGroupByName(arg)
|
542
|
+
end
|
543
|
+
|
544
|
+
case response
|
545
|
+
when FindGroupByNameResponse
|
546
|
+
return response.out
|
547
|
+
when ObjectNotFoundException
|
548
|
+
return AuthenticationObjectNotFoundException
|
549
|
+
else
|
550
|
+
raise AuthenticationException, response
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
private
|
555
|
+
|
556
|
+
# Parse the user
|
557
|
+
def self.parse_principal(rp)
|
558
|
+
p = {}
|
559
|
+
p[:id] = rp.iD
|
560
|
+
p[:active] = rp.active
|
561
|
+
p[:conception] = rp.conception
|
562
|
+
p[:description] = rp.description
|
563
|
+
p[:directoryID] = rp.directoryId
|
564
|
+
p[:lastModified] = rp.lastModified
|
565
|
+
p[:name] = rp.name
|
566
|
+
|
567
|
+
p[:attributes] = {}
|
568
|
+
|
569
|
+
rp.attributes.each do |attr|
|
570
|
+
case attr.values.size
|
571
|
+
when 0
|
572
|
+
p[:attributes][attr.name.to_sym] = nil
|
573
|
+
when 1
|
574
|
+
p[:attributes][attr.name.to_sym] = attr.values[0]
|
575
|
+
else
|
576
|
+
p[:attributes][attr.name.to_sym] = attr.values.to_a
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
return p
|
581
|
+
end
|
582
|
+
|
583
|
+
# Create ArrayOfValidationFactor from a ruby key=>value hash
|
584
|
+
def self.helper_validation_factors(validation_factors = {})
|
585
|
+
aovf = ArrayOfValidationFactor.new
|
586
|
+
validation_factors.each { |name,value| aovf << ValidationFactor.new(name, value)}
|
587
|
+
end
|
588
|
+
|
589
|
+
# Has the application been authenticated?
|
590
|
+
def self.application_auth_check
|
591
|
+
authenticate_application if @@application_token.nil?
|
592
|
+
end
|
593
|
+
|
594
|
+
# Shorthand for getting the security server object
|
595
|
+
def self.server
|
596
|
+
@@server ||= SecurityServerPortType.new(@@crowd_url)
|
597
|
+
end
|
598
|
+
|
599
|
+
# Wrapper for catching common exceptions. Also allows the application a chance
|
600
|
+
# to re-authenticate if the token is invalid.
|
601
|
+
def self.authenticated_connection
|
602
|
+
raise ArgumentError unless block_given?
|
603
|
+
|
604
|
+
application_auth_check
|
605
|
+
|
606
|
+
response = yield
|
607
|
+
rescue AuthenticationException => e
|
608
|
+
# Push the response into the exception message
|
609
|
+
raise AuthenticationException, e
|
610
|
+
rescue Errno::ECONNREFUSED => e
|
611
|
+
raise AuthenticationConnectionException, e
|
612
|
+
rescue ::SOAP::FaultError => e
|
613
|
+
# We'll retry once more on any fault.
|
614
|
+
begin
|
615
|
+
authenticate_application
|
616
|
+
response = yield
|
617
|
+
rescue AuthenticationException => e
|
618
|
+
raise AuthenticationException, e
|
619
|
+
rescue Errno::ECONNREFUSED => e
|
620
|
+
raise AuthenticationConnectionException, e
|
621
|
+
rescue Exception => e
|
622
|
+
raise AuthenticationException, e
|
623
|
+
end
|
624
|
+
rescue Exception => e
|
625
|
+
raise AuthenticationException, e
|
626
|
+
ensure
|
627
|
+
if response.is_a?(InvalidAuthorizationTokenException)
|
628
|
+
authenticate_application
|
629
|
+
response = yield
|
630
|
+
end
|
631
|
+
response
|
632
|
+
end
|
633
|
+
|
634
|
+
##
|
635
|
+
# Returns the domain configured in Crowd or null if no domain has been set.
|
636
|
+
#
|
637
|
+
# *Deprecated:* This method has been superceded by get_cookie_config.
|
638
|
+
def self.get_domain
|
639
|
+
response = authenticated_connection do
|
640
|
+
arg = GetDomain.new(@@application_token)
|
641
|
+
server.getDomain(arg)
|
642
|
+
end
|
643
|
+
|
644
|
+
case response
|
645
|
+
when GetDomainResponse
|
646
|
+
return response.out
|
647
|
+
else
|
648
|
+
raise AuthenticationException, response
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
652
|
+
##
|
653
|
+
# Updates the password credential for a principal who is in the application's assigned directory.
|
654
|
+
def self.update_principal_credential(principal, password)
|
655
|
+
response = authenticated_connection do
|
656
|
+
hash = Digest::SHA512.new.update(password).digest
|
657
|
+
cred = PasswordCredential.new(Base64::encode64(hash).gsub(/\n/, ''))
|
658
|
+
arg = UpdatePrincipalCredential.new(@@application_token, principal, cred)
|
659
|
+
server.updatePrincipalCredential(arg)
|
660
|
+
end
|
661
|
+
|
662
|
+
case response
|
663
|
+
when UpdatePrincipalCredentialResponse
|
664
|
+
return nil
|
665
|
+
else
|
666
|
+
raise AuthenticationException, response
|
667
|
+
end
|
668
|
+
end
|
669
|
+
end
|