keycloak-admin 0.6.5 → 0.7.4

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