keycloak 2.1.0 → 2.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd7cbf6d2db06b82251cd19d94c9753b33756a1f
4
- data.tar.gz: febd42f89d7269eac914fb92b1c003ecf62e5a7e
3
+ metadata.gz: 9a4572bcffa6438c4d2cdabf47e45ec0cf510800
4
+ data.tar.gz: 84a19a7ea5c489bd0677ad651814f2ef559e0e07
5
5
  SHA512:
6
- metadata.gz: d049e46d6b42a45f88a71e08617b0aabe15ee9af3690967f618795f84e635244e907b5c7b0e53e36d8e937351f8788836801ff56d955d2facd0b41f7efb5fac1
7
- data.tar.gz: 9dbf3762c6773581c334498d4ecaa6eaf67b5c58fc410a7f1d3b553c6065be2c27762bdabbcbfde2bd4540e5f1b05ac3598167c944ba06e3fde174af3a727256
6
+ metadata.gz: b9461cc31a94c2b3962b3a627ba6b991d3eb1df4b1cac9275e229747ab4a6f10149ae4b3b12c528739d1444fe756016be37e5f230973f442b65f803e98bfa971
7
+ data.tar.gz: 3349d5e9f62b4941516966b3f4910a114ccb7db0e8cd850ea06397bb643c157b30846a3f496dcab5ffec60a863b56d9aff3db6a89247555b0ec96b631849336c
@@ -1,14 +1,8 @@
1
1
  class InitializerGenerator < Rails::Generators::Base
2
- def create_initializer_file
3
- create_file "config/initializers/keycloak.rb" do
4
- proxy = ""
5
- generate_request_exception = true
6
- "# Set proxy to connect in keycloak server
7
- Keycloak.proxy = #{proxy}
8
- # If true, then all request exception will explode in application (this is the default value)
9
- Keycloak.generate_request_exception = #{generate_request_exception}
10
- # controller that manage the user session
11
- Keycloak.keycloak_controller = 'session'"
12
- end
13
- end
2
+ source_root(File.expand_path(File.dirname(__FILE__))
3
+
4
+ def copy_initializer
5
+ copy_file 'keycloak.rb', 'config/initializers/keycloak.rb'
6
+ end
7
+
14
8
  end
@@ -6,760 +6,797 @@ require 'base64'
6
6
  require 'uri'
7
7
 
8
8
  module Keycloak
9
+ class << self
10
+ attr_accessor :proxy, :generate_request_exception, :keycloak_controller,
11
+ :proc_cookie_token, :proc_external_attributes
12
+ end
9
13
 
10
- class << self
11
- attr_accessor :proxy, :generate_request_exception, :keycloak_controller,
12
- :proc_cookie_token, :proc_external_attributes
13
- end
14
14
 
15
+ def self.explode_exception
16
+ if Keycloak.generate_request_exception == nil
17
+ Keycloak.generate_request_exception = true
18
+ end
19
+ Keycloak.generate_request_exception
20
+ end
15
21
 
16
- def self.explode_exception
17
- if Keycloak.generate_request_exception == nil
18
- Keycloak.generate_request_exception = true
19
- end
20
- Keycloak.generate_request_exception
21
- end
22
+ module Client
23
+ class << self
24
+ attr_reader :realm, :url, :client_id, :auth_server_url,
25
+ :secret, :configuration, :public_key
26
+ end
22
27
 
23
- module Client
28
+ KEYCLOAK_JSON_FILE = 'keycloak.json'
24
29
 
25
- class << self
26
- attr_reader :realm, :url, :client_id, :auth_server_url,
27
- :secret, :configuration, :public_key
30
+ def self.get_token(user, password)
31
+ setup_module
28
32
 
29
- end
33
+ payload = { 'client_id' => @client_id,
34
+ 'client_secret' => @secret,
35
+ 'username' => user,
36
+ 'password' => password,
37
+ 'grant_type' => 'password' }
30
38
 
31
- KEYCLOAK_JSON_FILE = 'keycloak.json'
39
+ mount_request_token(payload)
40
+ end
32
41
 
33
- def self.get_token(user, password)
34
- setup_module
42
+ def self.get_token_by_code(code, redirect_uri)
43
+ verify_setup
35
44
 
36
- payload = {'client_id' => @client_id,
37
- 'client_secret' => @secret,
38
- 'username' => user,
39
- 'password' => password,
40
- 'grant_type' => 'password'
41
- }
45
+ payload = { 'client_id' => @client_id,
46
+ 'client_secret' => @secret,
47
+ 'code' => code,
48
+ 'grant_type' => 'authorization_code',
49
+ 'redirect_uri' => redirect_uri }
42
50
 
43
- mount_request_token(payload)
44
- end
51
+ mount_request_token(payload)
52
+ end
45
53
 
46
- def self.get_token_by_code(code, redirect_uri)
47
- verify_setup
54
+ def self.get_token_by_refresh_token(refreshToken = '')
55
+ verify_setup
48
56
 
49
- payload = {'client_id' => @client_id,
50
- 'client_secret' => @secret,
51
- 'code' => code,
52
- 'grant_type' => 'authorization_code',
53
- 'redirect_uri' => redirect_uri
54
- }
57
+ refreshToken = self.token['refresh_token'] if refreshToken.empty?
55
58
 
56
- mount_request_token(payload)
57
- end
59
+ payload = { 'client_id' => @client_id,
60
+ 'client_secret' => @secret,
61
+ 'refresh_token' => refreshToken,
62
+ 'grant_type' => 'refresh_token' }
58
63
 
59
- def self.get_token_by_refresh_token(refreshToken = '')
60
- verify_setup
64
+ mount_request_token(payload)
65
+ end
61
66
 
62
- refreshToken = self.token['refresh_token'] if refreshToken.empty?
67
+ def self.get_token_by_client_credentials
68
+ setup_module
63
69
 
64
- payload = {'client_id' => @client_id,
65
- 'client_secret' => @secret,
66
- 'refresh_token' => refreshToken,
67
- 'grant_type' => 'refresh_token'
68
- }
70
+ payload = { 'client_id' => @client_id,
71
+ 'client_secret' => @secret,
72
+ 'grant_type' => 'client_credentials' }
69
73
 
70
- mount_request_token(payload)
71
- end
74
+ mount_request_token(payload)
75
+ end
72
76
 
73
- def self.get_token_by_client_credentials
74
- setup_module
77
+ def self.get_token_introspection(token = '')
78
+ verify_setup
75
79
 
76
- payload = {'client_id' => @client_id,
77
- 'client_secret' => @secret,
78
- 'grant_type' => 'client_credentials'
79
- }
80
+ token = self.token["access_token"] if token.empty?
80
81
 
81
- mount_request_token(payload)
82
- end
82
+ payload = { 'token' => token }
83
83
 
84
- def self.get_token_introspection(token = '')
85
- verify_setup
84
+ authorization = Base64.strict_encode64("#{@client_id}:#{@secret}")
85
+ authorization = "Basic #{authorization}"
86
86
 
87
- token = self.token["access_token"] if token.empty?
88
-
89
- payload = {'token' => token}
90
-
91
- authorization = Base64.strict_encode64("#{@client_id}:#{@secret}")
92
- authorization = "Basic #{authorization}"
93
-
94
- header = {'Content-Type' => 'application/x-www-form-urlencoded',
95
- 'authorization' => authorization}
96
-
97
- _request = -> do
98
- RestClient.post(@configuration['token_introspection_endpoint'], payload, header){|response, request, result|
99
- case response.code
100
- when 200..399
101
- response.body
102
-
103
- else
104
- response.return!
105
- end
106
- }
107
- end
108
-
109
- exec_request _request
110
- end
111
-
112
- def self.url_login_redirect(redirect_uri, response_type = 'code')
113
- verify_setup
114
-
115
- p = URI.encode_www_form({:response_type => response_type, :client_id => @client_id, :redirect_uri => redirect_uri})
116
- "#{@configuration['authorization_endpoint']}?#{p}"
117
- end
118
-
119
- def self.logout(redirect_uri = '', refresh_token = '')
120
- verify_setup
121
-
122
- if self.token || !refresh_token.empty?
123
-
124
- refresh_token = self.token['refresh_token'] if refresh_token.empty?
125
-
126
- payload = {'client_id' => @client_id,
127
- 'client_secret' => @secret,
128
- 'refresh_token' => refresh_token
129
- }
130
-
131
- header = {'Content-Type' => 'application/x-www-form-urlencoded'}
132
-
133
- if redirect_uri.empty?
134
- final_url = @configuration['end_session_endpoint']
135
- else
136
- final_url = "#{@configuration['end_session_endpoint']}?#{URI.encode_www_form({:redirect_uri => redirect_uri})}"
137
- end
138
-
139
- _request = -> do
140
- RestClient.post(final_url, payload, header){|response, request, result|
141
- case response.code
142
- when 200..399
143
- true
144
- else
145
- response.return!
146
- end
147
- }
148
- end
149
-
150
- exec_request _request
151
- else
152
- true
153
- end
154
- end
155
-
156
- def self.get_userinfo(accessToken = '')
157
- verify_setup
158
-
159
- accessToken = self.token["access_token"] if accessToken.empty?
160
-
161
- payload = {'access_token' => accessToken}
162
-
163
- header = {'Content-Type' => 'application/x-www-form-urlencoded'}
164
-
165
- _request = -> do
166
- RestClient.post(@configuration['userinfo_endpoint'], payload, header){|response, request, result|
167
- case response.code
168
- when 200
169
- response.body
170
- else
171
- response.return!
172
- end
173
- }
174
- end
175
-
176
- exec_request _request
177
- end
178
-
179
- def self.url_user_account
180
- verify_setup
181
-
182
- "#{@url}/realms/#{@realm}/account"
183
- end
184
-
185
- def self.has_role?(userRole, accessToken = '')
186
- verify_setup
187
-
188
- if user_signed_in?(accessToken)
189
- dt = decoded_access_token(accessToken)[0]
190
- dt = dt["resource_access"][@client_id]
191
- if dt != nil
192
- dt["roles"].each do |role|
193
- return true if role.to_s == userRole.to_s
194
- end
195
- false
196
- else
197
- false
198
- end
199
- else
200
- false
201
- end
202
- end
203
-
204
- def self.user_signed_in?(accessToken = '')
205
- verify_setup
206
-
207
- begin
208
- JSON(get_token_introspection(accessToken))['active'] === true
209
- rescue => e
210
- if e.class < Keycloak::KeycloakException
211
- raise
212
- else
213
- false
214
- end
215
- end
216
- end
217
-
218
- def self.get_attribute(attributeName, accessToken = '')
219
- verify_setup
220
-
221
- attr = decoded_access_token(accessToken)[0]
222
- attr[attributeName]
223
- end
224
-
225
- def self.token
226
- unless Keycloak.proc_cookie_token.nil?
227
- JSON Keycloak.proc_cookie_token.call
228
- else
229
- raise Keycloak::ProcCookieTokenNotDefined
230
- end
231
- end
232
-
233
- def self.external_attributes
234
- unless Keycloak.proc_external_attributes.nil?
235
- Keycloak.proc_external_attributes.call
236
- else
237
- raise Keycloak::ProcExternalAttributesNotDefined
238
- end
239
- end
240
-
241
- private
242
-
243
- KEYCLOACK_CONTROLLER_DEFAULT = 'session'
244
-
245
- def self.get_installation
246
- if File.exists?(KEYCLOAK_JSON_FILE)
247
- installation = JSON File.read(KEYCLOAK_JSON_FILE)
248
- @realm = installation["realm"]
249
- @url = installation["auth-server-url"]
250
- @client_id = installation["resource"]
251
- @secret = installation["credentials"]["secret"]
252
- @public_key = installation["realm-public-key"]
253
- @auth_server_url = installation["auth-server-url"]
254
- openid_configuration
255
- else
256
- raise "#{KEYCLOAK_JSON_FILE} not found."
257
- end
258
- end
259
-
260
- def self.verify_setup
261
- get_installation if @configuration.nil?
262
- end
263
-
264
- def self.setup_module
265
- Keycloak.proxy ||= ''
266
- Keycloak.keycloak_controller ||= KEYCLOACK_CONTROLLER_DEFAULT
267
- get_installation
268
- end
269
-
270
- def self.exec_request(proc_request)
271
- if Keycloak.explode_exception
272
- proc_request.call
273
- else
274
- begin
275
- proc_request.call
276
- rescue RestClient::ExceptionWithResponse => err
277
- err.response
278
- end
279
- end
280
- end
281
-
282
- def self.openid_configuration
283
- RestClient.proxy = Keycloak.proxy unless Keycloak.proxy.empty?
284
- configUrl = "#{@url}/realms/#{@realm}/.well-known/openid-configuration"
285
- _request = -> do
286
- RestClient.get configUrl
287
- end
288
- response = exec_request _request
289
- if response.code == 200
290
- @configuration = JSON response.body
291
- else
292
- response.return!
293
- end
294
- end
295
-
296
- def self.mount_request_token(payload)
297
- header = {'Content-Type' => 'application/x-www-form-urlencoded'}
298
-
299
- _request = -> do
300
- RestClient.post(@configuration['token_endpoint'], payload, header){|response, request, result|
301
- case response.code
302
- when 200
303
- response.body
304
- else
305
- response.return!
306
- end
307
- }
308
- end
309
-
310
- exec_request _request
311
- end
312
-
313
- def self.decoded_access_token(accessToken = '')
314
- accessToken = self.token["access_token"] if accessToken.empty?
315
- JWT.decode accessToken, @public_key, false, { :algorithm => 'RS256' }
316
- end
317
-
318
- def self.decoded_refresh_token(refreshToken = '')
319
- refreshToken = self.token["access_token"] if refreshToken.empty?
320
- JWT.decode refreshToken, @public_key, false, { :algorithm => 'RS256' }
321
- end
322
-
323
- def self.decoded_id_token(idToken = '')
324
- tk = self.token
325
- idToken = tk["id_token"] if idToken.empty?
326
- if idToken
327
- @decoded_id_token = JWT.decode idToken, @public_key, false, { :algorithm => 'RS256' }
328
- end
329
- end
330
-
331
- end
332
-
333
- # Os recursos desse module (admin) serão utilizadas apenas por usuários que possuem as roles do client realm-management
334
- module Admin
335
-
336
- class << self
337
-
338
- end
339
-
340
- def self.get_users( queryParameters = nil)
341
- generic_get("users/", queryParameters)
342
- end
343
-
344
- def self.create_user(userRepresentation)
345
- generic_post("users/", nil, userRepresentation)
346
- end
347
-
348
- def self.count_users
349
- generic_get("users/count/")
350
- end
351
-
352
- def self.get_user(id)
353
- generic_get("users/#{id}")
354
- end
355
-
356
- def self.update_user(id, userRepresentation)
357
- generic_put("users/#{id}", nil, userRepresentation)
358
- end
359
-
360
- def self.delete_user(id)
361
- generic_delete("users/#{id}")
362
- end
363
-
364
- def self.revoke_consent_user(id, clientID = nil)
365
- if clientID.nil?
366
- clientID = Keycloak::Client.client_id
367
- end
368
- generic_delete("users/#{id}/consents/#{clientID}")
369
- end
370
-
371
- def self.update_account_email(id, actions, redirectUri = '', clientID = nil)
372
- if clientID.nil?
373
- clientID = Keycloak::Client.client_id
374
- end
375
- generic_put("users/#{id}/execute-actions-email", {:redirect_uri => redirectUri, :client_id => clientID}, actions)
376
- end
377
-
378
- def self.get_role_mappings(id)
379
- generic_get("users/#{id}/role-mappings")
380
- end
381
-
382
- def self.get_clients(queryParameters = nil)
383
- generic_get("clients/", queryParameters)
384
- end
385
-
386
- def self.get_all_roles_client(id)
387
- generic_get("clients/#{id}/roles")
388
- end
389
-
390
- def self.get_roles_client_by_name(id, roleName)
391
- generic_get("clients/#{id}/roles/#{roleName}")
392
- end
393
-
394
- def self.add_client_level_roles_to_user(id, client, roleRepresentation)
395
- generic_post("users/#{id}/role-mappings/clients/#{client}", nil, roleRepresentation)
396
- end
397
-
398
- def self.delete_client_level_roles_fom_user(id, client, roleRepresentation)
399
- generic_delete("users/#{id}/role-mappings/clients/#{client}", nil, roleRepresentation)
400
- end
401
-
402
- def self.get_client_level_role_for_user_and_app(id, client)
403
- generic_get("users/#{id}/role-mappings/clients/#{client}")
404
- end
405
-
406
- def self.update_effective_user_roles(id, clientID, rolesNames)
407
- client = JSON get_clients({:clientId => clientID})
408
-
409
- userRoles = JSON get_client_level_role_for_user_and_app(id, client[0]['id'])
410
-
411
- roles = Array.new
412
- # Include new role
413
- rolesNames.each do |r|
414
- if r && !r.empty?
415
- found = false
416
- userRoles.each do |ur|
417
- found = ur['name'] == r
418
- break if found
419
- found = false
420
- end
421
- if !found
422
- role = JSON get_roles_client_by_name(client[0]['id'], r)
423
- roles.push(role)
424
- end
425
- end
426
- end
427
-
428
- garbageRoles = Array.new
429
- # Exclude old role
430
- userRoles.each do |ur|
431
- found = false
432
- rolesNames.each do |r|
433
- if r && !r.empty?
434
- found = ur['name'] == r
435
- break if found
436
- found = false
437
- end
438
- end
439
- if !found
440
- garbageRoles.push(ur)
441
- end
442
- end
443
-
444
- if garbageRoles.count > 0
445
- delete_client_level_roles_fom_user(id, client[0]['id'], garbageRoles)
446
- end
447
-
448
- if roles.count > 0
449
- add_client_level_roles_to_user(id, client[0]['id'], roles)
450
- end
451
- end
452
-
453
- def self.reset_password(id, credentialRepresentation)
454
- generic_put("users/#{id}/reset-password", nil, credentialRepresentation)
455
- end
456
-
457
- # Generics methods
458
-
459
- def self.generic_get(service, queryParameters = nil)
460
- Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, nil, 'GET')
461
- end
462
-
463
- def self.generic_post(service, queryParameters, bodyParameter)
464
- Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, bodyParameter, 'POST')
465
- end
466
-
467
- def self.generic_put(service, queryParameters, bodyParameter)
468
- Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, bodyParameter, 'PUT')
469
- end
470
-
471
- def self.generic_delete(service, queryParameters = nil, bodyParameter = nil)
472
- Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, bodyParameter, 'DELETE')
473
- end
474
-
475
- private
476
-
477
- def self.base_url
478
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/"
479
- end
480
-
481
- def self.full_url(service)
482
- base_url + service
483
- end
484
-
485
- end
486
-
487
- module Internal
488
- include Keycloak::Admin
489
-
490
- class << self
491
- attr_accessor
492
- end
493
-
494
- def self.change_password(userID, redirectURI = '')
495
- proc = lambda {|token|
496
- Keycloak.generic_request(token["access_token"],
497
- Keycloak::Admin.full_url("users/#{userID}/execute-actions-email"),
498
- {:redirect_uri => redirectURI, :client_id => Keycloak::Client.client_id},
499
- ['UPDATE_PASSWORD'],
500
- 'PUT')
501
- }
502
-
503
- default_call(proc)
504
- end
505
-
506
- def self.forgot_password(userLogin, redirectURI = '')
507
- user = get_user_info(userLogin, true)
508
- change_password(user['id'], redirectURI)
509
- end
510
-
511
- def self.get_logged_user_info
512
- proc = lambda {|token|
513
- userinfo = JSON Keycloak::Client.get_userinfo
514
- Keycloak.generic_request(token["access_token"],
515
- Keycloak::Admin.full_url("users/#{userinfo['sub']}"),
516
- nil, nil, 'GET')
517
- }
518
-
519
- default_call(proc)
520
- end
521
-
522
- def self.get_user_info(userLogin, wholeWord = false)
523
- proc = lambda {|token|
524
- if userLogin.index('@').nil?
525
- search = {:username => userLogin}
526
- else
527
- search = {:email => userLogin}
528
- end
529
- users = JSON Keycloak.generic_request(token["access_token"],
530
- Keycloak::Admin.full_url("users/"),
531
- search, nil, 'GET')
532
- users[0]
533
- if users.count == 0
534
- raise Keycloak::UserLoginNotFound
535
- else
536
- efectiveIndex = -1
537
- users.each_with_index do |user, i|
538
- if wholeWord
539
- efectiveIndex = i if userLogin == user['username'] || userLogin == user['email']
540
- else
541
- efectiveIndex = 0
542
- end
543
- break if efectiveIndex >= 0
544
- end
545
-
546
- if efectiveIndex >= 0
547
- if wholeWord
548
- users[efectiveIndex]
549
- else
550
- users
551
- end
552
- else
553
- raise Keycloak::UserLoginNotFound
554
- end
555
- end
556
- }
557
-
558
- default_call(proc)
559
- end
560
-
561
- def self.is_logged_federation_user?
562
- info = get_logged_user_info
563
- info['federationLink'] != nil
564
- end
565
-
566
- def self.create_starter_user(userName, password, email, clientRolesNames, proc = nil)
567
- begin
568
- user = get_user_info(userName, true)
569
- newUser = false
570
- rescue Keycloak::UserLoginNotFound
571
- newUser = true
572
- rescue
573
- raise
574
- end
575
-
576
- procDefault = lambda {|token|
577
- userRepresentation = {:username => userName,
578
- :email => email,
579
- :enabled => true}
580
-
581
- if !newUser || Keycloak.generic_request(token["access_token"],
582
- Keycloak::Admin.full_url("users/"),
583
- nil, userRepresentation, 'POST')
584
-
585
- user = get_user_info(userName, true) if newUser
586
-
587
- credentialRepresentation = {:type => "password",
588
- :temporary => false,
589
- :value => password}
590
-
591
- if Keycloak.generic_request(token["access_token"],
592
- Keycloak::Admin.full_url("users/#{user['id']}/reset-password"),
593
- nil, credentialRepresentation, 'PUT')
594
-
595
- client = JSON Keycloak.generic_request(token["access_token"],
596
- Keycloak::Admin.full_url("clients/"),
597
- {:clientId => Keycloak::Client.client_id}, nil, 'GET')
598
-
599
- roles = Array.new
600
- clientRolesNames.each do |r|
601
- if r && !r.empty?
602
- role = JSON Keycloak.generic_request(token["access_token"],
603
- Keycloak::Admin.full_url("clients/#{client[0]['id']}/roles/#{r}"),
604
- nil, nil, 'GET')
605
- roles.push(role)
606
- end
607
- end
608
-
609
- if roles.count > 0
610
- Keycloak.generic_request(token["access_token"],
611
- Keycloak::Admin.full_url("users/#{user['id']}/role-mappings/clients/#{client[0]['id']}"),
612
- nil, roles, 'POST')
613
- end
614
- end
615
-
616
- end
617
- }
618
-
619
- if default_call(procDefault)
620
- if !proc.nil?
621
- proc.call user
622
- end
623
- end
624
-
625
- end
626
-
627
- protected
628
-
629
- def self.default_call(proc)
630
- begin
631
- tk = nil
632
- resp = nil
633
-
634
- Keycloak::Client.get_installation
635
-
636
- payload = {'client_id' => Keycloak::Client.client_id,
637
- 'client_secret' => Keycloak::Client.secret,
638
- 'grant_type' => 'client_credentials'
639
- }
640
-
641
- header = {'Content-Type' => 'application/x-www-form-urlencoded'}
642
-
643
- _request = -> do
644
- RestClient.post(Keycloak::Client.configuration['token_endpoint'], payload, header){|response, request, result|
645
- case response.code
646
- when 200..399
647
- tk = JSON response.body
648
- resp = proc.call(tk)
649
- else
650
- response.return!
651
- end
652
- }
653
- end
654
-
655
- Keycloak::Client.exec_request _request
656
- ensure
657
- if tk
658
- payload = {'client_id' => Keycloak::Client.client_id,
659
- 'client_secret' => Keycloak::Client.secret,
660
- 'refresh_token' => tk["refresh_token"]
661
- }
662
-
663
- header = {'Content-Type' => 'application/x-www-form-urlencoded'}
664
- _request = -> do
665
- RestClient.post(Keycloak::Client.configuration['end_session_endpoint'], payload, header){|response, request, result|
666
- case response.code
667
- when 200..399
668
- resp if resp.nil?
669
- else
670
- response.return!
671
- end
672
- }
673
- end
674
- Keycloak::Client.exec_request _request
675
- end
676
- end
677
- end
678
-
679
- end
680
-
681
- private
682
-
683
- def self.generic_request(accessToken, uri, queryParameters, bodyParameter, method)
684
- Keycloak::Client.verify_setup
685
- final_url = uri
686
-
687
- header = {'Content-Type' => 'application/x-www-form-urlencoded',
688
- 'Authorization' => "Bearer #{accessToken}"}
689
-
690
- if queryParameters
691
- parameters = URI.encode_www_form(queryParameters)
692
- final_url = final_url << '?' << parameters
693
- end
694
-
695
- case method.upcase
696
- when 'GET'
697
- _request = -> do
698
- RestClient.get(final_url, header){|response, request, result|
699
- rescue_response(response)
700
- }
701
- end
702
- when 'POST', 'PUT'
703
- header["Content-Type"] = 'application/json'
704
- parameters = JSON.generate bodyParameter
705
- _request = -> do
706
- case method.upcase
707
- when 'POST'
708
- RestClient.post(final_url, parameters, header){|response, request, result|
709
- rescue_response(response)
710
- }
711
- else
712
- RestClient.put(final_url, parameters, header){|response, request, result|
713
- rescue_response(response)
714
- }
715
- end
716
- end
717
- when 'DELETE'
718
- _request = -> do
719
- if bodyParameter
720
- header["Content-Type"] = 'application/json'
721
- parameters = JSON.generate bodyParameter
722
- RestClient::Request.execute(method: :delete, url: final_url,
723
- payload: parameters, headers: header){|response, request, result|
724
- rescue_response(response)
725
- }
726
- else
727
- RestClient.delete(final_url, header){|response, request, result|
728
- rescue_response(response)
729
- }
730
- end
731
- end
732
- else
733
- raise
734
- end
735
-
736
- _request.call
737
-
738
- end
739
-
740
- def self.rescue_response(response)
741
- case response.code
742
- when 200..399
743
- if response.body.empty?
744
- true
745
- else
746
- response.body
747
- end
748
- else
749
- if Keycloak.explode_exception
750
- response.return!
751
- else
752
- begin
753
- response.return!
754
- rescue RestClient::ExceptionWithResponse => err
755
- err.response
756
- rescue Exception => e
757
- e.message
758
- end
759
- end
760
- end
761
- end
87
+ header = {'Content-Type' => 'application/x-www-form-urlencoded',
88
+ 'authorization' => authorization}
762
89
 
90
+ _request = -> do
91
+ RestClient.post(@configuration['token_introspection_endpoint'], payload, header){|response, request, result|
92
+ case response.code
93
+ when 200..399
94
+ response.body
95
+
96
+ else
97
+ response.return!
98
+ end
99
+ }
100
+ end
101
+
102
+ exec_request _request
103
+ end
104
+
105
+ def self.url_login_redirect(redirect_uri, response_type = 'code')
106
+ verify_setup
107
+
108
+ p = URI.encode_www_form({ response_type: response_type, client_id: @client_id, redirect_uri: redirect_uri })
109
+ "#{@configuration['authorization_endpoint']}?#{p}"
110
+ end
111
+
112
+ def self.logout(redirect_uri = '', refresh_token = '')
113
+ verify_setup
114
+
115
+ if self.token || !refresh_token.empty?
116
+
117
+ refresh_token = self.token['refresh_token'] if refresh_token.empty?
118
+
119
+ payload = { 'client_id' => @client_id,
120
+ 'client_secret' => @secret,
121
+ 'refresh_token' => refresh_token
122
+ }
123
+
124
+ header = {'Content-Type' => 'application/x-www-form-urlencoded'}
125
+
126
+ if redirect_uri.empty?
127
+ final_url = @configuration['end_session_endpoint']
128
+ else
129
+ final_url = "#{@configuration['end_session_endpoint']}?#{URI.encode_www_form({ redirect_uri: redirect_uri })}"
130
+ end
131
+
132
+ _request = -> do
133
+ RestClient.post(final_url, payload, header){ |response, request, result|
134
+ case response.code
135
+ when 200..399
136
+ true
137
+ else
138
+ response.return!
139
+ end
140
+ }
141
+ end
142
+
143
+ exec_request _request
144
+ else
145
+ true
146
+ end
147
+ end
148
+
149
+ def self.get_userinfo(accessToken = '')
150
+ verify_setup
151
+
152
+ accessToken = self.token["access_token"] if accessToken.empty?
153
+
154
+ payload = { 'access_token' => accessToken }
155
+
156
+ header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
157
+
158
+ _request = -> do
159
+ RestClient.post(@configuration['userinfo_endpoint'], payload, header){ |response, request, result|
160
+ case response.code
161
+ when 200
162
+ response.body
163
+ else
164
+ response.return!
165
+ end
166
+ }
167
+ end
168
+
169
+ exec_request _request
170
+ end
171
+
172
+ def self.url_user_account
173
+ verify_setup
174
+
175
+ "#{@url}/realms/#{@realm}/account"
176
+ end
177
+
178
+ def self.has_role?(userRole, accessToken = '')
179
+ verify_setup
180
+
181
+ if user_signed_in?(accessToken)
182
+ dt = decoded_access_token(accessToken)[0]
183
+ dt = dt["resource_access"][@client_id]
184
+ if dt != nil
185
+ dt["roles"].each do |role|
186
+ return true if role.to_s == userRole.to_s
187
+ end
188
+ false
189
+ else
190
+ false
191
+ end
192
+ else
193
+ false
194
+ end
195
+ end
196
+
197
+ def self.user_signed_in?(accessToken = '')
198
+ verify_setup
199
+
200
+ begin
201
+ JSON(get_token_introspection(accessToken))['active'] === true
202
+ rescue => e
203
+ if e.class < Keycloak::KeycloakException
204
+ raise
205
+ else
206
+ false
207
+ end
208
+ end
209
+ end
210
+
211
+ def self.get_attribute(attributeName, accessToken = '')
212
+ verify_setup
213
+
214
+ attr = decoded_access_token(accessToken)[0]
215
+ attr[attributeName]
216
+ end
217
+
218
+ def self.token
219
+ if !Keycloak.proc_cookie_token.nil?
220
+ JSON Keycloak.proc_cookie_token.call
221
+ else
222
+ raise Keycloak::ProcCookieTokenNotDefined
223
+ end
224
+ end
225
+
226
+ def self.external_attributes
227
+ if !Keycloak.proc_external_attributes.nil?
228
+ Keycloak.proc_external_attributes.call
229
+ else
230
+ raise Keycloak::ProcExternalAttributesNotDefined
231
+ end
232
+ end
233
+
234
+ private
235
+
236
+ KEYCLOACK_CONTROLLER_DEFAULT = 'session'
237
+
238
+ def self.get_installation
239
+ if File.exists?(KEYCLOAK_JSON_FILE)
240
+ installation = JSON File.read(KEYCLOAK_JSON_FILE)
241
+ @realm = installation["realm"]
242
+ @url = installation["auth-server-url"]
243
+ @client_id = installation["resource"]
244
+ @secret = installation["credentials"]["secret"]
245
+ @public_key = installation["realm-public-key"]
246
+ @auth_server_url = installation["auth-server-url"]
247
+ openid_configuration
248
+ else
249
+ raise "#{KEYCLOAK_JSON_FILE} not found."
250
+ end
251
+ end
252
+
253
+ def self.verify_setup
254
+ get_installation if @configuration.nil?
255
+ end
256
+
257
+ def self.setup_module
258
+ Keycloak.proxy ||= ''
259
+ Keycloak.keycloak_controller ||= KEYCLOACK_CONTROLLER_DEFAULT
260
+ get_installation
261
+ end
262
+
263
+ def self.exec_request(proc_request)
264
+ if Keycloak.explode_exception
265
+ proc_request.call
266
+ else
267
+ begin
268
+ proc_request.call
269
+ rescue RestClient::ExceptionWithResponse => err
270
+ err.response
271
+ end
272
+ end
273
+ end
274
+
275
+ def self.openid_configuration
276
+ RestClient.proxy = Keycloak.proxy unless Keycloak.proxy.empty?
277
+ config_url = "#{@url}/realms/#{@realm}/.well-known/openid-configuration"
278
+ _request = -> do
279
+ RestClient.get config_url
280
+ end
281
+ response = exec_request _request
282
+ if response.code == 200
283
+ @configuration = JSON response.body
284
+ else
285
+ response.return!
286
+ end
287
+ end
288
+
289
+ def self.mount_request_token(payload)
290
+ header = {'Content-Type' => 'application/x-www-form-urlencoded'}
291
+
292
+ _request = -> do
293
+ RestClient.post(@configuration['token_endpoint'], payload, header){|response, request, result|
294
+ case response.code
295
+ when 200
296
+ response.body
297
+ else
298
+ response.return!
299
+ end
300
+ }
301
+ end
302
+
303
+ exec_request _request
304
+ end
305
+
306
+ def self.decoded_access_token(accessToken = '')
307
+ accessToken = self.token["access_token"] if accessToken.empty?
308
+ JWT.decode accessToken, @public_key, false, { :algorithm => 'RS256' }
309
+ end
310
+
311
+ def self.decoded_refresh_token(refreshToken = '')
312
+ refreshToken = self.token["access_token"] if refreshToken.empty?
313
+ JWT.decode refreshToken, @public_key, false, { :algorithm => 'RS256' }
314
+ end
315
+
316
+ def self.decoded_id_token(idToken = '')
317
+ tk = self.token
318
+ idToken = tk["id_token"] if idToken.empty?
319
+ if idToken
320
+ @decoded_id_token = JWT.decode idToken, @public_key, false, { :algorithm => 'RS256' }
321
+ end
322
+ end
323
+
324
+ end
325
+
326
+ # Os recursos desse module (admin) serão utilizadas apenas por usuários que possuem as roles do client realm-management
327
+ module Admin
328
+ class << self
329
+ end
330
+
331
+ def self.get_users(queryParameters = nil, accessToken = nil)
332
+ generic_get("users/", queryParameters, accessToken)
333
+ end
334
+
335
+ def self.create_user(userRepresentation, accessToken = nil)
336
+ generic_post("users/", nil, userRepresentation, accessToken)
337
+ end
338
+
339
+ def self.count_users(accessToken = nil)
340
+ generic_get("users/count/", nil, accessToken)
341
+ end
342
+
343
+ def self.get_user(id, accessToken = nil)
344
+ generic_get("users/#{id}", nil, accessToken)
345
+ end
346
+
347
+ def self.update_user(id, userRepresentation, accessToken = nil)
348
+ generic_put("users/#{id}", nil, userRepresentation, accessToken)
349
+ end
350
+
351
+ def self.delete_user(id, accessToken = nil)
352
+ generic_delete("users/#{id}", nil, nil, accessToken)
353
+ end
354
+
355
+ def self.revoke_consent_user(id, clientID = nil, accessToken = nil)
356
+ if clientID.nil?
357
+ clientID = Keycloak::Client.client_id
358
+ end
359
+ generic_delete("users/#{id}/consents/#{clientID}", nil, nil, accessToken)
360
+ end
361
+
362
+ def self.update_account_email(id, actions, redirectUri = '', clientID = nil, accessToken = nil)
363
+ if clientID.nil?
364
+ clientID = Keycloak::Client.client_id
365
+ end
366
+ generic_put("users/#{id}/execute-actions-email", {:redirect_uri => redirectUri, :client_id => clientID}, actions, accessToken)
367
+ end
368
+
369
+ def self.get_role_mappings(id, accessToken = nil)
370
+ generic_get("users/#{id}/role-mappings", nil, accessToken)
371
+ end
372
+
373
+ def self.get_clients(queryParameters = nil, accessToken = nil)
374
+ generic_get("clients/", queryParameters, accessToken)
375
+ end
376
+
377
+ def self.get_all_roles_client(id, accessToken = nil)
378
+ generic_get("clients/#{id}/roles", nil, accessToken)
379
+ end
380
+
381
+ def self.get_roles_client_by_name(id, roleName, accessToken = nil)
382
+ generic_get("clients/#{id}/roles/#{roleName}", nil, accessToken)
383
+ end
384
+
385
+ def self.add_client_level_roles_to_user(id, client, roleRepresentation, accessToken = nil)
386
+ generic_post("users/#{id}/role-mappings/clients/#{client}", nil, roleRepresentation, accessToken)
387
+ end
388
+
389
+ def self.delete_client_level_roles_from_user(id, client, roleRepresentation, accessToken = nil)
390
+ generic_delete("users/#{id}/role-mappings/clients/#{client}", nil, roleRepresentation, accessToken)
391
+ end
392
+
393
+ def self.get_client_level_role_for_user_and_app(id, client, accessToken = nil)
394
+ generic_get("users/#{id}/role-mappings/clients/#{client}", nil, accessToken)
395
+ end
396
+
397
+ def self.update_effective_user_roles(id, clientID, rolesNames, accessToken = nil)
398
+ client = JSON get_clients({ clientId: clientID })
399
+
400
+ userRoles = JSON get_client_level_role_for_user_and_app(id, client[0]['id'], accessToken)
401
+
402
+ roles = Array.new
403
+ # Include new role
404
+ rolesNames.each do |r|
405
+ if r && !r.empty?
406
+ found = false
407
+ userRoles.each do |ur|
408
+ found = ur['name'] == r
409
+ break if found
410
+ found = false
411
+ end
412
+ if !found
413
+ role = JSON get_roles_client_by_name(client[0]['id'], r, accessToken)
414
+ roles.push(role)
415
+ end
416
+ end
417
+ end
418
+
419
+ garbageRoles = Array.new
420
+ # Exclude old role
421
+ userRoles.each do |ur|
422
+ found = false
423
+ rolesNames.each do |r|
424
+ if r && !r.empty?
425
+ found = ur['name'] == r
426
+ break if found
427
+ found = false
428
+ end
429
+ end
430
+ if !found
431
+ garbageRoles.push(ur)
432
+ end
433
+ end
434
+
435
+ if garbageRoles.count > 0
436
+ delete_client_level_roles_from_user(id, client[0]['id'], garbageRoles, accessToken)
437
+ end
438
+
439
+ if roles.count > 0
440
+ add_client_level_roles_to_user(id, client[0]['id'], roles, accessToken)
441
+ end
442
+ end
443
+
444
+ def self.reset_password(id, credentialRepresentation, accessToken = nil)
445
+ generic_put("users/#{id}/reset-password", nil, credentialRepresentation, accessToken)
446
+ end
447
+
448
+ def self.get_effective_client_level_role_composite_user(id, client, accessToken = nil)
449
+ generic_get("users/#{id}/role-mappings/clients/#{client}/composite", nil, accessToken)
450
+ end
451
+
452
+ # Generics methods
453
+
454
+ def self.generic_get(service, queryParameters = nil, accessToken = nil)
455
+ Keycloak.generic_request(effective_access_token(accessToken), full_url(service), queryParameters, nil, 'GET')
456
+ end
457
+
458
+ def self.generic_post(service, queryParameters, bodyParameter, accessToken = nil)
459
+ Keycloak.generic_request(effective_access_token(accessToken), full_url(service), queryParameters, bodyParameter, 'POST')
460
+ end
461
+
462
+ def self.generic_put(service, queryParameters, bodyParameter, accessToken = nil)
463
+ Keycloak.generic_request(effective_access_token(accessToken), full_url(service), queryParameters, bodyParameter, 'PUT')
464
+ end
465
+
466
+ def self.generic_delete(service, queryParameters = nil, bodyParameter = nil, accessToken = nil)
467
+ Keycloak.generic_request(effective_access_token(accessToken), full_url(service), queryParameters, bodyParameter, 'DELETE')
468
+ end
469
+
470
+ private
471
+
472
+ def self.effective_access_token(access_token)
473
+ if access_token.blank?
474
+ Keycloak::Client.token['access_token']
475
+ else
476
+ access_token
477
+ end
478
+ end
479
+
480
+ def self.base_url
481
+ Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/"
482
+ end
483
+
484
+ def self.full_url(service)
485
+ base_url + service
486
+ end
487
+
488
+ end
489
+
490
+ module Internal
491
+ include Keycloak::Admin
492
+
493
+ class << self
494
+ end
495
+
496
+ def self.get_users(queryParameters = nil)
497
+ proc = lambda {|token|
498
+ Keycloak::Admin.get_users(queryParameters, token["access_token"])
499
+ }
500
+
501
+ default_call(proc)
502
+ end
503
+
504
+ def self.change_password(userID, redirectURI = '')
505
+ proc = lambda {|token|
506
+ Keycloak.generic_request(token["access_token"],
507
+ Keycloak::Admin.full_url("users/#{userID}/execute-actions-email"),
508
+ {:redirect_uri => redirectURI, :client_id => Keycloak::Client.client_id},
509
+ ['UPDATE_PASSWORD'],
510
+ 'PUT')
511
+ }
512
+
513
+ default_call(proc)
514
+ end
515
+
516
+ def self.forgot_password(userLogin, redirectURI = '')
517
+ user = get_user_info(userLogin, true)
518
+ change_password(user['id'], redirectURI)
519
+ end
520
+
521
+ def self.get_logged_user_info
522
+ proc = lambda {|token|
523
+ userinfo = JSON Keycloak::Client.get_userinfo
524
+ Keycloak.generic_request(token["access_token"],
525
+ Keycloak::Admin.full_url("users/#{userinfo['sub']}"),
526
+ nil, nil, 'GET')
527
+ }
528
+
529
+ default_call(proc)
530
+ end
531
+
532
+ def self.get_user_info(userLogin, wholeWord = false)
533
+ proc = lambda { |token|
534
+ if userLogin.index('@').nil?
535
+ search = {:username => userLogin}
536
+ else
537
+ search = {:email => userLogin}
538
+ end
539
+ users = JSON Keycloak.generic_request(token["access_token"],
540
+ Keycloak::Admin.full_url("users/"),
541
+ search, nil, 'GET')
542
+ users[0]
543
+ if users.count.zero?
544
+ raise Keycloak::UserLoginNotFound
545
+ else
546
+ efective_index = -1
547
+ users.each_with_index do |user, i|
548
+ if wholeWord
549
+ efective_index = i if userLogin == user['username'] || userLogin == user['email']
550
+ else
551
+ efective_index = 0
552
+ end
553
+ break if efective_index >= 0
554
+ end
555
+
556
+ if efective_index >= 0
557
+ if wholeWord
558
+ users[efective_index]
559
+ else
560
+ users
561
+ end
562
+ else
563
+ raise Keycloak::UserLoginNotFound
564
+ end
565
+ end
566
+ }
567
+
568
+ default_call(proc)
569
+ end
570
+
571
+ def self.logged_federation_user?
572
+ info = get_logged_user_info
573
+ info['federationLink'] != nil
574
+ end
575
+
576
+ def self.create_starter_user(userName, password, email, clientRolesNames, proc = nil)
577
+ begin
578
+ user = get_user_info(userName, true)
579
+ newUser = false
580
+ rescue Keycloak::UserLoginNotFound
581
+ newUser = true
582
+ rescue
583
+ raise
584
+ end
585
+
586
+ proc_default = lambda { |token|
587
+ user_representation = { username: userName,
588
+ email: email,
589
+ enabled: true }
590
+
591
+ if !newUser || Keycloak.generic_request(token["access_token"],
592
+ Keycloak::Admin.full_url("users/"),
593
+ nil, user_representation, 'POST')
594
+
595
+ user = get_user_info(userName, true) if newUser
596
+
597
+ credential_representation = { type: "password",
598
+ temporary: false,
599
+ value: password }
600
+
601
+ if Keycloak.generic_request(token["access_token"],
602
+ Keycloak::Admin.full_url("users/#{user['id']}/reset-password"),
603
+ nil, credential_representation, 'PUT')
604
+
605
+ client = JSON Keycloak.generic_request(token["access_token"],
606
+ Keycloak::Admin.full_url("clients/"),
607
+ { clientId: Keycloak::Client.client_id }, nil, 'GET')
608
+
609
+ roles = []
610
+ clientRolesNames.each do |r|
611
+ if r.present?
612
+ role = JSON Keycloak.generic_request(token["access_token"],
613
+ Keycloak::Admin.full_url("clients/#{client[0]['id']}/roles/#{r}"),
614
+ nil, nil, 'GET')
615
+ roles.push(role)
616
+ end
617
+ end
618
+
619
+ if roles.count > 0
620
+ Keycloak.generic_request(token["access_token"],
621
+ Keycloak::Admin.full_url("users/#{user['id']}/role-mappings/clients/#{client[0]['id']}"),
622
+ nil, roles, 'POST')
623
+ end
624
+ end
625
+
626
+ end
627
+ }
628
+
629
+ if default_call(proc_default)
630
+ proc.call user unless proc.nil?
631
+ end
632
+ end
633
+
634
+ def self.get_client_roles
635
+ proc = lambda {|token|
636
+ client = JSON Keycloak::Admin.get_clients({ clientId: Keycloak::Client.client_id }, token["access_token"])
637
+
638
+ Keycloak.generic_request(token["access_token"],
639
+ Keycloak::Admin.full_url("clients/#{client[0]['id']}/roles"),
640
+ nil, nil, 'GET')
641
+ }
642
+
643
+ default_call(proc)
644
+ end
645
+
646
+ def self.get_client_user_roles(userID)
647
+ proc = lambda {|token|
648
+ client = JSON Keycloak::Admin.get_clients({ clientId: Keycloak::Client.client_id }, token["access_token"])
649
+ Keycloak::Admin.get_effective_client_level_role_composite_user(userID, client[0]['id'], token["access_token"])
650
+ }
651
+
652
+ default_call(proc)
653
+ end
654
+
655
+ def self.has_role?(userID, userRole)
656
+ roles = JSON get_client_user_roles(userID)
657
+ if !roles.nil?
658
+ roles.each do |role|
659
+ return true if role['name'].to_s == userRole.to_s
660
+ end
661
+ false
662
+ else
663
+ false
664
+ end
665
+ end
666
+
667
+ protected
668
+
669
+ def self.default_call(proc)
670
+ begin
671
+ tk = nil
672
+ resp = nil
673
+
674
+ Keycloak::Client.get_installation
675
+
676
+ payload = { 'client_id' => Keycloak::Client.client_id,
677
+ 'client_secret' => Keycloak::Client.secret,
678
+ 'grant_type' => 'client_credentials' }
679
+
680
+ header = {'Content-Type' => 'application/x-www-form-urlencoded'}
681
+
682
+ _request = -> do
683
+ RestClient.post(Keycloak::Client.configuration['token_endpoint'], payload, header){|response, request, result|
684
+ case response.code
685
+ when 200..399
686
+ tk = JSON response.body
687
+ resp = proc.call(tk)
688
+ else
689
+ response.return!
690
+ end
691
+ }
692
+ end
693
+
694
+ Keycloak::Client.exec_request _request
695
+ ensure
696
+ if tk
697
+ payload = { 'client_id' => Keycloak::Client.client_id,
698
+ 'client_secret' => Keycloak::Client.secret,
699
+ 'refresh_token' => tk["refresh_token"] }
700
+
701
+ header = {'Content-Type' => 'application/x-www-form-urlencoded'}
702
+ _request = -> do
703
+ RestClient.post(Keycloak::Client.configuration['end_session_endpoint'], payload, header){|response, request, result|
704
+ case response.code
705
+ when 200..399
706
+ resp if resp.nil?
707
+ else
708
+ response.return!
709
+ end
710
+ }
711
+ end
712
+ Keycloak::Client.exec_request _request
713
+ end
714
+ end
715
+ end
716
+
717
+ end
718
+
719
+ private
720
+
721
+ def self.generic_request(accessToken, uri, queryParameters, bodyParameter, method)
722
+ Keycloak::Client.verify_setup
723
+ final_url = uri
724
+
725
+ header = {'Content-Type' => 'application/x-www-form-urlencoded',
726
+ 'Authorization' => "Bearer #{accessToken}"}
727
+
728
+ if queryParameters
729
+ parameters = URI.encode_www_form(queryParameters)
730
+ final_url = final_url << '?' << parameters
731
+ end
732
+
733
+ case method.upcase
734
+ when 'GET'
735
+ _request = -> do
736
+ RestClient.get(final_url, header){|response, request, result|
737
+ rescue_response(response)
738
+ }
739
+ end
740
+ when 'POST', 'PUT'
741
+ header["Content-Type"] = 'application/json'
742
+ parameters = JSON.generate bodyParameter
743
+ _request = -> do
744
+ case method.upcase
745
+ when 'POST'
746
+ RestClient.post(final_url, parameters, header){|response, request, result|
747
+ rescue_response(response)
748
+ }
749
+ else
750
+ RestClient.put(final_url, parameters, header){|response, request, result|
751
+ rescue_response(response)
752
+ }
753
+ end
754
+ end
755
+ when 'DELETE'
756
+ _request = -> do
757
+ if bodyParameter
758
+ header["Content-Type"] = 'application/json'
759
+ parameters = JSON.generate bodyParameter
760
+ RestClient::Request.execute(method: :delete, url: final_url,
761
+ payload: parameters, headers: header) { |response, request, result|
762
+ rescue_response(response)
763
+ }
764
+ else
765
+ RestClient.delete(final_url, header) { |response, request, result|
766
+ rescue_response(response)
767
+ }
768
+ end
769
+ end
770
+ else
771
+ raise
772
+ end
773
+
774
+ _request.call
775
+
776
+ end
777
+
778
+ def self.rescue_response(response)
779
+ case response.code
780
+ when 200..399
781
+ if response.body.empty?
782
+ true
783
+ else
784
+ response.body
785
+ end
786
+ else
787
+ if Keycloak.explode_exception
788
+ response.return!
789
+ else
790
+ begin
791
+ response.return!
792
+ rescue RestClient::ExceptionWithResponse => err
793
+ err.response
794
+ rescue StandardError => e
795
+ e.message
796
+ end
797
+ end
798
+ end
799
+ end
763
800
  end
764
801
 
765
802
  require 'keycloak/exceptions'