keycloak 1.2.0 → 2.0.0

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