keycloak 2.3.2 → 2.4.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
  SHA256:
3
- metadata.gz: 978fc047e4ff958ad16097d09cc9b85ec821bf2313cb231301171d2cbbef7ab5
4
- data.tar.gz: 9bdf8d17a3ce8e440f9474df0e56ddfe549ae147b3d4bdfd7f07741afd472788
3
+ metadata.gz: d419a683b8c5acc4e90870947280ad4953e44ffe3a91fc231afc9ed8665226d1
4
+ data.tar.gz: 523aa9997cbacb76ef37a2617b685cc9a919219b2511cd79bd38da0114ca1ccb
5
5
  SHA512:
6
- metadata.gz: dfe47b7aff82b92797ff5182648a09dd1828d3107df2b75f05dd19b446fa4548b2f922f63a275ad1624b1e1ccc861c9b6cdd516ca5a83ebfabfb5d745feb1ade
7
- data.tar.gz: fd6a948686df8474b6dcca4ae4515557e468715a7abb923ee2f9d21624b74c19649f3ca317168303b2bc7d854b8e1a3a1c16130d7ba378cc1806af1f23aae933
6
+ metadata.gz: a5776f216a4ef94247922c5b4837785ab71bb6611fe0bf6cc9f86f30847ae140f6d10634e969e7e3c682d1c87598077a54c387ae6a7f52dbd5582e3d2c17775e
7
+ data.tar.gz: 93d76cc19f4d93efe21bf7697a4f345818f22faaead39ad8376bca6d953dd173781b04877e8f2b32485673195aefeb710cd7a986ce655bf26a754915e75b6247
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  keycloak-*.gem
2
+ .rspec_status
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keycloak (2.3.2)
4
+ keycloak (2.4.0)
5
5
  json
6
6
  jwt
7
7
  rest-client
@@ -10,15 +10,15 @@ GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
12
  diff-lcs (1.3)
13
- domain_name (0.5.20170404)
13
+ domain_name (0.5.20180417)
14
14
  unf (>= 0.0.5, < 1.0.0)
15
15
  http-cookie (1.0.3)
16
16
  domain_name (~> 0.5)
17
17
  json (2.1.0)
18
18
  jwt (2.1.0)
19
- mime-types (3.1)
19
+ mime-types (3.2.2)
20
20
  mime-types-data (~> 3.2015)
21
- mime-types-data (3.2016.0521)
21
+ mime-types-data (3.2018.0812)
22
22
  netrc (0.11.0)
23
23
  rake (10.5.0)
24
24
  rest-client (2.0.2)
@@ -40,7 +40,7 @@ GEM
40
40
  rspec-support (3.7.1)
41
41
  unf (0.1.4)
42
42
  unf_ext
43
- unf_ext (0.0.7.4)
43
+ unf_ext (0.0.7.5)
44
44
 
45
45
  PLATFORMS
46
46
  ruby
@@ -52,4 +52,4 @@ DEPENDENCIES
52
52
  rspec (~> 3.0)
53
53
 
54
54
  BUNDLED WITH
55
- 1.16.1
55
+ 1.16.2
data/README.md CHANGED
@@ -8,6 +8,8 @@ Its development was based on version 3.2 of Keycloak, whose documentation can be
8
8
 
9
9
  Publication of gem: https://rubygems.org/gems/keycloak
10
10
 
11
+ Exemple: https://github.com/imagov/example-gem-keycloak
12
+
11
13
  ## Installation
12
14
 
13
15
  Add this line in your application's <b>gemfile</b>:
@@ -33,7 +35,7 @@ To add the configuration file:
33
35
 
34
36
  Since you already have a Keycloak environment configured and the gem already installed, the next step is to define how the application will authenticate. Keycloak works with key authentication protocols, such as OpenID Connect, Oauth 2.0 and SAML 2.0, integrating system access through Single-Sign On, and can also provide access to <b>LDAP</b> or <b>Active Directory</b> users.
35
37
 
36
- When you register a realm and also a Client in your Keycloak environment, you can download the Client installation file into the root folder of the application so that gem gets the information it needs to interact with Keycloak. To download this, simply access your Client's registry, click the <b>Installation</b> tab, select <b>Keycloak OIDC JSON</b> in the <b>Format option</b> field and click <b>Download</b>. If your application does not only work with a specific client (application server for APIs, for example), then you can tell what is the realm that gem will interact in the `keycloak.rb` configuration file.
38
+ When you register a realm and also a Client in your Keycloak environment, you can download the Client installation file into the `config` folder of the application so that gem gets the information it needs to interact with Keycloak. To download this, simply access your Client's registry, click the <b>Installation</b> tab, select <b>Keycloak OIDC JSON</b> in the <b>Format option</b> field and click <b>Download</b>. If your application does not only work with a specific client (application server for APIs, for example), then you can tell what is the realm that gem will interact in the `keycloak.rb` configuration file.
37
39
 
38
40
  Gem has a main module called <b>Keycloak</b>. Within this module there are three other modules: <b>Client</b>, <b>Admin</b> and <b>Internal</b>.
39
41
 
@@ -41,6 +43,12 @@ Gem has a main module called <b>Keycloak</b>. Within this module there are three
41
43
 
42
44
  The Keycloak module has some attributes and its definitions are fundamental for the perfect functioning of the gem in the application.
43
45
 
46
+ ```ruby
47
+ Keycloak.installation_file = 'path/to/file.json'
48
+ ```
49
+
50
+ Allows you to set the location of installation file if you have one. If not set, it will default to `keycloak.json` in the `config` folder of your repository. In any case, it will use installation file only if it's present.
51
+
44
52
  ```ruby
45
53
  Keycloak.realm
46
54
  ```
@@ -122,7 +130,7 @@ The `Keycloak::Client` module has the methods that represent the <b>endpoint</b>
122
130
  We will detail each of these methods:
123
131
 
124
132
  ```ruby
125
- Keycloak::Client.get_token(user, password)
133
+ Keycloak::Client.get_token(user, password, client_id = '', secret = '')
126
134
  ```
127
135
 
128
136
  If you choose to authenticate users using the screen of your own application, then use this method. Simply invoke it in the method of login in the `controller` defined with the session controller of your application, passing as parameter the <b>user</b> and the <b>password</b> informed by the user. If the authentication is valid, then a JSON containing the `access_token` and the `refresh_token` is returned.
@@ -136,21 +144,35 @@ To authenticate the users of your application using a template configured in Key
136
144
 
137
145
 
138
146
  ```ruby
139
- Keycloak::Client.get_token_by_code(code, redirect_uri)
147
+ Keycloak::Client.get_token_by_code(code, redirect_uri, client_id = '', secret = '')
140
148
  ```
141
149
 
142
150
  When using the `Keycloak::Client.url_login_redirect` method to get a `code`, pass it as a parameter in this method so that Keycloak returns a token, thus logging the user in the application. The second parameter (`redirect_uri`) must be passed so that when a token is made available, Keycloak redirects to the url informed.
143
151
 
144
152
 
145
153
  ```ruby
146
- Keycloak::Client.get_token_by_refresh_token(refresh_token = '')
154
+ Keycloak::Client.get_token_by_exchange(issuer, issuer_token, client_id = '', secret = '')
155
+ ```
156
+
157
+ To get a token through a token previously obtained from a trusted provider (OpenID standard), such as Facebook, Gooble, Twitter, or even another realm configured in the keycloak, simply invoke this method, passing in the `issuer` parameter the provider alias configured in the realm, and in the `issuer_token` parameter the token obtained by that provider. This will return a token authenticated by your realm.
158
+
159
+
160
+ ```ruby
161
+ Keycloak::Client.get_userinfo_issuer(access_token = '', userinfo_endpoint = '')
162
+ ```
163
+
164
+ This method returns the user information of a provider (`issuer` of the `get_token_by_exchange` method represented by the `access_token` passed as parameter. If the `access_token` parameter is not informed, then the gem will get this information in the cookie.
165
+
166
+
167
+ ```ruby
168
+ Keycloak::Client.get_token_by_refresh_token(refresh_token = '', client_id = '', secret = '')
147
169
  ```
148
170
 
149
171
  When the user is already logged in and your application internally tracks the token expiration time provided by Keycloak, then this method can be used to renew that token if it is still valid. To do this, simply pass the `refresh_token` as a parameter. If you do not inform `refresh_token`, gem will use the `refresh_token` stored in the cookie.
150
172
 
151
173
 
152
174
  ```ruby
153
- Keycloak::Client.get_token_introspection(token = '')
175
+ Keycloak::Client.get_token_introspection(token = '', client_id = '', secret = '', token_introspection_endpoint = '')
154
176
  ```
155
177
 
156
178
  This method returns the information from the `token` session passed as parameter. Among the information returned, the most important is the `active` field, since it informs whether the token session passed in the parameter is active or not. This will help your application control whether the logged-in user session has expired or not. If no token is passed as a parameter, gem will use the last `access_token` stored in the application's cookie.
@@ -164,14 +186,14 @@ There are some Keycloak services like <b>password reset</b>, <b>user registratio
164
186
 
165
187
 
166
188
  ```ruby
167
- Keycloak::Client.logout(redirect_uri = '', refresh_token = '')
189
+ Keycloak::Client.logout(redirect_uri = '', refresh_token = '', client_id = '', secret = '', end_session_endpoint = '')
168
190
  ```
169
191
 
170
192
  When used before the expiration of the logged on user's session, this method terminates the session. If the `redirect_uri` parameter is fed, then Keycloak will redirect your application to the url informed after logout. The second parameter is `refresh_token`, obtained at the time of authentication or session update. If the latter is not informed, then the gem will use the `refresh_token` of the cookie
171
193
 
172
194
 
173
195
  ```ruby
174
- Keycloak::Client.get_userinfo(access_token = '')
196
+ Keycloak::Client.get_userinfo(access_token = '', userinfo_endpoint = '')
175
197
  ```
176
198
 
177
199
  This method returns synthetic information from the user represented by the `access_token` passed as a parameter, such as `sub` - which is the authenticated user id -, `preferred_username` - which is the authenticated user name - and `email` - which is the user's email address. If the `access_token` parameter is not informed, then the gem will get this information in the cookie.
@@ -185,14 +207,14 @@ Returns the <b>url</b> for access to the realm user registry of the installation
185
207
 
186
208
 
187
209
  ```ruby
188
- Keycloak::Client.has_role?(user_role, access_token = '')
210
+ Keycloak::Client.has_role?(user_role, access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
189
211
  ```
190
212
 
191
213
  The `has_role?` method decodes the JWT `access_token` and verifies that the user who owns the token has the <b>role</b> informed in the `user_role` parameter. If `access_token` is not informed then gem will use the `access_token` of the cookie.
192
214
 
193
215
 
194
216
  ```ruby
195
- Keycloak::Client.user_signed_in?(access_token = '')
217
+ Keycloak::Client.user_signed_in?(access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
196
218
  ```
197
219
 
198
220
  This method checks whether the `access_token` passed in the parameter is still active. To check whether the user is active or not, the gem invokes the `get_token_introspection` method internally. If `access_token` is not informed then gem will use the `access_token` of the cookie.
@@ -376,8 +398,8 @@ The following are the <b>Generics Methods</b>:
376
398
  Keycloak::Admin.generic_get(service, query_parameters = nil, access_token = nil)
377
399
  ```
378
400
 
379
- `generic_get` permite que você faça requisições de serviços `GET` do <b>Keycloak</b>. A parte da URI que identifica o serviço deve ser passada no parâmetro `service`, com os parâmetros de rota (como o `{client}`, por exemplo) devidamente substituídos. No parâmetro `query_parameters` você poderá passar um `hash` contendo os <b>Queries Parameters</b> da requisição.<br>
380
- Exemplo:
401
+ `generic_get` allows you to make <b>Keycloak</b> `GET` service requests. The part of the URI that identifies the service must be passed in the `service` parameter, already with the route parameters (such as `{client}`, for example) properly replaced. In the `query_parameters` parameter you can pass a `hash` containing the <b>Queries Parameters</b> of the request.<br>
402
+ Example:
381
403
  ```ruby
382
404
  Keycloak::Admin.generic_get("users/", {email: 'admin@test.com'}, "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldU...")
383
405
  ```
@@ -387,107 +409,105 @@ Exemplo:
387
409
  Keycloak::Admin.generic_post(service, query_parameters, body_parameter, access_token = nil)
388
410
  ```
389
411
 
390
- `generic_post` permite que você faça requisições de serviços `POST` do <b>Keycloak</b>. A parte da URI que identifica o serviço deve ser passada no parâmetro `service`, com os parâmetros de rota (como o `{client}`, por exemplo) devidamente substituídos. No parâmetro `query_parameters` você poderá passar um `hash` contendo os <b>Query Parameters</b> da requisição. No parâmetro `body_parameter` você poderá passar um `hash` contendo os <b>Body Parameters</b> da requisição.<br>
391
- Exemplo:
412
+ `generic_post` allows you to make <b>Keycloak</b> `POST` service requests. The part of the URI that identifies the service must be passed in the `service` parameter, already with the route parameters (such as `{client}`, for example) properly replaced. In the `query_parameters` parameter you can pass a `hash` containing the <b>Query Parameters</b> of the request. In the `body_parameter` parameter you can pass a `hash` containing the <b>Body Parameters</b> of the request.<br>
413
+ Example:
392
414
  ```ruby
393
415
  Keycloak::Admin.generic_post("users/", nil, { username: "admin", email: "admin@test.com", enabled: true }, "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldU...")
394
416
  ```
395
417
 
396
-
397
418
  ```ruby
398
419
  Keycloak::Admin.generic_put(service, query_parameters, body_parameter, access_token = nil)
399
420
  ```
400
421
 
401
- `generic_put` permite que você faça requisições de serviços `PUT` do <b>Keycloak</b>. A parte da URI que identifica o serviço deve ser passada no parâmetro `service`, com os parâmetros de rota (como o `{client}`, por exemplo) devidamente substituídos. No parâmetro `query_parameters` você poderá passar um `hash` contendo os <b>Query Parameters</b> da requisição. No parâmetro `body_parameter` você poderá passar um `hash` contendo os <b>Body Parameters</b> da requisição.
422
+ `generic_put` allows you to make <b>Keycloak</b> `PUT` service requests. The part of the URI that identifies the service must be passed in the `service` parameter, already with the route parameters (such as `{client}`, for example) properly replaced. In the `query_parameters` parameter you can pass a `hash` containing the <b>Query Parameters</b> of the request. In the `body_parameter` parameter you can pass a `hash` containing the <b>Body Parameters</b> of the request.
402
423
 
403
424
 
404
425
  ```ruby
405
426
  Keycloak::Admin.generic_delete(service, query_parameters = nil, body_parameter = nil, access_token = nil)
406
427
  ```
407
428
 
408
- `generic_delete` permite que você faça requisições de serviços `DELETE` do <b>Keycloak</b>. A parte da URI que identifica o serviço deve ser passada no parâmetro `service`, com os parâmetros de rota (como o `{client}`, por exemplo) devidamente substituídos. No parâmetro `query_parameters` você poderá passar um `hash` contendo os <b>Query Parameters</b> da requisição. No parâmetro `body_parameter` você poderá passar um `hash` contendo os <b>Body Parameters</b> da requisição.
409
-
429
+ `generic_delete` allows you to make <b>Keycloak</b> `DELETE` service requests. The part of the URI that identifies the service must be passed in the `service` parameter, already with the route parameters (such as `{client}`, for example) properly replaced. In the `query_parameters` parameter you can pass a `hash` containing the <b>Query Parameters</b> of the request. In the `body_parameter` parameter you can pass a `hash` containing the <b>Body Parameters</b> of the request.
410
430
 
411
431
 
412
432
  ### Keycloak::Internal
413
433
 
414
- O módulo `Keycloak::internal`disponibiliza métodos criados para facilitar a interação entre a aplicação e o <b>Keycloak</b>. Partindo das informações encontradas no arquivo de instalação `keycloak.json`, todos os métodos invocados serão autenticados automaticamente, utilizando as credências da aplicação (`grant_type = client_credentials`), dependendo assim dos <b>roles</b> atribuídos a mesma para que o retorno da requisição seja autorizado.
434
+ The `Keycloak::internal` module provides methods designed to facilitate interaction between the application and <b>Keycloak</b>. From the information found in the `keycloak.json` installation file, all invoked methods will be authenticated automatically, using the application credentials (`grant_type = client_credentials`), depending on the assigned roles assigned to it. request is authorized.
415
435
 
416
436
 
417
437
  ```ruby
418
- Keycloak::Internal.get_users(query_parameters = nil)
438
+ Keycloak::Internal.get_users(query_parameters = nil, client_id = '', secret = '')
419
439
  ```
420
440
 
421
- `get_users` invoca o método `Keycloak::Admin.get_users` que, por sua vez, retorna uma lista de usuários, filtrada de acordo com o hash de parâmetros passado em `query_parameters`.
441
+ `get_users` invokes the `Keycloak::Admin.get_users` method that returns a list of users, filtered according to the parameters hash passed in `query_parameters`.
422
442
 
423
443
 
424
444
  ```ruby
425
- Keycloak::Internal.change_password(user_id, redirect_uri = '')
445
+ Keycloak::Internal.change_password(user_id, redirect_uri = '', client_id = '', secret = '')
426
446
  ```
427
447
 
428
- `change_password` invocará a API `PUT /admin/realms/{realm}/users/{id}/execute-actions-email` do Keycloak requisitando a action `UPDATE_PASSWORD`. Isso fará com que o Keycloak dispare um e-mail para o usuário representado pelo parâmetro `user_id`. O parâmetro `redirect_uri` é opcional. Se não for preenchido, então não haverá nenhum link para clicar após a ação de reset de senha ter sido concluída.
448
+ `change_password` will invoke the Keycloak `PUT /admin/realms/{realm}/users/{id}/execute-actions-email` API requesting the `UPDATE_PASSWORD` action. This will cause Keycloak to trigger an email to the user represented by the `user_id` parameter. The `redirect_uri` parameter is optional. If it is not filled, then there will be no link to click after the password reset action has been completed.
429
449
 
430
450
 
431
451
  ```ruby
432
- Keycloak::Internal.get_user_info(user_login, whole_word = false)
452
+ Keycloak::Internal.get_user_info(user_login, whole_word = false, client_id = '', secret = ''))
433
453
  ```
434
454
 
435
- `get_user_info`, baseado no parâmetro `user_login`, que poderá recepcionar o `username` ou o `email` do usuário, retornará uma lista (array) de [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) no caso em que o parâmetro `whole_word` for `false`, ou retornará um [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) quando o parâmetro `whole_word` for `true`. O parâmetro `whole_word` indica se o método deverá considerar usuários que tenham no `username` ou `email` parte da expressão passada no parâmetro `user_login` - para os casos de `whole_word = false` -, ou que tenha exatamente a expressão passada nesse parâmetro - para os casos de `whole_word = true`.
455
+ `get_user_info`, based on the `user_login` parameter, which will be able to receive the `username` or the `email` of the user, will return an array of [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) in the case where the `whole_word` parameter is `false`, or it will return a [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) when the `whole_word` parameter is `true`. The `whole_word` parameter indicates whether the method should consider users that have `username` or `email` part of the expression passed in the `user_login` parameter - for the cases of `whole_word = false` - or that has exactly the last expression in this parameter - for the cases of `whole_word = true`.
436
456
 
437
457
 
438
458
  ```ruby
439
- Keycloak::Internal.forgot_password(user_login, redirect_uri = '')
459
+ Keycloak::Internal.forgot_password(user_login, redirect_uri = '', client_id = '', secret = '')
440
460
  ```
441
461
 
442
- `forgot_password` invocará o método `Keycloak::Internal.change_password` após invocar o método `Keycloak::Internal.get_user_info` - passando no parâmetro `user_login` do método descrito o parâmetro `user_login`deste tópico e passando `true` no parâmetro `whole_word` -. A utilização deste método é indicado para os casos de aplicações permitam o reset da senha dos usuários sem que o mesmo esteja logado.
462
+ `forgot_password` will invoke the `Keycloak::Internal.change_password` method after invoking the `Keycloak::Internal.get_user_info` method - passing in the `user_login` parameter of the described method the `user_login` parameter of this topic and passing `true` in the parameter `whole_word`. The use of this method is indicated for the cases of applications allow the reset of the password of the users without it is logged in.
443
463
 
444
464
 
445
465
  ```ruby
446
- Keycloak::Internal.exists_name_or_email(value, user_id = '')
466
+ Keycloak::Internal.exists_name_or_email(value, user_id = '', client_id = '', secret = '')
447
467
  ```
448
468
 
449
- `exists_name_or_email` verifica se no reino existe algum usuário com `username` ou o `email` passado no parâmetro `value`. O parâmetro `user_id` serve para passar o `ID` de um usuário nos casos em que deseja-se alterar o `username` ou o `email` do mesmo, para que assim sejam considerados na verificação do `username` e do `email` usuários diferentes do usuário com o `ID` informado em `user_id`.
469
+ `exists_name_or_email` checks whether a user with `username` or `email` already exists in the `value` parameter in the realm. The `user_id` parameter is used to pass the `ID` of a user in cases where it is desired to change the `username` or `email` of the same, so that they are considered in the `username` and `email verification` different users of the user with the `ID` informed in `user_id`.
450
470
 
451
471
 
452
472
  ```ruby
453
- Keycloak::Internal.get_logged_user_info
473
+ Keycloak::Internal.get_logged_user_info(client_id = '', secret = '')
454
474
  ```
455
475
 
456
- `get_logged_user_info` retorna o [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário logado na aplicação.
476
+ `get_logged_user_info` returns the [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) of the user logged into the application.
457
477
 
458
478
 
459
479
  ```ruby
460
480
  # GET /admin/realms/{realm}/users
461
- Keycloak::Internal.logged_federation_user?
481
+ Keycloak::Internal.logged_federation_user?(client_id = '', secret = '')
462
482
  ```
463
483
 
464
- `logged_federation_user?` incova o método `Keycloak::Internal.get_logged_user_info` e verifica se o mesmo é um <b>Federation User</b> (um usuário do AD por exemplo).
484
+ `logged_federation_user?` method invokes the `Keycloak::Internal.get_logged_user_info` method and checks to see if it is an <b>Federation User</b> (an LDAP user for example).
465
485
 
466
486
 
467
487
  ```ruby
468
488
  # GET /admin/realms/{realm}/users
469
- Keycloak::Internal.create_starter_user(username, password, email, client_roles_names, proc = nil)
489
+ Keycloak::Internal.create_starter_user(username, password, email, client_roles_names, proc = nil, client_id = '', secret = '')
470
490
  ```
471
491
 
472
- `create_starter_user` é indicado para aplicações que permitam a criação de novos usuários sem que um usuário esteja logado ou até mesmo para criar novos usuários a partir do `rake db:seed`. Nos parâmetros `username`, `password` e `email` devem ser passados o nome do usuário, a senha do usuário, e o e-mail do usuário, respectivamente. No parâmetro `client_roles_names`deve ser passado uma lista (array) com o nome dos `roles` do Client que serão atribuídos ao usuário. O parâmetro `proc` trata-se de um método <b>lambda</b> que disponibilizará como parâmetro a [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário criado para que sejam definidas ações por parte da aplicação. Este método terá como retorno o mesmo retorno do método do parâmetro `proc` se o mesmo for definido, caso contrário retornará a [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário criado.
492
+ `create_starter_user` is suitable for applications that allow the creation of new users without a user being logged in or even to create new users from `rake db: seed`. In the `username`, `password` and `email` parameters, the user name, password, and email, respectively, must be passed. In the `client_roles_names` parameter, a list (array) with the name of the `roles` of the Client that will be assigned to the user must be passed. The `proc` parameter is a <b>lambda</b> method that will make available the [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) of the created user as a parameter, so that actions should be defined by the application. This method returns the same return of the `proc` parameter method if it is set, otherwise it will return to [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) of the created user.
473
493
 
474
494
 
475
495
  ```ruby
476
- Keycloak::Internal.get_client_roles
496
+ Keycloak::Internal.get_client_roles(client_id = '', secret = '')
477
497
  ```
478
498
 
479
- `get_client_roles` retornará uma lista (array) de [RoleRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_rolerepresentation) do Client indicado pelo arquivo de instalação `keycloak.json`.
499
+ `get_client_roles` will return an array of [RoleRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_rolerepresentation) from the Client indicated in the `client_id` parameter or, in the absence of this, by the client of the `keycloak.json` installation file.
480
500
 
481
501
 
482
502
  ```ruby
483
- Keycloak::Internal.get_client_user_roles(user_id)
503
+ Keycloak::Internal.get_client_user_roles(user_id, client_id = '', secret = '')
484
504
  ```
485
505
 
486
- `get_client_user_roles` invocará o método `Keycloak::Admin.get_effective_client_level_role_composite_user` considerando o Client indicado pelo arquivo de instalação `keycloak.json` e o usuário representado pelo parâmetro `user_id`.
506
+ `get_client_user_roles` will invoke the `Keycloak::Admin.get_effective_client_level_role_composite_user` method by considering the Client indicated in the `client_id` parameter or, if not, by the client of the `keycloak.json` installation file and the user represented by the `user_id` parameter.
487
507
 
488
508
 
489
509
  ```ruby
490
- Keycloak::Internal.has_role?(user_id, user_role)
510
+ Keycloak::Internal.has_role?(user_id, user_role, client_id = '', secret = '')
491
511
  ```
492
512
 
493
- `has_role?` informará se o usuário representado pelo parâmetro `user_id` possui o <b>role</b> com o nome representado pelo parâmetro `user_role`.
513
+ `has_role?` informing the user represented by the `user_id` parameter has <b>role</b> with the name represented by the `user_role` parameter.
@@ -5,6 +5,8 @@ O seu desenvolvimento foi baseado na versão 3.2 do Keycloak, cuja documentaçã
5
5
 
6
6
  Publicação da gem: https://rubygems.org/gems/keycloak
7
7
 
8
+ Exemplo: https://github.com/imagov/example-gem-keycloak
9
+
8
10
  ## Instalação
9
11
 
10
12
  Adicione esta linha no <b>Gemfile</b> de sua aplicação:
@@ -29,7 +31,7 @@ Para adicionar o arquivo de configuração:
29
31
 
30
32
  Considerando que você já possua um ambiente do Keycloak configurado e a gem já instalada, o próximo passo é definir como será a autenticação da aplicação. O Keycloak trabalha com os principais protocolos de autenticação, tais como o OpenID Connect, Oauth 2.0 e SAML 2.0, integrando acesso a sistemas via Single-Sign On, podendo inclusive disponibilizar acessos a usuários LDAP ou Active Directory.
31
33
 
32
- Ao cadastrar um Reino e também um Client no seu ambiente Keycloak, você poderá fazer o download do arquivo de instalação do Client para dentro da pasta raiz da aplicação, para que a gem obtenha as informações necessárias para interagir com o Keycloak. Para fazer esse download, basta acessar o cadastro de seu Client, clicar na aba <b>Installation</b>, selecionar <b>Keycloak OIDC JSON</b> no campo <b>Format option</b> e clicar em <b>Download</b>. Caso a sua aplicação não trabalhe apenas com um client específico (aplicação servidora de APIs, por exemplo), então você poderá informar o reino que a gem irá interagir no arquivo de configuração `keycloak.rb`.
34
+ Ao cadastrar um Reino e também um Client no seu ambiente Keycloak, você poderá fazer o download do arquivo de instalação do Client para dentro da pasta `config` da aplicação, para que a gem obtenha as informações necessárias para interagir com o Keycloak. Para fazer esse download, basta acessar o cadastro de seu Client, clicar na aba <b>Installation</b>, selecionar <b>Keycloak OIDC JSON</b> no campo <b>Format option</b> e clicar em <b>Download</b>. Caso a sua aplicação não trabalhe apenas com um client específico (aplicação servidora de APIs, por exemplo), então você poderá informar o reino que a gem irá interagir no arquivo de configuração `keycloak.rb`.
33
35
 
34
36
  A gem possui um módulo principal chamado <b>Keycloak</b>. Dentro desse módulo há três outros módulos: <b>Client</b>, <b>Admin</b> e <b>Internal</b>.
35
37
 
@@ -37,6 +39,12 @@ A gem possui um módulo principal chamado <b>Keycloak</b>. Dentro desse módulo
37
39
 
38
40
  O módulo Keycloak possui alguns atributos e suas definições são fundamentais para o perfeito funcionamento da gem na aplicação.
39
41
 
42
+ ```ruby
43
+ Keycloak.installation_file = 'path/to/file.json'
44
+ ```
45
+
46
+ Permite você determinar o local do arquivo de instalação do Keycloak, caso você esteja utilizando um. Se não for informado, o caminho default será `config/Keycloak.json`.
47
+
40
48
  ```ruby
41
49
  Keycloak.realm
42
50
  ```
@@ -116,7 +124,7 @@ Vamos ao detalhamento de cada um desses métodos:
116
124
 
117
125
 
118
126
  ```ruby
119
- Keycloak::Client.get_token(user, password)
127
+ Keycloak::Client.get_token(user, password, client_id = '', secret = '')
120
128
  ```
121
129
 
122
130
  Caso você opte por efetuar a autenticação dos usuários utilizando a tela da sua própria aplicação, então utilize esse método. Basta invocá-lo no método de login no `controller` definido com o controlador de sessão de sua aplicação, passando como parâmetro o <b>usuário</b> e a <b>senha</b> informados pelo usuário. Caso a autenticação seja válida, então será retornado um JSON contendo entre as informações principais o `access_token` e o `refresh_token`.
@@ -130,35 +138,35 @@ Para efetuar a autenticação dos usuários de sua aplicação utilizando um tem
130
138
 
131
139
 
132
140
  ```ruby
133
- Keycloak::Client.get_token_by_code(code, redirect_uri)
141
+ Keycloak::Client.get_token_by_code(code, redirect_uri, client_id = '', secret = '')
134
142
  ```
135
143
 
136
144
  Ao utilizar o método `Keycloak::Client.url_login_redirect` para obter um `code`, passe-o como parâmetro neste método para que o Keycloak retorne um token, efetuando assim o login do usuário na aplicação. O segundo parâmetro (`redirect_uri`) deve ser passado para que, ao disponibilizar um token, o Keycloak redirecione para a url informada.
137
145
 
138
146
 
139
147
  ```ruby
140
- Keycloak::Client.get_token_by_exchange(issuer, issuer_token)
148
+ Keycloak::Client.get_token_by_exchange(issuer, issuer_token, client_id = '', secret = '')
141
149
  ```
142
150
 
143
151
  Para obter um token através de um token obtido anteriormente de um provedor confiável (padrão OpenID), como Facebook, Gooble, Twitter, ou até mesmo outro reino configurado no keycloak, basta invocar este método, passando no parâmetro `issuer` o alias do provedor configurado no reino, e, no parâmetro `issuer_token` o token obtido por esse provedor. Com isso, será retornado um token autenticado pelo teu reino.
144
152
 
145
153
 
146
154
  ```ruby
147
- Keycloak::Client.get_userinfo_issuer(access_token = '')
155
+ Keycloak::Client.get_userinfo_issuer(access_token = '', userinfo_endpoint = '')
148
156
  ```
149
157
 
150
158
  Esse método retorna as informações do usuário de um provevedor (`issuer` do método `get_token_by_exchange`) representado pelo `access_token` passado como parâmetro. Caso o parâmetro `access_token` não seja informado, então a gem obterá essa informação no cookie.
151
159
 
152
160
 
153
161
  ```ruby
154
- Keycloak::Client.get_token_by_refresh_token(refresh_token = '')
162
+ Keycloak::Client.get_token_by_refresh_token(refresh_token = '', client_id = '', secret = '')
155
163
  ```
156
164
 
157
165
  Quando o usuário já estiver logado e a sua aplicação acompanhar internamente o tempo de expiração do token fornecido pelo Keycloak, então esse método poderá ser utilizado para a renovação desse token, caso o mesmo ainda seja válido. Para isso, basta passar como parãmetro o `refresh_token`. Caso não seja informado o `refresh_token`, a gem utilizará o `refresh_token` armazenado no cookie.
158
166
 
159
167
 
160
168
  ```ruby
161
- Keycloak::Client.get_token_introspection(token = '')
169
+ Keycloak::Client.get_token_introspection(token = '', client_id = '', secret = '', token_introspection_endpoint = '')
162
170
  ```
163
171
 
164
172
  Esse método retorna a as informações da sessão do `token` passado como parâmetro. Entre as informações retornadas, a mais importante é o campo `active`, pois ele informa se a sessão do token passado no parâmetro é ativo ou não. Isso auxiliará a sua aplicação a controlar se a sessão do usuário logado expirou ou não. Caso nenhum token seja passado como parâmetro, a gem utilizará o último `access_token` armazenado no cookie da aplicação.
@@ -172,14 +180,14 @@ Há alguns serviços do Keycloak como <b>reset de senha</b>, <b>cadastro de usu
172
180
 
173
181
 
174
182
  ```ruby
175
- Keycloak::Client.logout(redirect_uri = '', refresh_token = '')
183
+ Keycloak::Client.logout(redirect_uri = '', refresh_token = '', client_id = '', secret = '', end_session_endpoint = '')
176
184
  ```
177
185
 
178
186
  Quando utilizado antes da expiração da sessão do usuário logado, esse método encerra a sessão. Se o parâmetro `redirect_uri` for alimentado, então o Keycloak redirecionará a sua aplicação para a url informada após a efetuação do logout. O segundo parâmetro é o `refresh_token` obtido no momento da autenticação ou da atualização da sessão. Caso este último não seja informado, então a gem utilizará o `refresh_token` do cookie.
179
187
 
180
188
 
181
189
  ```ruby
182
- Keycloak::Client.get_userinfo(access_token = '')
190
+ Keycloak::Client.get_userinfo(access_token = '', userinfo_endpoint = '')
183
191
  ```
184
192
 
185
193
  Esse método retorna informações sintéticas do usuário representado pelo `access_token` passado como parâmetro, tais como `sub` - que é o Id do usuário autenticado -, `preferred_username` - que é o nome do usuário autenticado - e `email` - que é o e-mail do usuário. Caso o parâmetro `access_token` não seja informado, então a gem obterá essa informação no cookie.
@@ -193,14 +201,14 @@ Retorna a <b>url</b> para acesso ao cadastro de usuários do Reino do arquivo de
193
201
 
194
202
 
195
203
  ```ruby
196
- Keycloak::Client.has_role?(user_role, access_token = '')
204
+ Keycloak::Client.has_role?(user_role, access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
197
205
  ```
198
206
 
199
207
  O método `has_role?` decodifica o JWT `access_token` e verifica se o usuário dono do token possui o <b>role</b> informado no parâmetro `user_role`. Caso o `access_token` não seja informado, então a gem utilizará o `access_token` do cookie.
200
208
 
201
209
 
202
210
  ```ruby
203
- Keycloak::Client.user_signed_in?(access_token = '')
211
+ Keycloak::Client.user_signed_in?(access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
204
212
  ```
205
213
 
206
214
  Esse método verifica se o `access_token` passado no parâmetro ainda está ativo. Para verificar se o usuário está ativo ou não, internamente a gem invoca o método `get_token_introspection`. Caso o `access_token` não seja informado, então a gem utilizará o `access_token` do cookie.
@@ -422,46 +430,46 @@ Keycloak::Admin.generic_delete(service, query_parameters = nil, body_parameter =
422
430
 
423
431
  ### Keycloak::Internal
424
432
 
425
- O módulo `Keycloak::internal`disponibiliza métodos criados para facilitar a interação entre a aplicação e o <b>Keycloak</b>. Partindo das informações encontradas no arquivo de instalação `keycloak.json`, todos os métodos invocados serão autenticados automaticamente, utilizando as credências da aplicação (`grant_type = client_credentials`), dependendo assim dos <b>roles</b> atribuídos a mesma para que o retorno da requisição seja autorizado.
433
+ O módulo `Keycloak::internal` disponibiliza métodos criados para facilitar a interação entre a aplicação e o <b>Keycloak</b>. Partindo das informações encontradas no arquivo de instalação `keycloak.json`, todos os métodos invocados serão autenticados automaticamente, utilizando as credências da aplicação (`grant_type = client_credentials`), dependendo assim dos <b>roles</b> atribuídos a mesma para que o retorno da requisição seja autorizado.
426
434
 
427
435
 
428
436
  ```ruby
429
- Keycloak::Internal.get_users(query_parameters = nil)
437
+ Keycloak::Internal.get_users(query_parameters = nil, client_id = '', secret = '')
430
438
  ```
431
439
 
432
440
  `get_users` invoca o método `Keycloak::Admin.get_users` que, por sua vez, retorna uma lista de usuários, filtrada de acordo com o hash de parâmetros passado em `query_parameters`.
433
441
 
434
442
 
435
443
  ```ruby
436
- Keycloak::Internal.change_password(user_id, redirect_uri = '')
444
+ Keycloak::Internal.change_password(user_id, redirect_uri = '', client_id = '', secret = '')
437
445
  ```
438
446
 
439
447
  `change_password` invocará a API `PUT /admin/realms/{realm}/users/{id}/execute-actions-email` do Keycloak requisitando a action `UPDATE_PASSWORD`. Isso fará com que o Keycloak dispare um e-mail para o usuário representado pelo parâmetro `user_id`. O parâmetro `redirect_uri` é opcional. Se não for preenchido, então não haverá nenhum link para clicar após a ação de reset de senha ter sido concluída.
440
448
 
441
449
 
442
450
  ```ruby
443
- Keycloak::Internal.get_user_info(user_login, whole_word = false)
451
+ Keycloak::Internal.get_user_info(user_login, whole_word = false, client_id = '', secret = ''))
444
452
  ```
445
453
 
446
454
  `get_user_info`, baseado no parâmetro `user_login`, que poderá recepcionar o `username` ou o `email` do usuário, retornará uma lista (array) de [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) no caso em que o parâmetro `whole_word` for `false`, ou retornará um [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) quando o parâmetro `whole_word` for `true`. O parâmetro `whole_word` indica se o método deverá considerar usuários que tenham no `username` ou `email` parte da expressão passada no parâmetro `user_login` - para os casos de `whole_word = false` -, ou que tenha exatamente a expressão passada nesse parâmetro - para os casos de `whole_word = true`.
447
455
 
448
456
 
449
457
  ```ruby
450
- Keycloak::Internal.forgot_password(user_login, redirect_uri = '')
458
+ Keycloak::Internal.forgot_password(user_login, redirect_uri = '', client_id = '', secret = '')
451
459
  ```
452
460
 
453
- `forgot_password` invocará o método `Keycloak::Internal.change_password` após invocar o método `Keycloak::Internal.get_user_info` - passando no parâmetro `user_login` do método descrito o parâmetro `user_login`deste tópico e passando `true` no parâmetro `whole_word` -. A utilização deste método é indicado para os casos de aplicações permitam o reset da senha dos usuários sem que o mesmo esteja logado.
461
+ `forgot_password` invocará o método `Keycloak::Internal.change_password` após invocar o método `Keycloak::Internal.get_user_info` - passando no parâmetro `user_login` do método descrito o parâmetro `user_login`deste tópico e passando `true` no parâmetro `whole_word`. A utilização deste método é indicado para os casos de aplicações permitam o reset da senha dos usuários sem que o mesmo esteja logado.
454
462
 
455
463
 
456
464
  ```ruby
457
- Keycloak::Internal.exists_name_or_email(value, user_id = '')
465
+ Keycloak::Internal.exists_name_or_email(value, user_id = '', client_id = '', secret = '')
458
466
  ```
459
467
 
460
468
  `exists_name_or_email` verifica se no reino já existe algum usuário com `username` ou o `email` passado no parâmetro `value`. O parâmetro `user_id` serve para passar o `ID` de um usuário nos casos em que deseja-se alterar o `username` ou o `email` do mesmo, para que assim sejam considerados na verificação do `username` e do `email` usuários diferentes do usuário com o `ID` informado em `user_id`.
461
469
 
462
470
 
463
471
  ```ruby
464
- Keycloak::Internal.get_logged_user_info
472
+ Keycloak::Internal.get_logged_user_info(client_id = '', secret = '')
465
473
  ```
466
474
 
467
475
  `get_logged_user_info` retorna o [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário logado na aplicação.
@@ -469,36 +477,36 @@ Keycloak::Internal.get_logged_user_info
469
477
 
470
478
  ```ruby
471
479
  # GET /admin/realms/{realm}/users
472
- Keycloak::Internal.logged_federation_user?
480
+ Keycloak::Internal.logged_federation_user?(client_id = '', secret = '')
473
481
  ```
474
482
 
475
- `logged_federation_user?` incova o método `Keycloak::Internal.get_logged_user_info` e verifica se o mesmo é um <b>Federation User</b> (um usuário do AD por exemplo).
483
+ `logged_federation_user?` incova o método `Keycloak::Internal.get_logged_user_info` e verifica se o mesmo é um <b>Federation User</b> (um usuário do LDAP por exemplo).
476
484
 
477
485
 
478
486
  ```ruby
479
487
  # GET /admin/realms/{realm}/users
480
- Keycloak::Internal.create_starter_user(username, password, email, client_roles_names, proc = nil)
488
+ Keycloak::Internal.create_starter_user(username, password, email, client_roles_names, proc = nil, client_id = '', secret = '')
481
489
  ```
482
490
 
483
- `create_starter_user` é indicado para aplicações que permitam a criação de novos usuários sem que um usuário esteja logado ou até mesmo para criar novos usuários a partir do `rake db:seed`. Nos parâmetros `username`, `password` e `email` devem ser passados o nome do usuário, a senha do usuário, e o e-mail do usuário, respectivamente. No parâmetro `client_roles_names`deve ser passado uma lista (array) com o nome dos `roles` do Client que serão atribuídos ao usuário. O parâmetro `proc` trata-se de um método <b>lambda</b> que disponibilizará como parâmetro a [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário criado para que sejam definidas ações por parte da aplicação. Este método terá como retorno o mesmo retorno do método do parâmetro `proc` se o mesmo for definido, caso contrário retornará a [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário criado.
491
+ `create_starter_user` é indicado para aplicações que permitam a criação de novos usuários sem que um usuário esteja logado ou até mesmo para criar novos usuários a partir do `rake db:seed`. Nos parâmetros `username`, `password` e `email` devem ser passados o nome, a senha, e o e-mail do usuário, respectivamente. No parâmetro `client_roles_names`deve ser passado uma lista (array) com o nome dos `roles` do Client que serão atribuídos ao usuário. O parâmetro `proc` trata-se de um método <b>lambda</b> que disponibilizará como parâmetro a [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário criado para que sejam definidas ações por parte da aplicação. Esse método terá como retorno o mesmo retorno do método do parâmetro `proc` se o mesmo for definido, caso contrário retornará a [UserRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_userrepresentation) do usuário criado.
484
492
 
485
493
 
486
494
  ```ruby
487
- Keycloak::Internal.get_client_roles
495
+ Keycloak::Internal.get_client_roles(client_id = '', secret = '')
488
496
  ```
489
497
 
490
- `get_client_roles` retornará uma lista (array) de [RoleRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_rolerepresentation) do Client indicado pelo arquivo de instalação `keycloak.json`.
498
+ `get_client_roles` retornará uma lista (array) de [RoleRepresentation](http://www.keycloak.org/docs-api/3.2/rest-api/index.html#_rolerepresentation) do Client indicado no parâmetro `client_id` ou, na falta desse, pelo Client do arquivo de instalação `keycloak.json`.
491
499
 
492
500
 
493
501
  ```ruby
494
- Keycloak::Internal.get_client_user_roles(user_id)
502
+ Keycloak::Internal.get_client_user_roles(user_id, client_id = '', secret = '')
495
503
  ```
496
504
 
497
- `get_client_user_roles` invocará o método `Keycloak::Admin.get_effective_client_level_role_composite_user` considerando o Client indicado pelo arquivo de instalação `keycloak.json` e o usuário representado pelo parâmetro `user_id`.
505
+ `get_client_user_roles` invocará o método `Keycloak::Admin.get_effective_client_level_role_composite_user` considerando o Client indicado no parâmetro `client_id` ou, na falta desse, pelo Client do arquivo de instalação `keycloak.json` e o usuário representado pelo parâmetro `user_id`.
498
506
 
499
507
 
500
508
  ```ruby
501
- Keycloak::Internal.has_role?(user_id, user_role)
509
+ Keycloak::Internal.has_role?(user_id, user_role, client_id = '', secret = '')
502
510
  ```
503
511
 
504
512
  `has_role?` informará se o usuário representado pelo parâmetro `user_id` possui o <b>role</b> com o nome representado pelo parâmetro `user_role`.
@@ -6,33 +6,47 @@ require 'base64'
6
6
  require 'uri'
7
7
 
8
8
  module Keycloak
9
+ OLD_KEYCLOAK_JSON_FILE = 'keycloak.json'
10
+ KEYCLOAK_JSON_FILE = 'config/keycloak.json'
11
+
9
12
  class << self
10
13
  attr_accessor :proxy, :generate_request_exception, :keycloak_controller,
11
14
  :proc_cookie_token, :proc_external_attributes,
12
15
  :realm, :auth_server_url
13
16
  end
14
17
 
15
-
16
18
  def self.explode_exception
17
- if Keycloak.generate_request_exception == nil
18
- Keycloak.generate_request_exception = true
19
- end
19
+ Keycloak.generate_request_exception = true if Keycloak.generate_request_exception.nil?
20
20
  Keycloak.generate_request_exception
21
21
  end
22
22
 
23
+ def self.installation_file
24
+ if File.exists?(KEYCLOAK_JSON_FILE)
25
+ @installation_file ||= KEYCLOAK_JSON_FILE
26
+ else
27
+ @installation_file ||= OLD_KEYCLOAK_JSON_FILE
28
+ end
29
+ end
30
+
31
+ def self.installation_file=(file = nil)
32
+ raise InstallationFileNotFound unless file.instance_of?(String) && File.exists?(file)
33
+ @installation_file = file || KEYCLOAK_JSON_FILE
34
+ end
35
+
23
36
  module Client
24
37
  class << self
25
38
  attr_accessor :realm, :auth_server_url
26
39
  attr_reader :client_id, :secret, :configuration, :public_key
27
40
  end
28
41
 
29
- KEYCLOAK_JSON_FILE = 'keycloak.json'
30
-
31
- def self.get_token(user, password)
42
+ def self.get_token(user, password, client_id = '', secret = '')
32
43
  setup_module
33
44
 
34
- payload = { 'client_id' => @client_id,
35
- 'client_secret' => @secret,
45
+ client_id = @client_id if client_id.blank?
46
+ secret = @secret if secret.blank?
47
+
48
+ payload = { 'client_id' => client_id,
49
+ 'client_secret' => secret,
36
50
  'username' => user,
37
51
  'password' => password,
38
52
  'grant_type' => 'password' }
@@ -40,11 +54,14 @@ module Keycloak
40
54
  mount_request_token(payload)
41
55
  end
42
56
 
43
- def self.get_token_by_code(code, redirect_uri)
57
+ def self.get_token_by_code(code, redirect_uri, client_id = '', secret = '')
44
58
  verify_setup
45
59
 
46
- payload = { 'client_id' => @client_id,
47
- 'client_secret' => @secret,
60
+ client_id = @client_id if client_id.blank?
61
+ secret = @secret if secret.blank?
62
+
63
+ payload = { 'client_id' => client_id,
64
+ 'client_secret' => secret,
48
65
  'code' => code,
49
66
  'grant_type' => 'authorization_code',
50
67
  'redirect_uri' => redirect_uri }
@@ -52,48 +69,55 @@ module Keycloak
52
69
  mount_request_token(payload)
53
70
  end
54
71
 
55
- def self.get_token_by_exchange(issuer, issuer_token)
56
- setup_module
57
-
58
- payload = { 'client_id' => @client_id, 'client_secret' => @secret, 'audience' => @client_id, 'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange', 'subject_token_type' => 'urn:ietf:params:oauth:token-type:access_token', 'subject_issuer' => issuer, 'subject_token' => issuer_token }
59
- header = {'Content-Type' => 'application/x-www-form-urlencoded'}
60
- _request = -> do
61
- RestClient.post(@configuration['token_endpoint'], payload, header){|response, request, result|
62
- # case response.code
63
- # when 200
64
- # response.body
65
- # else
66
- # response.return!
67
- # end
68
- response.body
69
- }
72
+ def self.get_token_by_exchange(issuer, issuer_token, client_id = '', secret = '', token_endpoint = '')
73
+ setup_module
74
+
75
+ client_id = @client_id if client_id.blank?
76
+ secret = @secret if secret.blank?
77
+ token_endpoint = @configuration['token_endpoint'] if token_endpoint.blank?
78
+
79
+ payload = { 'client_id' => client_id, 'client_secret' => secret, 'audience' => client_id, 'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange', 'subject_token_type' => 'urn:ietf:params:oauth:token-type:access_token', 'subject_issuer' => issuer, 'subject_token' => issuer_token }
80
+ header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
81
+ _request = -> do
82
+ RestClient.post(token_endpoint, payload, header){|response, request, result|
83
+ # case response.code
84
+ # when 200
85
+ # response.body
86
+ # else
87
+ # response.return!
88
+ # end
89
+ response.body
90
+ }
70
91
  end
71
-
72
- exec_request _request
92
+ exec_request _request
73
93
  end
74
94
 
75
- def self.get_userinfo_issuer(access_token = '')
95
+ def self.get_userinfo_issuer(access_token = '', userinfo_endpoint = '')
76
96
  verify_setup
77
-
97
+
98
+ userinfo_endpoint = @configuration['userinfo_endpoint'] if userinfo_endpoint.blank?
99
+
78
100
  access_token = self.token["access_token"] if access_token.empty?
79
101
  payload = { 'access_token' => access_token }
80
102
  header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
81
103
  _request = -> do
82
- RestClient.post(@configuration['userinfo_endpoint'], payload, header){ |response, request, result|
83
- response.body
84
- }
104
+ RestClient.post(userinfo_endpoint, payload, header){ |response, request, result|
105
+ response.body
106
+ }
85
107
  end
86
-
87
- exec_request _request
108
+
109
+ exec_request _request
88
110
  end
89
111
 
90
- def self.get_token_by_refresh_token(refresh_token = '')
112
+ def self.get_token_by_refresh_token(refresh_token = '', client_id = '', secret = '')
91
113
  verify_setup
92
114
 
115
+ client_id = @client_id if client_id.blank?
116
+ secret = @secret if secret.blank?
93
117
  refresh_token = self.token['refresh_token'] if refresh_token.empty?
94
118
 
95
- payload = { 'client_id' => @client_id,
96
- 'client_secret' => @secret,
119
+ payload = { 'client_id' => client_id,
120
+ 'client_secret' => secret,
97
121
  'refresh_token' => refresh_token,
98
122
  'grant_type' => 'refresh_token' }
99
123
 
@@ -103,8 +127,8 @@ module Keycloak
103
127
  def self.get_token_by_client_credentials(client_id = '', secret = '')
104
128
  setup_module
105
129
 
106
- client_id = @client_id if client_id.empty?
107
- secret = @secret if secret.empty?
130
+ client_id = @client_id if client_id.blank?
131
+ secret = @secret if secret.blank?
108
132
 
109
133
  payload = { 'client_id' => client_id,
110
134
  'client_secret' => secret,
@@ -113,23 +137,24 @@ module Keycloak
113
137
  mount_request_token(payload)
114
138
  end
115
139
 
116
- def self.get_token_introspection(token = '', client_id = '', secret = '')
140
+ def self.get_token_introspection(token = '', client_id = '', secret = '', token_introspection_endpoint = '')
117
141
  verify_setup
118
142
 
119
- token = self.token["access_token"] if token.empty?
120
- payload = { 'token' => token }
143
+ client_id = @client_id if client_id.blank?
144
+ secret = @secret if secret.blank?
145
+ token = self.token["access_token"] if token.blank?
146
+ token_introspection_endpoint = @configuration['token_introspection_endpoint'] if token_introspection_endpoint.blank?
121
147
 
122
- client_id = @client_id if client_id.empty?
123
- secret = @secret if secret.empty?
148
+ payload = { 'token' => token }
124
149
 
125
150
  authorization = Base64.strict_encode64("#{client_id}:#{secret}")
126
151
  authorization = "Basic #{authorization}"
127
152
 
128
- header = {'Content-Type' => 'application/x-www-form-urlencoded',
129
- 'authorization' => authorization}
153
+ header = { 'Content-Type' => 'application/x-www-form-urlencoded',
154
+ 'authorization' => authorization }
130
155
 
131
156
  _request = -> do
132
- RestClient.post(@configuration['token_introspection_endpoint'], payload, header){|response, request, result|
157
+ RestClient.post(token_introspection_endpoint, payload, header){|response, request, result|
133
158
  case response.code
134
159
  when 200..399
135
160
  response.body
@@ -142,31 +167,36 @@ module Keycloak
142
167
  exec_request _request
143
168
  end
144
169
 
145
- def self.url_login_redirect(redirect_uri, response_type = 'code')
170
+ def self.url_login_redirect(redirect_uri, response_type = 'code', client_id = '', authorization_endpoint = '')
146
171
  verify_setup
147
172
 
148
- p = URI.encode_www_form({ response_type: response_type, client_id: @client_id, redirect_uri: redirect_uri })
149
- "#{@configuration['authorization_endpoint']}?#{p}"
173
+ client_id = @client_id if client_id.blank?
174
+ authorization_endpoint = @configuration['authorization_endpoint'] if authorization_endpoint.blank?
175
+
176
+ p = URI.encode_www_form({ response_type: response_type, client_id: client_id, redirect_uri: redirect_uri })
177
+ "#{authorization_endpoint}?#{p}"
150
178
  end
151
179
 
152
- def self.logout(redirect_uri = '', refresh_token = '')
180
+ def self.logout(redirect_uri = '', refresh_token = '', client_id = '', secret = '', end_session_endpoint = '')
153
181
  verify_setup
154
182
 
155
183
  if self.token || !refresh_token.empty?
156
184
 
157
185
  refresh_token = self.token['refresh_token'] if refresh_token.empty?
186
+ client_id = @client_id if client_id.blank?
187
+ secret = @secret if secret.blank?
188
+ end_session_endpoint = @configuration['end_session_endpoint'] if end_session_endpoint.blank?
158
189
 
159
- payload = { 'client_id' => @client_id,
160
- 'client_secret' => @secret,
161
- 'refresh_token' => refresh_token
162
- }
190
+ payload = { 'client_id' => client_id,
191
+ 'client_secret' => secret,
192
+ 'refresh_token' => refresh_token }
163
193
 
164
- header = {'Content-Type' => 'application/x-www-form-urlencoded'}
194
+ header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
165
195
 
166
196
  if redirect_uri.empty?
167
- final_url = @configuration['end_session_endpoint']
197
+ final_url = end_session_endpoint
168
198
  else
169
- final_url = "#{@configuration['end_session_endpoint']}?#{URI.encode_www_form({ redirect_uri: redirect_uri })}"
199
+ final_url = "#{end_session_endpoint}?#{URI.encode_www_form({ redirect_uri: redirect_uri })}"
170
200
  end
171
201
 
172
202
  _request = -> do
@@ -186,17 +216,18 @@ module Keycloak
186
216
  end
187
217
  end
188
218
 
189
- def self.get_userinfo(access_token = '')
219
+ def self.get_userinfo(access_token = '', userinfo_endpoint = '')
190
220
  verify_setup
191
221
 
192
222
  access_token = self.token["access_token"] if access_token.empty?
223
+ userinfo_endpoint = @configuration['userinfo_endpoint'] if userinfo_endpoint.blank?
193
224
 
194
225
  payload = { 'access_token' => access_token }
195
226
 
196
227
  header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
197
228
 
198
229
  _request = -> do
199
- RestClient.post(@configuration['userinfo_endpoint'], payload, header){ |response, request, result|
230
+ RestClient.post(userinfo_endpoint, payload, header){ |response, request, result|
200
231
  case response.code
201
232
  when 200
202
233
  response.body
@@ -215,12 +246,16 @@ module Keycloak
215
246
  "#{@auth_server_url}/realms/#{@realm}/account"
216
247
  end
217
248
 
218
- def self.has_role?(user_role, access_token = '')
249
+ def self.has_role?(user_role, access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
219
250
  verify_setup
220
251
 
221
- if user_signed_in?(access_token)
252
+ client_id = @client_id if client_id.blank?
253
+ secret = @secret if secret.blank?
254
+ token_introspection_endpoint = @configuration['token_introspection_endpoint'] if token_introspection_endpoint.blank?
255
+
256
+ if user_signed_in?(access_token, client_id, secret, token_introspection_endpoint)
222
257
  dt = decoded_access_token(access_token)[0]
223
- dt = dt["resource_access"][@client_id]
258
+ dt = dt["resource_access"][client_id]
224
259
  if dt != nil
225
260
  dt["roles"].each do |role|
226
261
  return true if role.to_s == user_role.to_s
@@ -234,11 +269,15 @@ module Keycloak
234
269
  end
235
270
  end
236
271
 
237
- def self.user_signed_in?(access_token = '')
272
+ def self.user_signed_in?(access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
238
273
  verify_setup
239
274
 
275
+ client_id = @client_id if client_id.blank?
276
+ secret = @secret if secret.blank?
277
+ token_introspection_endpoint = @configuration['token_introspection_endpoint'] if token_introspection_endpoint.blank?
278
+
240
279
  begin
241
- JSON(get_token_introspection(access_token))['active'] === true
280
+ JSON(get_token_introspection(access_token, client_id, secret, token_introspection_endpoint))['active'] === true
242
281
  rescue => e
243
282
  if e.class < Keycloak::KeycloakException
244
283
  raise
@@ -286,8 +325,8 @@ module Keycloak
286
325
  KEYCLOACK_CONTROLLER_DEFAULT = 'session'
287
326
 
288
327
  def self.get_installation
289
- if File.exists?(KEYCLOAK_JSON_FILE)
290
- installation = JSON File.read(KEYCLOAK_JSON_FILE)
328
+ if File.exists?(Keycloak.installation_file)
329
+ installation = JSON File.read(Keycloak.installation_file)
291
330
  @realm = installation["realm"]
292
331
  @client_id = installation["resource"]
293
332
  @secret = installation["credentials"]["secret"]
@@ -296,7 +335,7 @@ module Keycloak
296
335
  openid_configuration
297
336
  else
298
337
  if Keycloak.realm.blank? || Keycloak.auth_server_url.blank?
299
- raise "#{KEYCLOAK_JSON_FILE} and relm settings not found."
338
+ raise "#{Keycloak.installation_file} and relm settings not found."
300
339
  else
301
340
  @realm = Keycloak.realm
302
341
  @auth_server_url = Keycloak.auth_server_url
@@ -328,7 +367,7 @@ module Keycloak
328
367
  end
329
368
 
330
369
  def self.openid_configuration
331
- RestClient.proxy = Keycloak.proxy unless Keycloak.proxy.empty?
370
+ RestClient.proxy = Keycloak.proxy if Keycloak.proxy.present?
332
371
  config_url = "#{@auth_server_url}/realms/#{@realm}/.well-known/openid-configuration"
333
372
  _request = -> do
334
373
  RestClient.get config_url
@@ -398,16 +437,12 @@ module Keycloak
398
437
  end
399
438
 
400
439
  def self.revoke_consent_user(id, client_id = nil, access_token = nil)
401
- if client_id.nil?
402
- client_id = Keycloak::Client.client_id
403
- end
440
+ client_id = Keycloak::Client.client_id if client_id.blank?
404
441
  generic_delete("users/#{id}/consents/#{client_id}", nil, nil, access_token)
405
442
  end
406
443
 
407
444
  def self.update_account_email(id, actions, redirect_uri = '', client_id = nil, access_token = nil)
408
- if client_id.nil?
409
- client_id = Keycloak::Client.client_id
410
- end
445
+ client_id = Keycloak::Client.client_id if client_id.blank?
411
446
  generic_put("users/#{id}/execute-actions-email", {:redirect_uri => redirect_uri, :client_id => client_id}, actions, access_token)
412
447
  end
413
448
 
@@ -529,7 +564,6 @@ module Keycloak
529
564
  def self.full_url(service)
530
565
  base_url + service
531
566
  end
532
-
533
567
  end
534
568
 
535
569
  module Internal
@@ -538,32 +572,44 @@ module Keycloak
538
572
  class << self
539
573
  end
540
574
 
541
- def self.get_users(query_parameters = nil)
575
+ def self.get_users(query_parameters = nil, client_id = '', secret = '')
576
+ client_id = Keycloak::Client.client_id if client_id.blank?
577
+ secret = Keycloak::Client.secret if secret.blank?
578
+
542
579
  proc = lambda {|token|
543
580
  Keycloak::Admin.get_users(query_parameters, token["access_token"])
544
581
  }
545
582
 
546
- default_call(proc)
583
+ default_call(proc, client_id, secret)
547
584
  end
548
585
 
549
- def self.change_password(user_id, redirect_uri = '')
586
+ def self.change_password(user_id, redirect_uri = '', client_id = '', secret = '')
587
+ client_id = Keycloak::Client.client_id if client_id.blank?
588
+ secret = Keycloak::Client.secret if secret.blank?
589
+
550
590
  proc = lambda {|token|
551
591
  Keycloak.generic_request(token["access_token"],
552
592
  Keycloak::Admin.full_url("users/#{user_id}/execute-actions-email"),
553
- {:redirect_uri => redirect_uri, :client_id => Keycloak::Client.client_id},
593
+ {:redirect_uri => redirect_uri, :client_id => client_id},
554
594
  ['UPDATE_PASSWORD'],
555
595
  'PUT')
556
596
  }
557
597
 
558
- default_call(proc)
598
+ default_call(proc, client_id, secret)
559
599
  end
560
600
 
561
- def self.forgot_password(user_login, redirect_uri = '')
562
- user = get_user_info(user_login, true)
563
- change_password(user['id'], redirect_uri)
601
+ def self.forgot_password(user_login, redirect_uri = '', client_id = '', secret = '')
602
+ client_id = Keycloak::Client.client_id if client_id.blank?
603
+ secret = Keycloak::Client.secret if secret.blank?
604
+
605
+ user = get_user_info(user_login, true, client_id, secret)
606
+ change_password(user['id'], redirect_uri, client_id, secret)
564
607
  end
565
608
 
566
- def self.get_logged_user_info
609
+ def self.get_logged_user_info(client_id = '', secret = '')
610
+ client_id = Keycloak::Client.client_id if client_id.blank?
611
+ secret = Keycloak::Client.secret if secret.blank?
612
+
567
613
  proc = lambda {|token|
568
614
  userinfo = JSON Keycloak::Client.get_userinfo
569
615
  Keycloak.generic_request(token["access_token"],
@@ -571,10 +617,13 @@ module Keycloak
571
617
  nil, nil, 'GET')
572
618
  }
573
619
 
574
- default_call(proc)
620
+ default_call(proc, client_id, secret)
575
621
  end
576
622
 
577
- def self.get_user_info(user_login, whole_word = false)
623
+ def self.get_user_info(user_login, whole_word = false, client_id = '', secret = '')
624
+ client_id = Keycloak::Client.client_id if client_id.blank?
625
+ secret = Keycloak::Client.secret if secret.blank?
626
+
578
627
  proc = lambda { |token|
579
628
  if user_login.index('@').nil?
580
629
  search = {:username => user_login}
@@ -610,12 +659,15 @@ module Keycloak
610
659
  end
611
660
  }
612
661
 
613
- default_call(proc)
662
+ default_call(proc, client_id, secret)
614
663
  end
615
664
 
616
- def self.exists_name_or_email(value, user_id = '')
665
+ def self.exists_name_or_email(value, user_id = '', client_id = '', secret = '')
666
+ client_id = Keycloak::Client.client_id if client_id.blank?
667
+ secret = Keycloak::Client.secret if secret.blank?
668
+
617
669
  begin
618
- usuario = Keycloak::Internal.get_user_info(value, true)
670
+ usuario = Keycloak::Internal.get_user_info(value, true, client_id, secret)
619
671
  if user_id.empty? || user_id != usuario['id']
620
672
  usuario.present?
621
673
  else
@@ -626,15 +678,20 @@ module Keycloak
626
678
  end
627
679
  end
628
680
 
629
- def self.logged_federation_user?
630
- info = get_logged_user_info
681
+ def self.logged_federation_user?(client_id = '', secret = '')
682
+ client_id = Keycloak::Client.client_id if client_id.blank?
683
+ secret = Keycloak::Client.secret if secret.blank?
684
+ info = get_logged_user_info(client_id, secret)
631
685
  info['federationLink'] != nil
632
686
  end
633
687
 
634
- def self.create_simple_user(username, password, email, first_name, last_name, realm_roles_names, client_roles_names, proc = nil)
688
+ def self.create_simple_user(username, password, email, first_name, last_name, realm_roles_names, client_roles_names, proc = nil, client_id = '', secret = '')
689
+ client_id = Keycloak::Client.client_id if client_id.blank?
690
+ secret = Keycloak::Client.secret if secret.blank?
691
+
635
692
  begin
636
693
  username.downcase!
637
- user = get_user_info(username, true)
694
+ user = get_user_info(username, true, client_id, secret)
638
695
  newUser = false
639
696
  rescue Keycloak::UserLoginNotFound
640
697
  newUser = true
@@ -653,7 +710,7 @@ module Keycloak
653
710
  Keycloak::Admin.full_url("users/"),
654
711
  nil, user_representation, 'POST')
655
712
 
656
- user = get_user_info(username, true) if newUser
713
+ user = get_user_info(username, true, client_id, secret) if newUser
657
714
 
658
715
  credential_representation = { type: "password",
659
716
  temporary: false,
@@ -665,7 +722,7 @@ module Keycloak
665
722
 
666
723
  client = JSON Keycloak.generic_request(token["access_token"],
667
724
  Keycloak::Admin.full_url("clients/"),
668
- { clientId: Keycloak::Client.client_id }, nil, 'GET')
725
+ { clientId: client_id }, nil, 'GET')
669
726
 
670
727
  if client_roles_names.count > 0
671
728
  roles = []
@@ -708,38 +765,49 @@ module Keycloak
708
765
  end
709
766
  }
710
767
 
711
- if default_call(proc_default)
768
+ if default_call(proc_default, client_id, secret)
712
769
  proc.call user unless proc.nil?
713
770
  end
714
771
  end
715
772
 
716
- def self.create_starter_user(username, password, email, client_roles_names, proc = nil)
717
- Keycloak::Internal.create_simple_user(username, password, email, '', '', [], client_roles_names, proc)
773
+ def self.create_starter_user(username, password, email, client_roles_names, proc = nil, client_id = '', secret = '')
774
+ client_id = Keycloak::Client.client_id if client_id.blank?
775
+ secret = Keycloak::Client.secret if secret.blank?
776
+ Keycloak::Internal.create_simple_user(username, password, email, '', '', [], client_roles_names, proc, client_id, secret)
718
777
  end
719
778
 
720
- def self.get_client_roles
779
+ def self.get_client_roles(client_id = '', secret = '')
780
+ client_id = Keycloak::Client.client_id if client_id.blank?
781
+ secret = Keycloak::Client.secret if secret.blank?
782
+
721
783
  proc = lambda {|token|
722
- client = JSON Keycloak::Admin.get_clients({ clientId: Keycloak::Client.client_id }, token["access_token"])
784
+ client = JSON Keycloak::Admin.get_clients({ clientId: client_id }, token["access_token"])
723
785
 
724
786
  Keycloak.generic_request(token["access_token"],
725
787
  Keycloak::Admin.full_url("clients/#{client[0]['id']}/roles"),
726
788
  nil, nil, 'GET')
727
789
  }
728
790
 
729
- default_call(proc)
791
+ default_call(proc, client_id, secret)
730
792
  end
731
793
 
732
- def self.get_client_user_roles(user_id)
794
+ def self.get_client_user_roles(user_id, client_id = '', secret = '')
795
+ client_id = Keycloak::Client.client_id if client_id.blank?
796
+ secret = Keycloak::Client.secret if secret.blank?
797
+
733
798
  proc = lambda {|token|
734
- client = JSON Keycloak::Admin.get_clients({ clientId: Keycloak::Client.client_id }, token["access_token"])
799
+ client = JSON Keycloak::Admin.get_clients({ clientId: client_id }, token["access_token"])
735
800
  Keycloak::Admin.get_effective_client_level_role_composite_user(user_id, client[0]['id'], token["access_token"])
736
801
  }
737
802
 
738
- default_call(proc)
803
+ default_call(proc, client_id, secret)
739
804
  end
740
805
 
741
- def self.has_role?(user_id, user_role)
742
- roles = JSON get_client_user_roles(user_id)
806
+ def self.has_role?(user_id, user_role, client_id = '', secret = '')
807
+ client_id = Keycloak::Client.client_id if client_id.blank?
808
+ secret = Keycloak::Client.secret if secret.blank?
809
+
810
+ roles = JSON get_client_user_roles(user_id, client_id, secret)
743
811
  if !roles.nil?
744
812
  roles.each do |role|
745
813
  return true if role['name'].to_s == user_role.to_s
@@ -752,15 +820,17 @@ module Keycloak
752
820
 
753
821
  protected
754
822
 
755
- def self.default_call(proc)
823
+ def self.default_call(proc, client_id = '', secret = '')
824
+ client_id = Keycloak::Client.client_id if client_id.blank?
825
+ secret = Keycloak::Client.secret if secret.blank?
756
826
  begin
757
827
  tk = nil
758
828
  resp = nil
759
829
 
760
830
  Keycloak::Client.get_installation
761
831
 
762
- payload = { 'client_id' => Keycloak::Client.client_id,
763
- 'client_secret' => Keycloak::Client.secret,
832
+ payload = { 'client_id' => client_id,
833
+ 'client_secret' => secret,
764
834
  'grant_type' => 'client_credentials' }
765
835
 
766
836
  header = {'Content-Type' => 'application/x-www-form-urlencoded'}
@@ -780,8 +850,8 @@ module Keycloak
780
850
  Keycloak::Client.exec_request _request
781
851
  ensure
782
852
  if tk
783
- payload = { 'client_id' => Keycloak::Client.client_id,
784
- 'client_secret' => Keycloak::Client.secret,
853
+ payload = { 'client_id' => client_id,
854
+ 'client_secret' => secret,
785
855
  'refresh_token' => tk["refresh_token"] }
786
856
 
787
857
  header = {'Content-Type' => 'application/x-www-form-urlencoded'}
@@ -3,4 +3,5 @@ module Keycloak
3
3
  class UserLoginNotFound < KeycloakException; end
4
4
  class ProcCookieTokenNotDefined < KeycloakException; end
5
5
  class ProcExternalAttributesNotDefined < KeycloakException; end
6
+ class InstallationFileNotFound < KeycloakException; end
6
7
  end
@@ -1,3 +1,3 @@
1
1
  module Keycloak
2
- VERSION = "2.3.2"
2
+ VERSION = "2.4.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: 2.3.2
4
+ version: 2.4.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: 2018-04-06 00:00:00.000000000 Z
11
+ date: 2018-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
140
  version: '0'
141
141
  requirements: []
142
142
  rubyforge_project:
143
- rubygems_version: 2.7.3
143
+ rubygems_version: 2.7.7
144
144
  signing_key:
145
145
  specification_version: 4
146
146
  summary: Add authentication to applications and secure services with Keycloak