keycloak-admin 2.0.0 → 2.0.2

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +54 -2
  4. data/keycloak-admin.gemspec +14 -5
  5. data/lib/keycloak-admin/client/client.rb +30 -11
  6. data/lib/keycloak-admin/client/client_authz_permission_client.rb +1 -1
  7. data/lib/keycloak-admin/client/client_authz_policy_client.rb +1 -1
  8. data/lib/keycloak-admin/client/client_authz_resource_client.rb +1 -1
  9. data/lib/keycloak-admin/client/client_authz_scope_client.rb +1 -1
  10. data/lib/keycloak-admin/client/configurable_token_client.rb +2 -1
  11. data/lib/keycloak-admin/client/group_client.rb +4 -6
  12. data/lib/keycloak-admin/client/organization_client.rb +7 -7
  13. data/lib/keycloak-admin/client/resource.rb +98 -0
  14. data/lib/keycloak-admin/client/response.rb +36 -0
  15. data/lib/keycloak-admin/client/role_mapper_client.rb +2 -1
  16. data/lib/keycloak-admin/client/user_client.rb +22 -11
  17. data/lib/keycloak-admin/configuration.rb +22 -0
  18. data/lib/keycloak-admin/error.rb +62 -0
  19. data/lib/keycloak-admin/version.rb +1 -1
  20. data/lib/keycloak-admin.rb +1 -0
  21. metadata +38 -53
  22. data/.github/workflows/Dockerfile +0 -24
  23. data/.github/workflows/ci.yml +0 -94
  24. data/.gitignore +0 -10
  25. data/.rspec +0 -2
  26. data/Dockerfile +0 -13
  27. data/Gemfile +0 -3
  28. data/Gemfile.lock +0 -52
  29. data/bin/console +0 -9
  30. data/spec/client/attack_detection_client_spec.rb +0 -102
  31. data/spec/client/client_authz_permission_client_spec.rb +0 -170
  32. data/spec/client/client_authz_policy_client_spec.rb +0 -170
  33. data/spec/client/client_authz_resource_client_spec.rb +0 -150
  34. data/spec/client/client_authz_scope_client_spec.rb +0 -134
  35. data/spec/client/client_client_spec.rb +0 -133
  36. data/spec/client/client_role_mappings_client_spec.rb +0 -82
  37. data/spec/client/client_scope_client_spec.rb +0 -220
  38. data/spec/client/client_scope_protocol_mapper_client_spec.rb +0 -230
  39. data/spec/client/client_spec.rb +0 -48
  40. data/spec/client/configurable_token_client_spec.rb +0 -34
  41. data/spec/client/group_client_spec.rb +0 -328
  42. data/spec/client/identity_provider_client_spec.rb +0 -92
  43. data/spec/client/organization_client_spec.rb +0 -595
  44. data/spec/client/realm_client_spec.rb +0 -155
  45. data/spec/client/role_client_spec.rb +0 -79
  46. data/spec/client/role_mapper_client_spec.rb +0 -113
  47. data/spec/client/token_client_spec.rb +0 -68
  48. data/spec/client/user_client_spec.rb +0 -418
  49. data/spec/configuration_spec.rb +0 -113
  50. data/spec/gemspec_spec.rb +0 -25
  51. data/spec/integration/client_authorization_spec.rb +0 -93
  52. data/spec/representation/attack_detection_representation_spec.rb +0 -16
  53. data/spec/representation/client_authz_permission_representation_spec.rb +0 -52
  54. data/spec/representation/client_authz_policy_representation_spec.rb +0 -47
  55. data/spec/representation/client_authz_resource_representation_spec.rb +0 -33
  56. data/spec/representation/client_authz_scope_representation_spec.rb +0 -19
  57. data/spec/representation/client_representation_spec.rb +0 -119
  58. data/spec/representation/client_scope_representation_spec.rb +0 -125
  59. data/spec/representation/credential_representation_spec.rb +0 -68
  60. data/spec/representation/group_representation_spec.rb +0 -22
  61. data/spec/representation/identity_provider_mapper_representation_spec.rb +0 -24
  62. data/spec/representation/identity_provider_representation_spec.rb +0 -113
  63. data/spec/representation/impersonation_representation_spec.rb +0 -163
  64. data/spec/representation/organization_representation_spec.rb +0 -64
  65. data/spec/representation/protocol_mapper_representation_spec.rb +0 -57
  66. data/spec/representation/role_representation_spec.rb +0 -37
  67. data/spec/representation/session_representation_spec.rb +0 -16
  68. data/spec/representation/user_representation_spec.rb +0 -15
  69. data/spec/resource/group_resource_spec.rb +0 -14
  70. data/spec/resource/user_resource_spec.rb +0 -14
  71. data/spec/spec_helper.rb +0 -29
@@ -1,48 +0,0 @@
1
- RSpec.describe KeycloakAdmin::Client do
2
- describe "#server_url" do
3
- def client_with_server_url(server_url)
4
- configuration = KeycloakAdmin::Configuration.new
5
- configuration.server_url = server_url
6
- KeycloakAdmin::Client.new(configuration)
7
- end
8
-
9
- it "returns the configured url untouched when it has no trailing slash" do
10
- expect(client_with_server_url("http://auth.service.io/auth").server_url).to eql "http://auth.service.io/auth"
11
- end
12
-
13
- it "strips a trailing slash so built paths stay normalized" do
14
- expect(client_with_server_url("http://auth.service.io/auth/").server_url).to eql "http://auth.service.io/auth"
15
- end
16
-
17
- it "strips repeated trailing slashes" do
18
- expect(client_with_server_url("http://localhost:8080///").server_url).to eql "http://localhost:8080"
19
- end
20
-
21
- it "returns nil when no url is configured" do
22
- expect(client_with_server_url(nil).server_url).to be_nil
23
- end
24
- end
25
-
26
- describe "#execute_http" do
27
- let(:realm_name) { "valid-realm" }
28
- before(:each) do
29
- @client = KeycloakAdmin::Client.new(KeycloakAdmin.config)
30
- end
31
-
32
- it "handles timeout" do
33
- expect do
34
- @client.execute_http do
35
- raise Faraday::TimeoutError.new
36
- end
37
- end.to raise_error(Faraday::TimeoutError)
38
- end
39
-
40
- it "handles response exception" do
41
- expect do
42
- @client.execute_http do
43
- raise Faraday::ServerError.new("boom", status: 500, body: "Server error")
44
- end
45
- end.to raise_error("Keycloak: The request failed with response code 500 and message: Server error")
46
- end
47
- end
48
- end
@@ -1,34 +0,0 @@
1
- RSpec.describe KeycloakAdmin::ConfigurableTokenClient do
2
- describe "#initialize" do
3
- context "when realm_name is defined" do
4
- let(:realm_name) { "master" }
5
- it "does not raise any error" do
6
- expect {
7
- KeycloakAdmin.realm(realm_name).configurable_token
8
- }.to_not raise_error
9
- end
10
- end
11
-
12
- context "when realm_name is not defined" do
13
- let(:realm_name) { nil }
14
- it "raises any error" do
15
- expect {
16
- KeycloakAdmin.realm(realm_name).configurable_token
17
- }.to raise_error(ArgumentError)
18
- end
19
- end
20
- end
21
-
22
- describe "#token_url" do
23
- let(:realm_name) { "valid-realm" }
24
- let(:user_id) { nil }
25
-
26
- before(:each) do
27
- @built_url = KeycloakAdmin.realm(realm_name).configurable_token.token_url
28
- end
29
-
30
- it "return a proper url with the realm name" do
31
- expect(@built_url).to eq "http://auth.service.io/auth/realms/valid-realm/configurable-token"
32
- end
33
- end
34
- end
@@ -1,328 +0,0 @@
1
- RSpec.describe KeycloakAdmin::GroupClient do
2
- describe "#groups_url" do
3
- let(:realm_name) { "valid-realm" }
4
- let(:group_id) { nil }
5
-
6
- before(:each) do
7
- @built_url = KeycloakAdmin.realm(realm_name).groups.groups_url(group_id)
8
- end
9
-
10
- context "when group_id is not defined" do
11
- let(:group_id) { nil }
12
- it "return a proper url without group id" do
13
- expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/groups"
14
- end
15
- end
16
-
17
- context "when group_id is defined" do
18
- let(:group_id) { "95985b21-d884-4bbd-b852-cb8cd365afc2" }
19
- it "return a proper url with the group id" do
20
- expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/groups/95985b21-d884-4bbd-b852-cb8cd365afc2"
21
- end
22
- end
23
- end
24
-
25
- describe "#get" do
26
- let(:realm_name) { "valid-realm" }
27
-
28
- before(:each) do
29
- @group_client = KeycloakAdmin.realm(realm_name).groups
30
-
31
- stub_token_client
32
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get).and_return '{"id":"test_group_id","name":"test_group_name"}'
33
- end
34
-
35
- it "get a group" do
36
- group = @group_client.get("test_group_id")
37
- expect(group.id).to eq "test_group_id"
38
- expect(group.name).to eq "test_group_name"
39
- end
40
-
41
- it "passes rest client options" do
42
- faraday_options = {timeout: 10}
43
- allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
44
-
45
- expect(KeycloakAdmin::Resource).to receive(:new).with(
46
- "http://auth.service.io/auth/admin/realms/valid-realm/groups/test_group_id", faraday_options).and_call_original
47
-
48
- group = @group_client.get("test_group_id")
49
- expect(group.id).to eq "test_group_id"
50
- expect(group.name).to eq "test_group_name"
51
- end
52
- end
53
-
54
- describe "#list" do
55
- let(:realm_name) { "valid-realm" }
56
-
57
- before(:each) do
58
- @group_client = KeycloakAdmin.realm(realm_name).groups
59
-
60
- stub_token_client
61
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get).and_return '[{"id":"test_group_id","name":"test_group_name"}]'
62
- end
63
-
64
- it "lists groups" do
65
- groups = @group_client.list
66
- expect(groups.length).to eq 1
67
- expect(groups[0].name).to eq "test_group_name"
68
- end
69
-
70
- it "passes rest client options" do
71
- faraday_options = {timeout: 10}
72
- allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
73
-
74
- expect(KeycloakAdmin::Resource).to receive(:new).with(
75
- "http://auth.service.io/auth/admin/realms/valid-realm/groups", faraday_options).and_call_original
76
-
77
- groups = @group_client.list
78
- expect(groups.length).to eq 1
79
- expect(groups[0].name).to eq "test_group_name"
80
- end
81
- end
82
-
83
-
84
- describe "#children" do
85
- let(:realm_name) { "valid-realm" }
86
-
87
- before(:each) do
88
- @group_client = KeycloakAdmin.realm(realm_name).groups
89
-
90
- stub_token_client
91
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get).and_return '[{"id":"test_group_id","name":"test_group_name"}]'
92
- end
93
-
94
- it "lists children groups" do
95
- groups = @group_client.children("parent_group_id")
96
- expect(groups.length).to eq 1
97
- expect(groups[0].name).to eq "test_group_name"
98
- end
99
-
100
- it "passes rest client options" do
101
- faraday_options = {timeout: 10}
102
- allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
103
-
104
- expect(KeycloakAdmin::Resource).to receive(:new).with(
105
- "http://auth.service.io/auth/admin/realms/valid-realm/groups/parent_group_id/children", faraday_options).and_call_original
106
-
107
- groups = @group_client.children("parent_group_id")
108
- expect(groups.length).to eq 1
109
- expect(groups[0].name).to eq "test_group_name"
110
- end
111
- end
112
-
113
- describe "#save" do
114
- let(:realm_name) { "valid-realm" }
115
-
116
- before(:each) do
117
- @group_client = KeycloakAdmin.realm(realm_name).groups
118
-
119
- stub_token_client
120
- end
121
-
122
- context "when the group does not exist" do
123
- let(:group) { KeycloakAdmin::GroupRepresentation.from_hash(
124
- "name" => "test_group_name"
125
- )}
126
-
127
- before do
128
- response = double
129
- allow(response).to receive(:headers).and_return(
130
- { location: 'http://auth.service.io/auth/admin/realms/valid-realm/groups/be061c48-6edd-4783-a726-1a57d4bfa22b' }
131
- )
132
-
133
- expect_any_instance_of(KeycloakAdmin::Resource).to receive(:post).with(group.to_json, anything).and_return response
134
- end
135
-
136
- it "saves a group" do
137
- @group_client.save(group)
138
- end
139
-
140
- it "passes rest client options" do
141
- faraday_options = {timeout: 10}
142
- allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
143
-
144
- expect(KeycloakAdmin::Resource).to receive(:new).with(
145
- "http://auth.service.io/auth/admin/realms/valid-realm/groups", faraday_options).and_call_original
146
-
147
- @group_client.save(group)
148
- end
149
- end
150
-
151
- context "when the group already exists" do
152
- let(:group) { KeycloakAdmin::GroupRepresentation.from_hash(
153
- "id" => "test_group_id",
154
- "name" => "test_group_name"
155
- )}
156
-
157
- before do
158
- response = double
159
- allow(response).to receive(:headers).and_return(
160
- { location: 'http://auth.service.io/auth/admin/realms/valid-realm/groups/be061c48-6edd-4783-a726-1a57d4bfa22b' }
161
- )
162
-
163
- expect_any_instance_of(KeycloakAdmin::Resource).to receive(:put).with(group.to_json, anything).and_return response
164
- end
165
-
166
- it "saves a group" do
167
- @group_client.save(group)
168
- end
169
-
170
- it "passes rest client options" do
171
- faraday_options = {timeout: 10}
172
- allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
173
-
174
- expect(KeycloakAdmin::Resource).to receive(:new).with(
175
- "http://auth.service.io/auth/admin/realms/valid-realm/groups/test_group_id", faraday_options).and_call_original
176
-
177
- @group_client.save(group)
178
- end
179
- end
180
- end
181
-
182
- describe "#create" do
183
- let(:realm_name) { "valid-realm" }
184
-
185
- before(:each) do
186
- @group_client = KeycloakAdmin.realm(realm_name).groups
187
-
188
- stub_token_client
189
- @response = double(
190
- headers: { location: 'http://auth.service.io/auth/admin/realms/valid-realm/groups/be061c48-6edd-4783-a726-1a57d4bfa22b' },
191
- status: 201,
192
- reason_phrase: 'Created'
193
- )
194
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:post).and_return @response
195
- end
196
-
197
- it "creates a group" do
198
- group_id = @group_client.create!("test_group_name")
199
- expect(group_id).to eq 'be061c48-6edd-4783-a726-1a57d4bfa22b'
200
- end
201
-
202
- it "detects unexpected response to create a group" do
203
- allow(@response).to receive(:status).and_return 200
204
- allow(@response).to receive(:reason_phrase).and_return 'OK'
205
-
206
- expect{ @group_client.create!("test_group_name") }.to raise_error(
207
- 'Create method returned status OK (Code: 200); expected status: Created (201)'
208
- )
209
- end
210
- end
211
-
212
- describe "#create_subgroup!" do
213
- let(:realm_name) { "valid-realm" }
214
-
215
- before(:each) do
216
- @group_client = KeycloakAdmin.realm(realm_name).groups
217
-
218
- stub_token_client
219
- @response = double(
220
- headers: { location: 'http://auth.service.io/auth/admin/realms/valid-realm/groups/7686af34-204c-4515-8122-78d19febbf6e' },
221
- status: 201,
222
- reason_phrase: 'Created'
223
- )
224
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:post).and_return @response
225
- end
226
-
227
- it "creates a subgroup" do
228
- group_id = @group_client.create_subgroup!('be061c48-6edd-4783-a726-1a57d4bfa22b', 'subgroup-name')
229
- expect(group_id).to eq '7686af34-204c-4515-8122-78d19febbf6e'
230
- end
231
- end
232
-
233
- describe "#delete" do
234
- let(:realm_name) { "valid-realm" }
235
-
236
- before(:each) do
237
- @group_client = KeycloakAdmin.realm(realm_name).groups
238
-
239
- stub_token_client
240
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:delete).and_return ''
241
- end
242
-
243
- it "deletes a group" do
244
- result = @group_client.delete("test_group_id")
245
- expect(result).to be(true)
246
- end
247
-
248
- it "raises a delete error" do
249
- faraday_options = {timeout: 10}
250
- allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
251
-
252
- expect(KeycloakAdmin::Resource).to receive(:new).with(
253
- "http://auth.service.io/auth/admin/realms/valid-realm/groups/test_group_id", faraday_options).and_raise("error")
254
-
255
- expect { @group_client.delete("test_group_id") }.to raise_error("error")
256
- end
257
- end
258
-
259
- describe '#get_realm_level_roles' do
260
- let(:realm_name) { 'valid-realm' }
261
- before(:each) do
262
- @group_client = KeycloakAdmin.realm(realm_name).groups
263
- stub_token_client
264
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get).and_return '[{"id":"role-id","name":"role-name"}]'
265
- end
266
-
267
- it 'gets all realm-level roles for a group' do
268
- roles = @group_client.get_realm_level_roles('test-group-id')
269
- expect(roles.length).to eq 1
270
- expect(roles[0].id).to eq 'role-id'
271
- expect(roles[0].name).to eq 'role-name'
272
- end
273
- end
274
-
275
- describe '#add_realm_level_role_name!' do
276
- let(:realm_name) { 'valid-realm' }
277
-
278
- before(:each) do
279
- @group_client = KeycloakAdmin.realm(realm_name).groups
280
-
281
- stub_token_client
282
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:post).and_return ''
283
- end
284
-
285
- it 'adds a realm-level role to a group' do
286
- role_representation = double
287
- allow(role_representation).to receive(:name).and_return 'test-role-name'
288
-
289
- role_client = double
290
- allow(role_client).to receive(:get).with('test-role-name').and_return role_representation
291
- allow(KeycloakAdmin::RoleClient).to receive(:new).and_return role_client
292
-
293
- result = @group_client.add_realm_level_role_name!('test-group-id', 'test-role-name')
294
- expect(result).to eq role_representation
295
- end
296
- end
297
-
298
- describe '#remove_realm_level_role_name!' do
299
- let(:realm_name) { 'valid-realm' }
300
-
301
- before(:each) do
302
- @group_client = KeycloakAdmin.realm(realm_name).groups
303
-
304
- stub_token_client
305
- allow(KeycloakAdmin::Resource).to receive(:execute).and_return ''
306
- end
307
-
308
- it 'deletes a realm-level role from a group' do
309
- role_representation = double
310
- allow(role_representation).to receive(:name).and_return 'test-role-name'
311
-
312
- role_client = double
313
- allow(role_client).to receive(:get).with('test-role-name').and_return role_representation
314
- allow(KeycloakAdmin::RoleClient).to receive(:new).and_return role_client
315
-
316
- result = @group_client.remove_realm_level_role_name!('test-group-id', 'test-role-name')
317
- expect(result).to be(true)
318
- expect(KeycloakAdmin::Resource).to have_received(:execute).with(
319
- hash_including(
320
- url: "http://auth.service.io/auth/admin/realms/valid-realm/groups/test-group-id/role-mappings/realm",
321
- method: :delete,
322
- payload: @group_client.send(:create_payload, [role_representation]),
323
- headers: @group_client.send(:headers)
324
- )
325
- )
326
- end
327
- end
328
- end
@@ -1,92 +0,0 @@
1
- RSpec.describe KeycloakAdmin::IdentityProviderClient do
2
- describe "#identity_providers_url" do
3
- let(:realm_name) { "valid-realm" }
4
- let(:provider_id) { nil }
5
-
6
- before(:each) do
7
- @built_url = KeycloakAdmin.realm(realm_name).identity_providers.identity_providers_url(provider_id)
8
- end
9
-
10
- context "when provider_id is not defined" do
11
- let(:provider_id) { nil }
12
- it "returns a proper url without provider id" do
13
- expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/identity-provider/instances"
14
- end
15
- end
16
-
17
- context "when provider_id is defined" do
18
- let(:provider_id) { "95985b21-d884-4bbd-b852-cb8cd365afc2" }
19
- it "returns a proper url with the provider id" do
20
- expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/identity-provider/instances/95985b21-d884-4bbd-b852-cb8cd365afc2"
21
- end
22
- end
23
- end
24
-
25
- describe "#list" do
26
- let(:realm_name) { "valid-realm" }
27
- let(:json_response) do
28
- <<-JSON
29
- [
30
- {
31
- "alias": "acme",
32
- "displayName": "ACME",
33
- "internalId": "20fea77e-ae3d-411e-9467-2b3a20cd3e6d",
34
- "providerId": "saml",
35
- "enabled": true,
36
- "updateProfileFirstLoginMode": "on",
37
- "trustEmail": true,
38
- "storeToken": false,
39
- "addReadTokenRoleOnCreate": false,
40
- "authenticateByDefault": false,
41
- "linkOnly": false,
42
- "firstBrokerLoginFlowAlias": "first broker login",
43
- "config": {
44
- "hideOnLoginPage": "",
45
- "validateSignature": "true",
46
- "samlXmlKeyNameTranformer": "KEY_ID",
47
- "signingCertificate": "",
48
- "postBindingLogout": "false",
49
- "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
50
- "postBindingResponse": "true",
51
- "backchannelSupported": "",
52
- "signatureAlgorithm": "RSA_SHA256",
53
- "wantAssertionsEncrypted": "false",
54
- "xmlSigKeyInfoKeyNameTransformer": "CERT_SUBJECT",
55
- "useJwksUrl": "true",
56
- "wantAssertionsSigned": "true",
57
- "postBindingAuthnRequest": "true",
58
- "forceAuthn": "",
59
- "wantAuthnRequestsSigned": "true",
60
- "singleSignOnServiceUrl": "https://login.microsoftonline.com/test/saml2",
61
- "addExtensionsElementWithKeyInfo": "false"
62
- }
63
- }
64
- ]
65
- JSON
66
- end
67
- before(:each) do
68
- @identity_provider_client = KeycloakAdmin.realm(realm_name).identity_providers
69
-
70
- stub_token_client
71
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get).and_return json_response
72
- end
73
-
74
- it "lists identity providers" do
75
- identity_providers = @identity_provider_client.list
76
- expect(identity_providers.length).to eq 1
77
- expect(identity_providers[0].alias).to eq "acme"
78
- end
79
-
80
- it "passes rest client options" do
81
- faraday_options = {timeout: 10}
82
- allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
83
-
84
- expect(KeycloakAdmin::Resource).to receive(:new).with(
85
- "http://auth.service.io/auth/admin/realms/valid-realm/identity-provider/instances", faraday_options).and_call_original
86
-
87
- identity_providers = @identity_provider_client.list
88
- expect(identity_providers.length).to eq 1
89
- expect(identity_providers[0].alias).to eq "acme"
90
- end
91
- end
92
- end