keycloak-admin 1.1.3 → 1.1.5
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -4
- data/CHANGELOG.md +200 -188
- data/Gemfile.lock +51 -49
- data/README.md +756 -748
- data/keycloak-admin.gemspec +2 -2
- data/lib/keycloak-admin/client/group_client.rb +17 -0
- data/lib/keycloak-admin/client/role_mapper_client.rb +6 -4
- data/lib/keycloak-admin/client/user_client.rb +12 -0
- data/lib/keycloak-admin/representation/credential_representation.rb +37 -4
- data/lib/keycloak-admin/version.rb +1 -1
- data/spec/client/client_authz_permission_client_spec.rb +1 -1
- data/spec/client/client_authz_policy_client_spec.rb +1 -1
- data/spec/client/group_client_spec.rb +70 -0
- data/spec/client/role_mapper_client_spec.rb +45 -0
- data/spec/client/user_client_spec.rb +45 -0
- data/spec/integration/client_authorization_spec.rb +3 -5
- data/spec/representation/credential_representation_spec.rb +68 -0
- metadata +8 -7
data/keycloak-admin.gemspec
CHANGED
|
@@ -19,6 +19,6 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
|
|
20
20
|
spec.add_dependency "http-cookie", "~> 1.0", ">= 1.0.3"
|
|
21
21
|
spec.add_dependency "rest-client", "~> 2.0"
|
|
22
|
-
spec.add_development_dependency "rspec", "3.
|
|
23
|
-
spec.add_development_dependency "byebug", "
|
|
22
|
+
spec.add_development_dependency "rspec", "3.13.2"
|
|
23
|
+
spec.add_development_dependency "byebug", "12.0.0"
|
|
24
24
|
end
|
|
@@ -108,6 +108,23 @@ module KeycloakAdmin
|
|
|
108
108
|
role_representation
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
+
# Remove a realm-level role from a group by the role name
|
|
112
|
+
def remove_realm_level_role_name!(group_id, role_name)
|
|
113
|
+
role_representation = RoleClient.new(@configuration, @realm_client).get(role_name)
|
|
114
|
+
url = "#{groups_url(group_id)}/role-mappings/realm"
|
|
115
|
+
execute_http do
|
|
116
|
+
RestClient::Request.execute(
|
|
117
|
+
@configuration.rest_client_options.merge(
|
|
118
|
+
url:,
|
|
119
|
+
method: :delete,
|
|
120
|
+
payload: create_payload([role_representation]),
|
|
121
|
+
headers: headers
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
true
|
|
126
|
+
end
|
|
127
|
+
|
|
111
128
|
def groups_url(id=nil)
|
|
112
129
|
if id
|
|
113
130
|
"#{@realm_client.realm_admin_url}/groups/#{id}"
|
|
@@ -23,10 +23,12 @@ module KeycloakAdmin
|
|
|
23
23
|
def remove_realm_level(role_representation_list)
|
|
24
24
|
execute_http do
|
|
25
25
|
RestClient::Request.execute(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
@configuration.rest_client_options.merge(
|
|
27
|
+
method: :delete,
|
|
28
|
+
url: realm_level_url,
|
|
29
|
+
payload: create_payload(role_representation_list),
|
|
30
|
+
headers: headers
|
|
31
|
+
)
|
|
30
32
|
)
|
|
31
33
|
end
|
|
32
34
|
end
|
|
@@ -123,6 +123,13 @@ module KeycloakAdmin
|
|
|
123
123
|
user_id
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
+
def credentials(user_id)
|
|
127
|
+
response = execute_http do
|
|
128
|
+
RestClient::Resource.new(credentials_url(user_id), @configuration.rest_client_options).get(headers)
|
|
129
|
+
end
|
|
130
|
+
JSON.parse(response).map { |group_as_hash| CredentialRepresentation.from_hash(group_as_hash) }
|
|
131
|
+
end
|
|
132
|
+
|
|
126
133
|
def forgot_password(user_id, lifespan=nil)
|
|
127
134
|
execute_actions_email(user_id, ["UPDATE_PASSWORD"], lifespan)
|
|
128
135
|
end
|
|
@@ -232,6 +239,11 @@ module KeycloakAdmin
|
|
|
232
239
|
"#{users_url(user_id)}/groups"
|
|
233
240
|
end
|
|
234
241
|
|
|
242
|
+
def credentials_url(user_id)
|
|
243
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
|
244
|
+
"#{users_url(user_id)}/credentials"
|
|
245
|
+
end
|
|
246
|
+
|
|
235
247
|
def impersonation_url(user_id)
|
|
236
248
|
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
|
237
249
|
"#{users_url(user_id)}/impersonation"
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module KeycloakAdmin
|
|
2
2
|
class CredentialRepresentation < Representation
|
|
3
|
-
attr_accessor :
|
|
3
|
+
attr_accessor :id,
|
|
4
|
+
:type,
|
|
5
|
+
:userLabel,
|
|
4
6
|
:device,
|
|
5
7
|
:value,
|
|
6
8
|
:hashedSaltedValue,
|
|
@@ -10,7 +12,9 @@ module KeycloakAdmin
|
|
|
10
12
|
:algorithm,
|
|
11
13
|
:digits,
|
|
12
14
|
:period,
|
|
13
|
-
:
|
|
15
|
+
:createdDate,
|
|
16
|
+
:credentialData,
|
|
17
|
+
:secretData,
|
|
14
18
|
:config,
|
|
15
19
|
:temporary
|
|
16
20
|
|
|
@@ -30,10 +34,39 @@ module KeycloakAdmin
|
|
|
30
34
|
def self.from_hash(hash)
|
|
31
35
|
credential = new
|
|
32
36
|
hash.each do |key, value|
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
if credential.respond_to?("#{key}=")
|
|
38
|
+
credential.public_send("#{key}=", value)
|
|
39
|
+
end
|
|
35
40
|
end
|
|
41
|
+
|
|
42
|
+
nested_attributes = safely_parse_nested_json(hash["credentialData"]).merge(safely_parse_nested_json(hash["secretData"]))
|
|
43
|
+
|
|
44
|
+
nested_attributes.each do |key, value|
|
|
45
|
+
if credential.respond_to?("#{key}=")
|
|
46
|
+
current_value = credential.public_send(key)
|
|
47
|
+
if current_value.nil?
|
|
48
|
+
credential.public_send("#{key}=", value)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
36
53
|
credential
|
|
37
54
|
end
|
|
55
|
+
|
|
56
|
+
class << self
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def safely_parse_nested_json(json_string)
|
|
60
|
+
if json_string.nil? || json_string.strip.empty?
|
|
61
|
+
{}
|
|
62
|
+
else
|
|
63
|
+
begin
|
|
64
|
+
JSON.parse(json_string)
|
|
65
|
+
rescue JSON::ParserError
|
|
66
|
+
{}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
38
71
|
end
|
|
39
72
|
end
|
|
@@ -255,4 +255,74 @@ RSpec.describe KeycloakAdmin::GroupClient do
|
|
|
255
255
|
expect { @group_client.delete("test_group_id") }.to raise_error("error")
|
|
256
256
|
end
|
|
257
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(RestClient::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(RestClient::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(RestClient::Request).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(RestClient::Request).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
|
|
258
328
|
end
|
|
@@ -65,4 +65,49 @@ RSpec.describe KeycloakAdmin::RoleMapperClient do
|
|
|
65
65
|
@role_mapper_client.save_realm_level(role_list)
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
|
+
|
|
69
|
+
describe "#remove_realm_level" do
|
|
70
|
+
let(:realm_name) { "valid-realm" }
|
|
71
|
+
let(:user_id) { "test_user" }
|
|
72
|
+
let(:role_list) { [
|
|
73
|
+
KeycloakAdmin::RoleRepresentation.from_hash(
|
|
74
|
+
"id" => "d9e3376b-f602-4086-8eee-89fea73c73ea"
|
|
75
|
+
)
|
|
76
|
+
] }
|
|
77
|
+
let(:expected_url) { "http://auth.service.io/auth/admin/realms/valid-realm/users/test_user/role-mappings/realm" }
|
|
78
|
+
|
|
79
|
+
before(:each) do
|
|
80
|
+
@role_mapper_client = KeycloakAdmin.realm(realm_name).user(user_id).role_mapper
|
|
81
|
+
|
|
82
|
+
stub_token_client
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "removes realm-level role mappings" do
|
|
86
|
+
expect(RestClient::Request).to receive(:execute).with(
|
|
87
|
+
hash_including(
|
|
88
|
+
method: :delete,
|
|
89
|
+
url: expected_url,
|
|
90
|
+
payload: role_list.to_json
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
@role_mapper_client.remove_realm_level(role_list)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "passes rest client options" do
|
|
98
|
+
rest_client_options = {timeout: 10}
|
|
99
|
+
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:rest_client_options).and_return rest_client_options
|
|
100
|
+
|
|
101
|
+
expect(RestClient::Request).to receive(:execute).with(
|
|
102
|
+
hash_including(
|
|
103
|
+
method: :delete,
|
|
104
|
+
url: expected_url,
|
|
105
|
+
payload: role_list.to_json,
|
|
106
|
+
timeout: 10
|
|
107
|
+
)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
@role_mapper_client.remove_realm_level(role_list)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
68
113
|
end
|
|
@@ -370,4 +370,49 @@ RSpec.describe KeycloakAdmin::TokenClient do
|
|
|
370
370
|
end
|
|
371
371
|
end
|
|
372
372
|
end
|
|
373
|
+
|
|
374
|
+
describe '#credentials' do
|
|
375
|
+
let(:realm_name) { "valid-realm" }
|
|
376
|
+
|
|
377
|
+
before(:each) do
|
|
378
|
+
@user_client = KeycloakAdmin.realm(realm_name).users
|
|
379
|
+
stub_token_client
|
|
380
|
+
json_payload = <<-'payload'
|
|
381
|
+
[
|
|
382
|
+
{
|
|
383
|
+
"id": "2ff4b4d0-fd72-4c6e-9684-02ab337687c2",
|
|
384
|
+
"type": "password",
|
|
385
|
+
"userLabel": "My password",
|
|
386
|
+
"createdDate": 1767604673211,
|
|
387
|
+
"credentialData": "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"id": "34389672-9356-4154-9ed6-6c212b869010",
|
|
391
|
+
"type": "otp",
|
|
392
|
+
"userLabel": "Smartphone",
|
|
393
|
+
"createdDate": 1767605202060,
|
|
394
|
+
"credentialData": "{\"subType\":\"totp\",\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\"}"
|
|
395
|
+
}
|
|
396
|
+
]
|
|
397
|
+
payload
|
|
398
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return json_payload
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
context 'when user_id is defined' do
|
|
402
|
+
let(:user_id) { '95985b21-d884-4bbd-b852-cb8cd365afc2' }
|
|
403
|
+
it 'returns list of credentials' do
|
|
404
|
+
response = @user_client.credentials(user_id)
|
|
405
|
+
expect(response.size).to eq 2
|
|
406
|
+
expect(response[0].id).to eq "2ff4b4d0-fd72-4c6e-9684-02ab337687c2"
|
|
407
|
+
expect(response[1].id).to eq "34389672-9356-4154-9ed6-6c212b869010"
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
context 'when user_id is not defined' do
|
|
412
|
+
let(:user_id) { nil }
|
|
413
|
+
it 'raise argument error' do
|
|
414
|
+
expect { @user_client.credentials(user_id) }.to raise_error(ArgumentError)
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
end
|
|
373
418
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
RSpec.describe 'ClientAuthorization' do
|
|
2
2
|
|
|
3
|
-
before do
|
|
4
|
-
skip unless ENV["GITHUB_ACTIONS"]
|
|
3
|
+
before(:each) do
|
|
4
|
+
skip("This test requires to be run in a Github action.") unless ENV["GITHUB_ACTIONS"]
|
|
5
5
|
|
|
6
6
|
KeycloakAdmin.configure do |config|
|
|
7
7
|
config.use_service_account = false
|
|
@@ -14,14 +14,12 @@ RSpec.describe 'ClientAuthorization' do
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
after do
|
|
17
|
+
after(:each) do
|
|
18
18
|
configure
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
describe "ClientAuthorization Suite" do
|
|
22
22
|
it do
|
|
23
|
-
skip unless ENV["GITHUB_ACTIONS"]
|
|
24
|
-
|
|
25
23
|
realm_name = "dummy"
|
|
26
24
|
|
|
27
25
|
client = KeycloakAdmin.realm(realm_name).clients.find_by_client_id("dummy-client")
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
|
|
2
|
+
RSpec.describe KeycloakAdmin::CredentialRepresentation do
|
|
3
|
+
describe ".from_json" do
|
|
4
|
+
it "parses a password" do
|
|
5
|
+
json_payload = <<-'payload'
|
|
6
|
+
{
|
|
7
|
+
"id": "2ff4b4d0-fd72-4c6e-9684-02ab337687c2",
|
|
8
|
+
"type": "password",
|
|
9
|
+
"userLabel": "My password",
|
|
10
|
+
"createdDate": 1767604673211,
|
|
11
|
+
"credentialData": "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}"
|
|
12
|
+
}
|
|
13
|
+
payload
|
|
14
|
+
|
|
15
|
+
credential = described_class.from_json(json_payload)
|
|
16
|
+
expect(credential).to be
|
|
17
|
+
expect(credential).to be_a described_class
|
|
18
|
+
expect(credential.id).to eq "2ff4b4d0-fd72-4c6e-9684-02ab337687c2"
|
|
19
|
+
expect(credential.type).to eq "password"
|
|
20
|
+
expect(credential.createdDate).to eq 1767604673211
|
|
21
|
+
expect(credential.credentialData).to eq "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}"
|
|
22
|
+
expect(credential.userLabel).to eq "My password"
|
|
23
|
+
expect(credential.device).to be_nil
|
|
24
|
+
expect(credential.value).to be_nil
|
|
25
|
+
expect(credential.hashedSaltedValue).to be_nil
|
|
26
|
+
expect(credential.salt).to be_nil
|
|
27
|
+
expect(credential.hashIterations).to eq 5
|
|
28
|
+
expect(credential.counter).to be_nil
|
|
29
|
+
expect(credential.algorithm).to eq "argon2"
|
|
30
|
+
expect(credential.digits).to be_nil
|
|
31
|
+
expect(credential.period).to be_nil
|
|
32
|
+
expect(credential.config).to be_nil
|
|
33
|
+
expect(credential.temporary).to be_nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "parses an otp" do
|
|
37
|
+
json_payload = <<-'payload'
|
|
38
|
+
{
|
|
39
|
+
"id": "34389672-9356-4154-9ed6-6c212b869010",
|
|
40
|
+
"type": "otp",
|
|
41
|
+
"userLabel": "Smartphone",
|
|
42
|
+
"createdDate": 1767605202060,
|
|
43
|
+
"credentialData": "{\"subType\":\"totp\",\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\"}"
|
|
44
|
+
}
|
|
45
|
+
payload
|
|
46
|
+
|
|
47
|
+
credential = described_class.from_json(json_payload)
|
|
48
|
+
expect(credential).to be
|
|
49
|
+
expect(credential).to be_a described_class
|
|
50
|
+
expect(credential.id).to eq "34389672-9356-4154-9ed6-6c212b869010"
|
|
51
|
+
expect(credential.type).to eq "otp"
|
|
52
|
+
expect(credential.createdDate).to eq 1767605202060
|
|
53
|
+
expect(credential.credentialData).to eq "{\"subType\":\"totp\",\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\"}"
|
|
54
|
+
expect(credential.userLabel).to eq "Smartphone"
|
|
55
|
+
expect(credential.device).to be_nil
|
|
56
|
+
expect(credential.value).to be_nil
|
|
57
|
+
expect(credential.hashedSaltedValue).to be_nil
|
|
58
|
+
expect(credential.salt).to be_nil
|
|
59
|
+
expect(credential.hashIterations).to be_nil
|
|
60
|
+
expect(credential.counter).to eq 0
|
|
61
|
+
expect(credential.algorithm).to eq "HmacSHA1"
|
|
62
|
+
expect(credential.digits).to eq 6
|
|
63
|
+
expect(credential.period).to eq 30
|
|
64
|
+
expect(credential.config).to be_nil
|
|
65
|
+
expect(credential.temporary).to be_nil
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: keycloak-admin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lorent Lempereur
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: http-cookie
|
|
@@ -50,28 +50,28 @@ dependencies:
|
|
|
50
50
|
requirements:
|
|
51
51
|
- - '='
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 3.
|
|
53
|
+
version: 3.13.2
|
|
54
54
|
type: :development
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - '='
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 3.
|
|
60
|
+
version: 3.13.2
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: byebug
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - '='
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
67
|
+
version: 12.0.0
|
|
68
68
|
type: :development
|
|
69
69
|
prerelease: false
|
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - '='
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version:
|
|
74
|
+
version: 12.0.0
|
|
75
75
|
description: Keycloak Admin REST API client written in Ruby
|
|
76
76
|
email:
|
|
77
77
|
- lorent.lempereur.dev@gmail.com
|
|
@@ -160,6 +160,7 @@ files:
|
|
|
160
160
|
- spec/representation/client_authz_resource_representation_spec.rb
|
|
161
161
|
- spec/representation/client_authz_scope_representation_spec.rb
|
|
162
162
|
- spec/representation/client_representation_spec.rb
|
|
163
|
+
- spec/representation/credential_representation_spec.rb
|
|
163
164
|
- spec/representation/group_representation_spec.rb
|
|
164
165
|
- spec/representation/identity_provider_mapper_representation_spec.rb
|
|
165
166
|
- spec/representation/identity_provider_representation_spec.rb
|
|
@@ -190,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
190
191
|
- !ruby/object:Gem::Version
|
|
191
192
|
version: '0'
|
|
192
193
|
requirements: []
|
|
193
|
-
rubygems_version: 3.
|
|
194
|
+
rubygems_version: 3.3.7
|
|
194
195
|
signing_key:
|
|
195
196
|
specification_version: 4
|
|
196
197
|
summary: Keycloak Admin REST API client written in Ruby
|