keycloak-admin 0.6.5 → 0.7.4

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.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -1
  3. data/CHANGELOG.md +65 -0
  4. data/Dockerfile +1 -1
  5. data/Gemfile.lock +13 -4
  6. data/README.md +160 -9
  7. data/keycloak-admin.gemspec +3 -0
  8. data/lib/keycloak-admin.rb +13 -0
  9. data/lib/keycloak-admin/client/client.rb +13 -3
  10. data/lib/keycloak-admin/client/client_client.rb +24 -0
  11. data/lib/keycloak-admin/client/client_role_mappings_client.rb +32 -0
  12. data/lib/keycloak-admin/client/group_client.rb +46 -0
  13. data/lib/keycloak-admin/client/realm_client.rb +54 -0
  14. data/lib/keycloak-admin/client/role_client.rb +32 -0
  15. data/lib/keycloak-admin/client/role_mapper_client.rb +20 -0
  16. data/lib/keycloak-admin/client/token_client.rb +6 -1
  17. data/lib/keycloak-admin/client/user_client.rb +23 -6
  18. data/lib/keycloak-admin/configuration.rb +1 -1
  19. data/lib/keycloak-admin/representation/camel_json.rb +1 -1
  20. data/lib/keycloak-admin/representation/client_representation.rb +16 -0
  21. data/lib/keycloak-admin/representation/group_representation.rb +15 -0
  22. data/lib/keycloak-admin/representation/realm_representation.rb +14 -0
  23. data/lib/keycloak-admin/representation/representation.rb +6 -1
  24. data/lib/keycloak-admin/representation/role_representation.rb +17 -0
  25. data/lib/keycloak-admin/representation/user_representation.rb +13 -13
  26. data/lib/keycloak-admin/resource/base_role_containing_resource.rb +26 -0
  27. data/lib/keycloak-admin/resource/group_resource.rb +7 -0
  28. data/lib/keycloak-admin/resource/user_resource.rb +7 -0
  29. data/lib/keycloak-admin/version.rb +1 -1
  30. data/spec/client/client_client_spec.rb +53 -0
  31. data/spec/client/client_role_mappings_client_spec.rb +82 -0
  32. data/spec/client/client_spec.rb +28 -0
  33. data/spec/client/group_client_spec.rb +125 -0
  34. data/spec/client/realm_client_spec.rb +108 -0
  35. data/spec/client/role_client_spec.rb +83 -0
  36. data/spec/client/role_mapper_client_spec.rb +47 -0
  37. data/spec/client/token_client_spec.rb +32 -1
  38. data/spec/client/user_client_spec.rb +147 -0
  39. data/spec/configuration_spec.rb +2 -0
  40. data/spec/representation/user_representation_spec.rb +15 -0
  41. data/spec/resource/group_resource_spec.rb +14 -0
  42. data/spec/resource/user_resource_spec.rb +14 -0
  43. data/spec/spec_helper.rb +7 -0
  44. metadata +40 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1514ae886ef6e9a3b7a0716ea6be8f472222fdd9
4
- data.tar.gz: 1ba37cacfd7668d8c3d5b8f934f31de62c21b10d
2
+ SHA256:
3
+ metadata.gz: 8e59d2429daf60f186a44419025f9ecf6468e948306b10dd07acc6f71ff36bdb
4
+ data.tar.gz: a82dd0cdce80a82e19372ed04cf4b84f84a0138faac9d7fcc4d3eca1f128507f
5
5
  SHA512:
6
- metadata.gz: 9bf9575e8155e8803d6675aa764ddd01bbc761c9a672f8ea0cab5974503b5d24cf1ea955fa25aa5b1a1619fd8063002f5d6802b9541bd93747378c46609f332a
7
- data.tar.gz: f4ce9faf771762e2b319bb02bfbef51015f1971617f08c2673d2d235abace7427d8eebb1f8267f54a09b1475a60e9bdb9f0df4441b3bb5a923ba3f46b9e7760f
6
+ metadata.gz: 4b940501a2a046248b9773d6075e72e6c0717a291646a5dbd583b67b59ab54b9a02b6f7407e2fa75330ad829bd50100155f42245358380163868b48968488caa
7
+ data.tar.gz: 9ae5a43cfcde48897618294f845c2494ba45e1ecb80d980aa15b99397e9cfc4014a2ef03f36fbdbee1cf8b96f6d5099bae087217901b09f0505cac702967dfa2
data/.gitignore CHANGED
@@ -5,4 +5,5 @@ test/dummy/db/*.sqlite3
5
5
  test/dummy/db/*.sqlite3-journal
6
6
  test/dummy/log/*.log
7
7
  test/dummy/tmp/
8
- *.gem
8
+ *.gem
9
+ .idea/
data/CHANGELOG.md ADDED
@@ -0,0 +1,65 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.7.4] - 2019-10-17
9
+
10
+ * Support for Rails 6
11
+
12
+ ## [0.7.3] - 2019-07-11
13
+
14
+ Thanks to @cederigo=
15
+ * For a given user, get her list of groups
16
+
17
+ ## [0.7.2] - 2019-06-17
18
+
19
+ Thanks to @vlad-ro:
20
+
21
+ * Get list of client role mappings for a group
22
+ * Save client role mappings for a user/group
23
+ * Save realm-level role mappings for a user/group
24
+
25
+ ## [0.7.1] - 2019-06-11
26
+
27
+ Thanks to @vlad-ro:
28
+
29
+ * List users
30
+ * List clients
31
+ * List groups, create/save a group
32
+ * List roles, save a role
33
+ * List realms, save/update/delete a realm
34
+ * Get list of client role mappings for a user
35
+ * Support passing rest client options for user save and search
36
+ * Support using gem without ActiveSupport
37
+
38
+ ## [0.7.0] - 2019-06-06
39
+
40
+ Thanks to @vlad-ro:
41
+
42
+ * Support passing rest client options
43
+ * More documentation
44
+ * More tests
45
+ * Better handling of timeouts
46
+
47
+ ## [0.6.5] - 2019-05-14
48
+
49
+ * Get user
50
+
51
+ ## [0.6.2] - 2019-05-14
52
+
53
+ * Update users
54
+
55
+ ## [0.6] - 2019-03-06
56
+
57
+ * Save a locale when creating a new user
58
+
59
+ ## [0.5] - 2018-01-26
60
+
61
+ * Client to access Custom REST API configurable-token
62
+
63
+ ## [0.3] - 2018-01-19
64
+
65
+ * Support of impersonation
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:2.3
1
+ FROM ruby:2.6.5
2
2
  RUN mkdir -p /usr/src/app/lib/keycloak-admin
3
3
  WORKDIR /usr/src/app
4
4
 
data/Gemfile.lock CHANGED
@@ -1,18 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keycloak-admin (0.6.5)
4
+ keycloak-admin (0.7.4)
5
5
  http-cookie (~> 1.0, >= 1.0.3)
6
+ rest-client (~> 2.0)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
10
11
  byebug (9.1.0)
11
12
  diff-lcs (1.3)
12
- domain_name (0.5.20180417)
13
+ domain_name (0.5.20190701)
13
14
  unf (>= 0.0.5, < 1.0.0)
14
15
  http-cookie (1.0.3)
15
16
  domain_name (~> 0.5)
17
+ mime-types (3.2.2)
18
+ mime-types-data (~> 3.2015)
19
+ mime-types-data (3.2019.0331)
20
+ netrc (0.11.0)
21
+ rest-client (2.0.2)
22
+ http-cookie (>= 1.0.2, < 2.0)
23
+ mime-types (>= 1.16, < 4.0)
24
+ netrc (~> 0.8)
16
25
  rspec (3.7.0)
17
26
  rspec-core (~> 3.7.0)
18
27
  rspec-expectations (~> 3.7.0)
@@ -28,7 +37,7 @@ GEM
28
37
  rspec-support (3.7.0)
29
38
  unf (0.1.4)
30
39
  unf_ext
31
- unf_ext (0.0.7.5)
40
+ unf_ext (0.0.7.6)
32
41
 
33
42
  PLATFORMS
34
43
  ruby
@@ -39,4 +48,4 @@ DEPENDENCIES
39
48
  rspec (= 3.7.0)
40
49
 
41
50
  BUNDLED WITH
42
- 1.16.3
51
+ 1.17.3
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  Ruby client that acts as a client for the Keycloak REST API.
5
5
  This gem basically acts as an url builder using `http-client` to get responses and serialize them into _representation_ objects.
6
6
 
7
- _Warning: This beta gem is currently used for personal used. Most Keycloak Admin features are not implemented yet._
7
+ _Warning: This beta gem is currently used for personal use. Most Keycloak Admin features are not implemented yet._
8
8
 
9
9
  ## Install
10
10
 
@@ -12,7 +12,7 @@ This gem *does not* require Rails.
12
12
  For example, using `bundle`, add this line to your Gemfile.
13
13
 
14
14
  ```ruby
15
- gem "keycloak-admin", "0.6.5"
15
+ gem "keycloak-admin", "0.7.4"
16
16
  ```
17
17
 
18
18
  ## Login
@@ -58,6 +58,7 @@ KeycloakAdmin.configure do |config|
58
58
  config.username = ENV["KEYCLOAK_ADMIN_USER"]
59
59
  config.password = ENV["KEYCLOAK_ADMIN_PASSWORD"]
60
60
  config.logger = Rails.logger
61
+ config.rest_client_options = { verify_ssl: OpenSSL::SSL::VERIFY_NONE }
61
62
  end
62
63
  ```
63
64
  This example is autoloaded in a Rails environment.
@@ -69,13 +70,14 @@ All options have a default value. However, all of them can be changed in your in
69
70
  | Option | Default Value | Type | Required? | Description | Example |
70
71
  | ---- | ----- | ------ | ----- | ------ | ----- |
71
72
  | `server_url` | `nil`| String | Required | The base url where your Keycloak server is located. This value can be retrieved in your Keycloak client configuration. | `server_domain` | `nil`| String | Required | Public domain that identify your authentication cookies. | `auth.service.io` |
72
- | `client_realm_name` | `""`| String | Required | Name of the realm that contain the admin client. | `master` |
73
+ | `client_realm_name` | `""`| String | Required | Name of the realm that contains the admin client. | `master` |
73
74
  | `client_id` | `admin-cli`| String | Required | Client that should be used to access admin capabilities. | `api-cli` |
74
75
  | `client_secret` | `nil`| String | Optional | If your client is `confidential`, this parameter must be specified. | `4e3c481c-f823-4a6a-b8a7-bf8c86e3eac3` |
75
- | `use_service_account` | `true` | Boolean | Required | `true` if the connection to the client uses a Service Account. `false` if the connetio nto the client uses a username/password credential | `false` |
76
- | `username` | `nil`| String | Optional | Username that access to the Admin REST API. Recommended if `user_service_account` is set to `false`. | `mummy` |
77
- | `password` | `nil`| String | Optional | Clear password that access to the Admin REST API. Recommended if `user_service_account` is set to `false`. | `bobby` |
76
+ | `use_service_account` | `true` | Boolean | Required | `true` if the connection to the client uses a Service Account. `false` if the connection to the client uses a username/password credential. | `false` |
77
+ | `username` | `nil`| String | Optional | Username to access the Admin REST API. Recommended if `user_service_account` is set to `false`. | `mummy` |
78
+ | `password` | `nil`| String | Optional | Clear password to access the Admin REST API. Recommended if `user_service_account` is set to `false`. | `bobby` |
78
79
  | `logger` | `Logger.new(STDOUT)`| Logger | Optional | The logger used by `keycloak-admin` | `Rails.logger` | 
80
+ | `rest_client_options` | `{}`| Hash | Optional | Options to pass to `RestClient` | `{ verify_ssl: OpenSSL::SSL::VERIFY_NONE }` | 
79
81
 
80
82
 
81
83
  ## Use Case
@@ -83,11 +85,18 @@ All options have a default value. However, all of them can be changed in your in
83
85
  ### Supported features
84
86
 
85
87
  * Get an access token
86
- * Create/update/get a user
88
+ * Create/update/get/delete a user
89
+ * Get list of users, search for user(s)
87
90
  * Reset credentials
88
- * Delete a user
89
91
  * Impersonate a user
90
92
  * Exchange a configurable token
93
+ * Get list of clients
94
+ * Get list of groups, create/save a group
95
+ * Get list of roles, save a role
96
+ * Get list of realms, save/update/delete a realm
97
+ * Get list of client role mappings for a user/group
98
+ * Save client role mappings for a user/group
99
+ * Save realm-level role mappings for a user/group
91
100
 
92
101
  ### Get an access token
93
102
 
@@ -97,7 +106,7 @@ Returns an instance of `KeycloakAdmin::TokenRepresentation`.
97
106
  KeycloakAdmin.realm("a_realm").token.get
98
107
  ```
99
108
 
100
- ### Get a user from its idenfier
109
+ ### Get a user from its identifier
101
110
 
102
111
  Returns an instance of `KeycloakAdmin::UserRepresentation` or `nil` when this user does not exist.
103
112
 
@@ -114,6 +123,14 @@ Returns an array of `KeycloakAdmin::UserRepresentation`.
114
123
  KeycloakAdmin.realm("a_realm").users.search("a_username_or_an_email")
115
124
  ```
116
125
 
126
+ ### List all users in a realm
127
+
128
+ Returns an array of `KeycloakAdmin::UserRepresentation`.
129
+
130
+ ```ruby
131
+ KeycloakAdmin.realm("a_realm").users.list
132
+ ```
133
+
117
134
  ### Save a user
118
135
 
119
136
  Returns the provided `user`, which must be of type `KeycloakAdmin::UserRepresentation`.
@@ -132,6 +149,12 @@ KeycloakAdmin.realm("a_realm").users.update("05c135c6-5ad8-4e17-b1fa-635fc089fd7
132
149
  })
133
150
  ```
134
151
 
152
+ ### Delete a user
153
+
154
+ ```ruby
155
+ KeycloakAdmin.realm("a_realm").users.delete(user_id)
156
+ ```
157
+
135
158
  ### Create and save a user with password and a locale
136
159
 
137
160
  Returns the created user of type `KeycloakAdmin::UserRepresentation`.
@@ -182,6 +205,134 @@ token_lifespan_in_seconds = 20
182
205
  KeycloakAdmin.realm("a_realm").configurable_token.exchange_with(user_access_token, token_lifespan_in_seconds)
183
206
  ```
184
207
 
208
+ ### Get list of realms
209
+
210
+ Returns an array of `KeycloakAdmin::RealmRepresentation`.
211
+
212
+ ```ruby
213
+ KeycloakAdmin.realm("master").list
214
+ ```
215
+
216
+ ### Save a realm
217
+
218
+ Takes `realm` of type `KeycloakAdmin::RealmRepresentation`, or an object implementing `to_json`, such as a `Hash`.
219
+
220
+ ```ruby
221
+ KeycloakAdmin.realm(nil).save(realm)
222
+ ```
223
+
224
+ ### Update a realm
225
+
226
+ If you want to update its entire entity. To update some specific attributes, provide an object implementing `to_json`, such as a `Hash`.
227
+
228
+ ```ruby
229
+ KeycloakAdmin.realm("a_realm").update({
230
+ smtpServer: { host: 'test_host' }
231
+ })
232
+ ```
233
+
234
+ ### Delete a realm
235
+
236
+ ```ruby
237
+ KeycloakAdmin.realm("a_realm").delete
238
+ ```
239
+
240
+ ### Get list of clients in a realm
241
+
242
+ Returns an array of `KeycloakAdmin::ClientRepresentation`.
243
+
244
+ ```ruby
245
+ KeycloakAdmin.realm("a_realm").clients.list
246
+ ```
247
+
248
+ ### Get list of groups in a realm
249
+
250
+ Returns an array of `KeycloakAdmin::GroupRepresentation`.
251
+
252
+ ```ruby
253
+ KeycloakAdmin.realm("a_realm").groups.list
254
+ ```
255
+
256
+ ### Save a group
257
+
258
+ Returns the id of saved `group` provided, which must be of type `KeycloakAdmin::GroupRepresentation`.
259
+
260
+ ```ruby
261
+ KeycloakAdmin.realm("a_realm").groups.save(group)
262
+ ```
263
+
264
+ ### Create and save a group with a name and path
265
+
266
+ Returns the id of created group.
267
+
268
+ ```ruby
269
+ group_name = "test"
270
+ group_path = "/top"
271
+ group_id = KeycloakAdmin.realm("a_realm").groups.create!(group_name, group_path)
272
+ ```
273
+
274
+ ### Get list of roles in a realm
275
+
276
+ Returns an array of `KeycloakAdmin::RoleRepresentation`.
277
+
278
+ ```ruby
279
+ KeycloakAdmin.realm("a_realm").roles.list
280
+ ```
281
+
282
+ ### Save a role
283
+
284
+ Takes `role`, which must be of type `KeycloakAdmin::RoleRepresentation`.
285
+
286
+ ```ruby
287
+ KeycloakAdmin.realm("a_realm").roles.save(role)
288
+ ```
289
+
290
+ ### Get list of client role mappings for a user/group
291
+
292
+ Returns an array of `KeycloakAdmin::RoleRepresentation`.
293
+
294
+ ```ruby
295
+ user_id = "95985b21-d884-4bbd-b852-cb8cd365afc2"
296
+ client_id = "1869e876-71b4-4de2-849e-66540db3a098"
297
+ KeycloakAdmin.realm("a_realm").user(user_id).client_role_mappings(client_id).list_available
298
+ ```
299
+ or
300
+ ```ruby
301
+ group_id = "3a63b5c0-ef8a-47fd-86ed-b5fead18d9b8"
302
+ client_id = "1869e876-71b4-4de2-849e-66540db3a098"
303
+ KeycloakAdmin.realm("a_realm").group(group_id).client_role_mappings(client_id).list_available
304
+ ```
305
+
306
+ ### Save list of client role mappings for a user/group
307
+
308
+ Takes `role_list`, which must be an array of type `KeycloakAdmin::RoleRepresentation`.
309
+
310
+ ```ruby
311
+ user_id = "95985b21-d884-4bbd-b852-cb8cd365afc2"
312
+ client_id = "1869e876-71b4-4de2-849e-66540db3a098"
313
+ KeycloakAdmin.realm("a_realm").user(user_id).client_role_mappings(client_id).save(role_list)
314
+ ```
315
+ or
316
+ ```ruby
317
+ group_id = "3a63b5c0-ef8a-47fd-86ed-b5fead18d9b8"
318
+ client_id = "1869e876-71b4-4de2-849e-66540db3a098"
319
+ KeycloakAdmin.realm("a_realm").group(group_id).client_role_mappings(client_id).save(role_list)
320
+ ```
321
+
322
+ ### Save list of realm-level role mappings for a user/group
323
+
324
+ Takes `role_list`, which must be an array of type `KeycloakAdmin::RoleRepresentation`.
325
+
326
+ ```ruby
327
+ user_id = "95985b21-d884-4bbd-b852-cb8cd365afc2"
328
+ KeycloakAdmin.realm("a_realm").user(user_id).role_mapper.save_realm_level(role_list)
329
+ ```
330
+ or
331
+ ```ruby
332
+ group_id = "3a63b5c0-ef8a-47fd-86ed-b5fead18d9b8"
333
+ KeycloakAdmin.realm("a_realm").group(group_id).role_mapper.save_realm_level(role_list)
334
+ ```
335
+
185
336
  ## How to execute library tests
186
337
 
187
338
  From the `keycloak-admin-api` directory:
@@ -15,7 +15,10 @@ Gem::Specification.new do |spec|
15
15
  spec.files = `git ls-files -z`.split("\x0")
16
16
  spec.require_paths = ["lib"]
17
17
 
18
+ spec.required_ruby_version = '>= 2.3'
19
+
18
20
  spec.add_dependency "http-cookie", "~> 1.0", ">= 1.0.3"
21
+ spec.add_dependency "rest-client", "~> 2.0"
19
22
  spec.add_development_dependency "rspec", "3.7.0"
20
23
  spec.add_development_dependency "byebug", "9.1.0"
21
24
  end
@@ -2,17 +2,29 @@ require "logger"
2
2
 
3
3
  require_relative "keycloak-admin/configuration"
4
4
  require_relative "keycloak-admin/client/client"
5
+ require_relative "keycloak-admin/client/client_client"
6
+ require_relative "keycloak-admin/client/client_role_mappings_client"
7
+ require_relative "keycloak-admin/client/group_client"
5
8
  require_relative "keycloak-admin/client/realm_client"
9
+ require_relative "keycloak-admin/client/role_client"
10
+ require_relative "keycloak-admin/client/role_mapper_client"
6
11
  require_relative "keycloak-admin/client/token_client"
7
12
  require_relative "keycloak-admin/client/user_client"
8
13
  require_relative "keycloak-admin/client/configurable_token_client"
9
14
  require_relative "keycloak-admin/representation/camel_json"
10
15
  require_relative "keycloak-admin/representation/representation"
16
+ require_relative "keycloak-admin/representation/client_representation"
17
+ require_relative "keycloak-admin/representation/group_representation"
11
18
  require_relative "keycloak-admin/representation/token_representation"
12
19
  require_relative "keycloak-admin/representation/impersonation_redirection_representation"
13
20
  require_relative "keycloak-admin/representation/impersonation_representation"
14
21
  require_relative "keycloak-admin/representation/credential_representation"
22
+ require_relative "keycloak-admin/representation/realm_representation"
23
+ require_relative "keycloak-admin/representation/role_representation"
15
24
  require_relative "keycloak-admin/representation/user_representation"
25
+ require_relative "keycloak-admin/resource/base_role_containing_resource"
26
+ require_relative "keycloak-admin/resource/group_resource"
27
+ require_relative "keycloak-admin/resource/user_resource"
16
28
 
17
29
  module KeycloakAdmin
18
30
 
@@ -42,6 +54,7 @@ module KeycloakAdmin
42
54
  config.use_service_account = true
43
55
  config.username = nil
44
56
  config.password = nil
57
+ config.rest_client_options = nil
45
58
  end
46
59
  end
47
60
 
@@ -9,13 +9,13 @@ module KeycloakAdmin
9
9
  @configuration.server_url
10
10
  end
11
11
 
12
- def token
13
- @token ||= KeycloakAdmin.realm(@configuration.client_realm_name).token.get
12
+ def current_token
13
+ @current_token ||= KeycloakAdmin.realm(@configuration.client_realm_name).token.get
14
14
  end
15
15
 
16
16
  def headers
17
17
  {
18
- Authorization: "Bearer #{token.access_token}",
18
+ Authorization: "Bearer #{current_token.access_token}",
19
19
  content_type: :json,
20
20
  accept: :json
21
21
  }
@@ -23,10 +23,20 @@ module KeycloakAdmin
23
23
 
24
24
  def execute_http
25
25
  yield
26
+ rescue RestClient::Exceptions::Timeout => e
27
+ raise
26
28
  rescue RestClient::ExceptionWithResponse => e
27
29
  http_error(e.response)
28
30
  end
29
31
 
32
+ def created_id(response)
33
+ unless response.net_http_res.is_a? Net::HTTPCreated
34
+ raise "Create method returned status #{response.net_http_res.message} (Code: #{response.net_http_res.code}); expected status: Created (201)"
35
+ end
36
+ (_head, _separator, id) = response.headers[:location].rpartition('/')
37
+ id
38
+ end
39
+
30
40
  private
31
41
 
32
42
  def http_error(response)