keycloak 1.2.0 → 2.0.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: da54a19c777a0965809f08c8913b4bbce7c1abd3
4
- data.tar.gz: eb76df093291e5f43789f02999ba1af0149d4421
3
+ metadata.gz: 16dc6ab9a33a507e177fc676f907c015291d0f70
4
+ data.tar.gz: 4c49fd2835f1ac1a39410c50f77b8fca4bdb791c
5
5
  SHA512:
6
- metadata.gz: b438b078455362d62a4381fcc410a073c74f3aa67e45c35f4f8fe0ec2eec64540683e6ad0bf42c24005cb1755ca5b6c9f1820e91c96d327281f1d06d2a66582d
7
- data.tar.gz: 1700bafbf32593ab794e481d48a192b6c726b60f9b3cb861493e9f69008edc5869d8883ff91edecd848c03d701589ca70d09ef9ad8d6337f361c3a60080f9011
6
+ metadata.gz: 813ec13535ea225feb0a42048169c6d62caa51ccc7b54aac269ce8beba2a5b63e2ee065163f0df196ec83aa0f74cfeb8fa363a3a64160a6bf249fbadbae487d0
7
+ data.tar.gz: 37d21da9cecd8a1f21a013b6afb8a35f99919654ca5957bedf4f86cd2a01ac2fd8d3620a82f7d115ffa5ae77bd9b9c283195981440a69611058a023844105b59
@@ -8,10 +8,7 @@ class InitializerGenerator < Rails::Generators::Base
8
8
  # If true, then all request exception will explode in application (this is the default value)
9
9
  Keycloak.generate_request_exception = #{generate_request_exception}
10
10
  # controller that manage the user session
11
- Keycloak.keycloak_controller = 'session'
12
- # internal user for admin tasks
13
- Keycloak::Internal.admin_user = ''
14
- Keycloak::Internal.admin_password = ''"
11
+ Keycloak.keycloak_controller = 'session'"
15
12
  end
16
13
  end
17
14
  end
@@ -9,7 +9,7 @@ module Keycloak
9
9
 
10
10
  class << self
11
11
  attr_accessor :proxy, :generate_request_exception, :keycloak_controller,
12
- :last_response
12
+ :proc_cookie_token, :proc_external_attributes
13
13
  end
14
14
 
15
15
 
@@ -23,26 +23,20 @@ module Keycloak
23
23
  module Client
24
24
 
25
25
  class << self
26
- attr_reader :user, :password, :realm, :url, :client_id, :auth_server_url,
27
- :secret, :configuration, :public_key, :decoded_access_token,
28
- :token, :token_introspection, :decoded_refresh_token,
29
- :active, :decoded_id_token, :userinfo
26
+ attr_reader :realm, :url, :client_id, :auth_server_url,
27
+ :secret, :configuration, :public_key
30
28
 
31
- attr_accessor :external_attributes
32
29
  end
33
30
 
34
31
  KEYCLOAK_JSON_FILE = 'keycloak.json'
35
32
 
36
33
  def self.get_token(user, password)
37
34
  setup_module
38
- reset_active
39
-
40
- @user, @password = user, password
41
35
 
42
36
  payload = {'client_id' => @client_id,
43
37
  'client_secret' => @secret,
44
- 'username' => @user,
45
- 'password' => @password,
38
+ 'username' => user,
39
+ 'password' => password,
46
40
  'grant_type' => 'password'
47
41
  }
48
42
 
@@ -50,24 +44,50 @@ module Keycloak
50
44
  end
51
45
 
52
46
  def self.get_token_by_code(code, redirect_uri)
53
- reset_active
47
+ verify_setup
48
+
49
+ payload = {'client_id' => @client_id,
50
+ 'client_secret' => @secret,
51
+ 'code' => code,
52
+ 'grant_type' => 'authorization_code',
53
+ 'redirect_uri' => redirect_uri
54
+ }
55
+
56
+ mount_request_token(payload)
57
+ end
58
+
59
+ def self.get_token_by_refresh_token(refreshToken = nil)
60
+ verify_setup
61
+
62
+ refreshToken = self.token['refresh_token']
63
+
64
+ payload = {'client_id' => @client_id,
65
+ 'client_secret' => @secret,
66
+ 'refresh_token' => refreshToken,
67
+ 'grant_type' => 'refresh_token'
68
+ }
69
+
70
+ mount_request_token(payload)
71
+ end
72
+
73
+ def self.get_token_by_client_credentials
74
+ setup_module
54
75
 
55
76
  payload = {'client_id' => @client_id,
56
- 'client_secret' => @secret,
57
- 'code' => code,
58
- 'grant_type' => 'authorization_code',
59
- 'redirect_uri' => redirect_uri
60
- }
77
+ 'client_secret' => @secret,
78
+ 'grant_type' => 'client_credentials'
79
+ }
61
80
 
62
81
  mount_request_token(payload)
63
82
  end
64
83
 
65
84
  def self.get_token_introspection(refresh = false)
66
- reset_active(false)
85
+ verify_setup
86
+
67
87
  unless refresh
68
- payload = {'token' => @token["access_token"]}
88
+ payload = {'token' => self.token["access_token"]}
69
89
  else
70
- payload = {'token' => @token["refresh_token"]}
90
+ payload = {'token' => self.token["refresh_token"]}
71
91
  end
72
92
 
73
93
  authorization = Base64.strict_encode64("#{@client_id}:#{@secret}")
@@ -80,15 +100,11 @@ module Keycloak
80
100
  RestClient.post(@configuration['token_introspection_endpoint'], payload, header){|response, request, result|
81
101
  case response.code
82
102
  when 200..399
83
- @token_introspection = JSON response.body
84
- @active = @token_introspection['active']
85
- @token_introspection
103
+ response.body
104
+
86
105
  else
87
106
  response.return!
88
107
  end
89
- if !@active
90
- reset_active
91
- end
92
108
  }
93
109
  end
94
110
 
@@ -96,16 +112,20 @@ module Keycloak
96
112
  end
97
113
 
98
114
  def self.url_login_redirect(redirect_uri, response_type = 'code')
115
+ verify_setup
116
+
99
117
  p = URI.encode_www_form({:response_type => response_type, :client_id => @client_id, :redirect_uri => redirect_uri})
100
118
  "#{@configuration['authorization_endpoint']}?#{p}"
101
119
  end
102
120
 
103
121
  def self.logout(redirect_uri = '')
104
- if @token
122
+ verify_setup
123
+
124
+ if self.token
105
125
  payload = {'client_id' => @client_id,
106
- 'client_secret' => @secret,
107
- 'refresh_token' => @token["refresh_token"]
108
- }
126
+ 'client_secret' => @secret,
127
+ 'refresh_token' => self.token["refresh_token"]
128
+ }
109
129
 
110
130
  header = {'Content-Type' => 'application/x-www-form-urlencoded'}
111
131
 
@@ -119,7 +139,6 @@ module Keycloak
119
139
  RestClient.post(final_url, payload, header){|response, request, result|
120
140
  case response.code
121
141
  when 200..399
122
- reset_active
123
142
  true
124
143
  else
125
144
  response.return!
@@ -134,7 +153,9 @@ module Keycloak
134
153
  end
135
154
 
136
155
  def self.get_userinfo
137
- payload = {'access_token' => @token["access_token"]}
156
+ verify_setup
157
+
158
+ payload = {'access_token' => self.token["access_token"]}
138
159
 
139
160
  header = {'Content-Type' => 'application/x-www-form-urlencoded'}
140
161
 
@@ -142,8 +163,7 @@ module Keycloak
142
163
  RestClient.post(@configuration['userinfo_endpoint'], payload, header){|response, request, result|
143
164
  case response.code
144
165
  when 200
145
- @userinfo = JSON response.body
146
- @userinfo
166
+ response.body
147
167
  else
148
168
  response.return!
149
169
  end
@@ -154,6 +174,8 @@ module Keycloak
154
174
  end
155
175
 
156
176
  def self.url_user_account
177
+ verify_setup
178
+
157
179
  "#{@url}/realms/#{@realm}/account"
158
180
  end
159
181
 
@@ -166,7 +188,6 @@ module Keycloak
166
188
  @secret = installation["credentials"]["secret"]
167
189
  @public_key = installation["realm-public-key"]
168
190
  @auth_server_url = installation["auth-server-url"]
169
- reset_active(false)
170
191
  openid_configuration
171
192
  else
172
193
  raise "#{KEYCLOAK_JSON_FILE} not found."
@@ -174,8 +195,10 @@ module Keycloak
174
195
  end
175
196
 
176
197
  def self.has_role?(userRole)
198
+ verify_setup
199
+
177
200
  if user_signed_in?
178
- dt = @decoded_access_token[0]
201
+ dt = decoded_access_token[0]
179
202
  dt = dt["resource_access"][@client_id]
180
203
  if dt != nil
181
204
  dt["roles"].each do |role|
@@ -191,22 +214,50 @@ module Keycloak
191
214
  end
192
215
 
193
216
  def self.user_signed_in?
217
+ verify_setup
218
+
194
219
  begin
195
- get_token_introspection['active']
196
- rescue
197
- @active
220
+ JSON(get_token_introspection)['active'] === true
221
+ rescue => e
222
+ if e.class < Keycloak::KeycloakException
223
+ raise
224
+ else
225
+ false
226
+ end
198
227
  end
199
228
  end
200
229
 
201
230
  def self.get_attribute(attributeName)
202
- attr = @decoded_access_token[0]
231
+ verify_setup
232
+
233
+ attr = decoded_access_token[0]
203
234
  attr[attributeName]
204
235
  end
205
236
 
237
+ def self.token
238
+ unless Keycloak.proc_cookie_token.nil?
239
+ JSON Keycloak.proc_cookie_token.call
240
+ else
241
+ raise Keycloak::ProcCookieTokenNotDefined
242
+ end
243
+ end
244
+
245
+ def self.external_attributes
246
+ unless Keycloak.proc_external_attributes.nil?
247
+ Keycloak.proc_external_attributes.call
248
+ else
249
+ raise Keycloak::ProcExternalAttributesNotDefined
250
+ end
251
+ end
252
+
206
253
  private
207
254
 
208
255
  KEYCLOACK_CONTROLLER_DEFAULT = 'session'
209
256
 
257
+ def self.verify_setup
258
+ get_installation if @configuration.nil?
259
+ end
260
+
210
261
  def self.setup_module
211
262
  Keycloak.proxy ||= ''
212
263
  Keycloak.keycloak_controller ||= KEYCLOACK_CONTROLLER_DEFAULT
@@ -227,9 +278,9 @@ module Keycloak
227
278
 
228
279
  def self.openid_configuration
229
280
  RestClient.proxy = Keycloak.proxy unless Keycloak.proxy.empty?
230
- full_url = "#{@url}/realms/#{@realm}/.well-known/openid-configuration"
281
+ configUrl = "#{@url}/realms/#{@realm}/.well-known/openid-configuration"
231
282
  _request = -> do
232
- RestClient.get full_url
283
+ RestClient.get configUrl
233
284
  end
234
285
  response = exec_request _request
235
286
  if response.code == 200
@@ -239,14 +290,6 @@ module Keycloak
239
290
  end
240
291
  end
241
292
 
242
- def self.reset_active(resetExternalAttributes = true)
243
- @active = false
244
- @userinfo = nil
245
- if resetExternalAttributes
246
- @external_attributes = nil
247
- end
248
- end
249
-
250
293
  def self.mount_request_token(payload)
251
294
  header = {'Content-Type' => 'application/x-www-form-urlencoded'}
252
295
 
@@ -254,15 +297,7 @@ module Keycloak
254
297
  RestClient.post(@configuration['token_endpoint'], payload, header){|response, request, result|
255
298
  case response.code
256
299
  when 200
257
- @active = true
258
- @token = JSON response.body
259
- @decoded_access_token = JWT.decode @token["access_token"], @public_key, false, { :algorithm => 'RS256' }
260
- @decoded_refresh_token = JWT.decode @token["refresh_token"], @public_key, false, { :algorithm => 'RS256' }
261
- if @token["id_token"]
262
- @decoded_id_token = JWT.decode @token["id_token"], @public_key, false, { :algorithm => 'RS256' }
263
- end
264
- Keycloak::Admin.setup_admin(@auth_server_url, @realm, @token["access_token"])
265
- @token
300
+ response.body
266
301
  else
267
302
  response.return!
268
303
  end
@@ -272,19 +307,28 @@ module Keycloak
272
307
  exec_request _request
273
308
  end
274
309
 
310
+ def self.decoded_access_token
311
+ JWT.decode self.token["access_token"], @public_key, false, { :algorithm => 'RS256' }
312
+ end
313
+
314
+ def self.decoded_refresh_token
315
+ JWT.decode self.token["refresh_token"], @public_key, false, { :algorithm => 'RS256' }
316
+ end
317
+
318
+ def self.decoded_id_token
319
+ tk = self.token
320
+ if tk["id_token"]
321
+ @decoded_id_token = JWT.decode tk["id_token"], @public_key, false, { :algorithm => 'RS256' }
322
+ end
323
+ end
324
+
275
325
  end
276
326
 
277
327
  # Os recursos desse module (admin) serão utilizadas apenas por usuários que possuem as roles do client realm-management
278
328
  module Admin
279
329
 
280
330
  class << self
281
- attr_reader :access_token, :auth_server_url, :realm
282
- end
283
331
 
284
- def self.setup_admin(auth_server_url, realm, access_token)
285
- @auth_server_url = auth_server_url
286
- @access_token = access_token
287
- @realm = realm
288
332
  end
289
333
 
290
334
  def self.get_users( queryParameters = nil)
@@ -407,25 +451,25 @@ module Keycloak
407
451
  # Generics methods
408
452
 
409
453
  def self.generic_get(service, queryParameters = nil)
410
- Keycloak.generic_request(@access_token, full_url(service), queryParameters, nil, 'GET')
454
+ Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, nil, 'GET')
411
455
  end
412
456
 
413
457
  def self.generic_post(service, queryParameters, bodyParameter)
414
- Keycloak.generic_request(@access_token, full_url(service), queryParameters, bodyParameter, 'POST')
458
+ Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, bodyParameter, 'POST')
415
459
  end
416
460
 
417
461
  def self.generic_put(service, queryParameters, bodyParameter)
418
- Keycloak.generic_request(@access_token, full_url(service), queryParameters, bodyParameter, 'PUT')
462
+ Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, bodyParameter, 'PUT')
419
463
  end
420
464
 
421
465
  def self.generic_delete(service, queryParameters = nil, bodyParameter = nil)
422
- Keycloak.generic_request(@access_token, full_url(service), queryParameters, bodyParameter, 'DELETE')
466
+ Keycloak.generic_request(Keycloak::Client.token['access_token'], full_url(service), queryParameters, bodyParameter, 'DELETE')
423
467
  end
424
468
 
425
469
  private
426
470
 
427
471
  def self.base_url
428
- @auth_server_url + "/admin/realms/#{@realm}/"
472
+ Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/"
429
473
  end
430
474
 
431
475
  def self.full_url(service)
@@ -438,13 +482,13 @@ module Keycloak
438
482
  include Keycloak::Admin
439
483
 
440
484
  class << self
441
- attr_accessor :admin_user, :admin_password
485
+ attr_accessor
442
486
  end
443
487
 
444
488
  def self.change_password(userID, redirectURI = '')
445
489
  proc = lambda {|token|
446
490
  Keycloak.generic_request(token["access_token"],
447
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/users/#{userID}/execute-actions-email",
491
+ Keycloak::Admin.full_url("users/#{userID}/execute-actions-email"),
448
492
  {:redirect_uri => redirectURI, :client_id => Keycloak::Client.client_id},
449
493
  ['UPDATE_PASSWORD'],
450
494
  'PUT')
@@ -460,9 +504,9 @@ module Keycloak
460
504
 
461
505
  def self.get_logged_user_info
462
506
  proc = lambda {|token|
463
- userinfo = Keycloak::Client.get_userinfo
507
+ userinfo = JSON Keycloak::Client.get_userinfo
464
508
  Keycloak.generic_request(token["access_token"],
465
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/users/#{userinfo['sub']}",
509
+ Keycloak::Admin.full_url("users/#{userinfo['sub']}"),
466
510
  nil, nil, 'GET')
467
511
  }
468
512
 
@@ -477,7 +521,7 @@ module Keycloak
477
521
  search = {:email => userLogin}
478
522
  end
479
523
  users = JSON Keycloak.generic_request(token["access_token"],
480
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/users/",
524
+ Keycloak::Admin.full_url("users/"),
481
525
  search, nil, 'GET')
482
526
  users[0]
483
527
  if users.count == 0
@@ -529,7 +573,7 @@ module Keycloak
529
573
  :enabled => true}
530
574
 
531
575
  if !newUser || Keycloak.generic_request(token["access_token"],
532
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/users/",
576
+ Keycloak::Admin.full_url("users/"),
533
577
  nil, userRepresentation, 'POST')
534
578
 
535
579
  user = get_user_info(userName, true) if newUser
@@ -539,18 +583,18 @@ module Keycloak
539
583
  :value => password}
540
584
 
541
585
  if Keycloak.generic_request(token["access_token"],
542
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/users/#{user['id']}/reset-password",
586
+ Keycloak::Admin.full_url("users/#{user['id']}/reset-password"),
543
587
  nil, credentialRepresentation, 'PUT')
544
588
 
545
589
  client = JSON Keycloak.generic_request(token["access_token"],
546
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/clients/",
590
+ Keycloak::Admin.full_url("clients/"),
547
591
  {:clientId => Keycloak::Client.client_id}, nil, 'GET')
548
592
 
549
593
  roles = Array.new
550
594
  clientRolesNames.each do |r|
551
595
  if r && !r.empty?
552
596
  role = JSON Keycloak.generic_request(token["access_token"],
553
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/clients/#{client[0]['id']}/roles/#{r}",
597
+ Keycloak::Admin.full_url("clients/#{client[0]['id']}/roles/#{r}"),
554
598
  nil, nil, 'GET')
555
599
  roles.push(role)
556
600
  end
@@ -558,7 +602,7 @@ module Keycloak
558
602
 
559
603
  if roles.count > 0
560
604
  Keycloak.generic_request(token["access_token"],
561
- Keycloak::Client.auth_server_url + "/admin/realms/#{Keycloak::Client.realm}/users/#{user['id']}/role-mappings/clients/#{client[0]['id']}",
605
+ Keycloak::Admin.full_url("users/#{user['id']}/role-mappings/clients/#{client[0]['id']}"),
562
606
  nil, roles, 'POST')
563
607
  end
564
608
  end
@@ -584,11 +628,9 @@ module Keycloak
584
628
  Keycloak::Client.get_installation
585
629
 
586
630
  payload = {'client_id' => Keycloak::Client.client_id,
587
- 'client_secret' => Keycloak::Client.secret,
588
- 'username' => @admin_user,
589
- 'password' => @admin_password,
590
- 'grant_type' => 'password'
591
- }
631
+ 'client_secret' => Keycloak::Client.secret,
632
+ 'grant_type' => 'client_credentials'
633
+ }
592
634
 
593
635
  header = {'Content-Type' => 'application/x-www-form-urlencoded'}
594
636
 
@@ -633,6 +675,7 @@ module Keycloak
633
675
  private
634
676
 
635
677
  def self.generic_request(accessToken, uri, queryParameters, bodyParameter, method)
678
+ Keycloak::Client.verify_setup
636
679
  final_url = uri
637
680
 
638
681
  header = {'Content-Type' => 'application/x-www-form-urlencoded',
@@ -689,20 +732,19 @@ module Keycloak
689
732
  end
690
733
 
691
734
  def self.rescue_response(response)
692
- @last_response = response
693
- case @last_response.code
735
+ case response.code
694
736
  when 200..399
695
- if @last_response.body.empty?
737
+ if response.body.empty?
696
738
  true
697
739
  else
698
- @last_response.body
740
+ response.body
699
741
  end
700
742
  else
701
743
  if Keycloak.explode_exception
702
- @last_response.return!
744
+ response.return!
703
745
  else
704
746
  begin
705
- @last_response.return!
747
+ response.return!
706
748
  rescue RestClient::ExceptionWithResponse => err
707
749
  err.response
708
750
  rescue Exception => e
@@ -1,3 +1,6 @@
1
1
  module Keycloak
2
- class UserLoginNotFound < StandardError; end
2
+ class KeycloakException < StandardError; end
3
+ class UserLoginNotFound < KeycloakException; end
4
+ class ProcCookieTokenNotDefined < KeycloakException; end
5
+ class ProcExternalAttributesNotDefined < KeycloakException; end
3
6
  end
@@ -1,3 +1,3 @@
1
1
  module Keycloak
2
- VERSION = "1.2.0"
2
+ VERSION = "2.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keycloak
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guilherme Portugues
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-10 00:00:00.000000000 Z
11
+ date: 2017-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler