keycloak-admin 1.0.21 → 1.0.22
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/CHANGELOG.md +6 -0
- data/Dockerfile +1 -1
- data/Gemfile.lock +5 -5
- data/README.md +1 -1
- data/lib/keycloak-admin/client/attack_detection_client.rb +42 -0
- data/lib/keycloak-admin/client/client.rb +2 -2
- data/lib/keycloak-admin/client/realm_client.rb +4 -0
- data/lib/keycloak-admin/client/user_client.rb +50 -13
- data/lib/keycloak-admin/representation/attack_detection_representation.rb +17 -0
- data/lib/keycloak-admin/representation/federated_identity_representation.rb +3 -3
- data/lib/keycloak-admin/representation/session_representation.rb +23 -0
- data/lib/keycloak-admin/resource/base_role_containing_resource.rb +1 -1
- data/lib/keycloak-admin/version.rb +1 -1
- data/lib/keycloak-admin.rb +3 -0
- data/spec/client/attack_detection_client_spec.rb +102 -0
- data/spec/client/user_client_spec.rb +77 -0
- data/spec/representation/attack_detection_representation_spec.rb +16 -0
- data/spec/representation/session_representation_spec.rb +16 -0
- data/spec/spec_helper.rb +2 -2
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f50997d1b2b3688cb70a8f23ee49d0691dffc312d6b2ebc0ba9860ff2517d65
|
4
|
+
data.tar.gz: 9a778464a35c8bf11e90a23249ab7ac11c6d7e95ab39d4bec1e78a3a47f1a685
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39f2301f9cafc3e4b66cdeadb7347de01ee38f492686e138698d5e48de1da10dc1621df829aa6750fc2bf2198d78d9bfe36e82f7e263c1b1c3b671be94fdd7a6
|
7
|
+
data.tar.gz: 2bed1fdf4667cae74c4b843fed95921d41d7f7e5b3a9f66b4437f1dd62fe9cc0413aa778e9184881fc180ecf346dce6b33f4a917b8fd4dac9b7590b66467e81a
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [1.0.22] - 2023-05-29
|
9
|
+
|
10
|
+
* Fetch user's all active sessions (thanks to @prsanjay)
|
11
|
+
* Check whether a user is locked or not (thanks to @prsanjay)
|
12
|
+
* Logout users from all the active sessions (thanks to @prsanjay)
|
13
|
+
|
8
14
|
## [1.0.21] - 2023-02-03
|
9
15
|
|
10
16
|
* List users who are a member of a group (thanks to @tlloydthwaites)
|
data/Dockerfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
keycloak-admin (1.0.
|
4
|
+
keycloak-admin (1.0.22)
|
5
5
|
http-cookie (~> 1.0, >= 1.0.3)
|
6
6
|
rest-client (~> 2.1)
|
7
7
|
|
@@ -17,7 +17,7 @@ GEM
|
|
17
17
|
domain_name (~> 0.5)
|
18
18
|
mime-types (3.4.1)
|
19
19
|
mime-types-data (~> 3.2015)
|
20
|
-
mime-types-data (3.
|
20
|
+
mime-types-data (3.2023.0218.1)
|
21
21
|
netrc (0.11.0)
|
22
22
|
rest-client (2.1.0)
|
23
23
|
http-accept (>= 1.7.0, < 2.0)
|
@@ -28,12 +28,12 @@ GEM
|
|
28
28
|
rspec-core (~> 3.12.0)
|
29
29
|
rspec-expectations (~> 3.12.0)
|
30
30
|
rspec-mocks (~> 3.12.0)
|
31
|
-
rspec-core (3.12.
|
31
|
+
rspec-core (3.12.2)
|
32
32
|
rspec-support (~> 3.12.0)
|
33
|
-
rspec-expectations (3.12.
|
33
|
+
rspec-expectations (3.12.3)
|
34
34
|
diff-lcs (>= 1.2.0, < 2.0)
|
35
35
|
rspec-support (~> 3.12.0)
|
36
|
-
rspec-mocks (3.12.
|
36
|
+
rspec-mocks (3.12.5)
|
37
37
|
diff-lcs (>= 1.2.0, < 2.0)
|
38
38
|
rspec-support (~> 3.12.0)
|
39
39
|
rspec-support (3.12.0)
|
data/README.md
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
module KeycloakAdmin
|
2
|
+
class AttackDetectionClient < Client
|
3
|
+
def initialize(configuration, realm_client)
|
4
|
+
super(configuration)
|
5
|
+
raise ArgumentError.new("realm must be defined") unless realm_client.name_defined?
|
6
|
+
@realm_client = realm_client
|
7
|
+
end
|
8
|
+
|
9
|
+
def lock_status(user_id)
|
10
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
11
|
+
|
12
|
+
response = execute_http do
|
13
|
+
RestClient::Resource.new(brute_force_url(user_id), @configuration.rest_client_options).get(headers)
|
14
|
+
end
|
15
|
+
AttackDetectionRepresentation.from_hash(JSON.parse(response))
|
16
|
+
end
|
17
|
+
|
18
|
+
def unlock_user(user_id)
|
19
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
20
|
+
|
21
|
+
execute_http do
|
22
|
+
RestClient::Resource.new(brute_force_url(user_id), @configuration.rest_client_options).delete(headers)
|
23
|
+
end
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def unlock_users
|
28
|
+
execute_http do
|
29
|
+
RestClient::Resource.new(brute_force_url, @configuration.rest_client_options).delete(headers)
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def brute_force_url(user_id = nil)
|
35
|
+
if user_id
|
36
|
+
"#{@realm_client.realm_admin_url}/attack-detection/brute-force/users/#{user_id}"
|
37
|
+
else
|
38
|
+
"#{@realm_client.realm_admin_url}/attack-detection/brute-force/users"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -33,7 +33,7 @@ module KeycloakAdmin
|
|
33
33
|
unless response.net_http_res.is_a? Net::HTTPCreated
|
34
34
|
raise "Create method returned status #{response.net_http_res.message} (Code: #{response.net_http_res.code}); expected status: Created (201)"
|
35
35
|
end
|
36
|
-
(_head, _separator, id) = response.headers[:location].rpartition(
|
36
|
+
(_head, _separator, id) = response.headers[:location].rpartition("/")
|
37
37
|
id
|
38
38
|
end
|
39
39
|
|
@@ -41,7 +41,7 @@ module KeycloakAdmin
|
|
41
41
|
if value.nil?
|
42
42
|
""
|
43
43
|
elsif value.kind_of?(Array)
|
44
|
-
"[#{value.map(&:to_json) *
|
44
|
+
"[#{value.map(&:to_json) * ","}]"
|
45
45
|
else
|
46
46
|
value.to_json
|
47
47
|
end
|
@@ -20,15 +20,19 @@ module KeycloakAdmin
|
|
20
20
|
user_representation
|
21
21
|
end
|
22
22
|
|
23
|
-
def update(user_id,
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
def update(user_id, payload = {})
|
24
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
25
|
+
|
26
|
+
user = UserRepresentation.new
|
27
|
+
user.first_name = payload[:name]
|
28
|
+
user.enabled = payload[:enabled]
|
29
|
+
user.attributes = payload[:attributes]
|
30
|
+
execute_http do
|
31
|
+
RestClient::Resource.new(users_url(user_id), @configuration.rest_client_options).put(
|
32
|
+
create_payload(user), headers
|
30
33
|
)
|
31
|
-
|
34
|
+
end
|
35
|
+
true
|
32
36
|
end
|
33
37
|
|
34
38
|
def add_group(user_id, group_id)
|
@@ -113,7 +117,7 @@ module KeycloakAdmin
|
|
113
117
|
@configuration.rest_client_options.merge(
|
114
118
|
method: :put,
|
115
119
|
url: reset_password_url(user_id),
|
116
|
-
payload: { type:
|
120
|
+
payload: { type: "password", value: new_password, temporary: false }.to_json,
|
117
121
|
headers: headers
|
118
122
|
)
|
119
123
|
)
|
@@ -125,10 +129,13 @@ module KeycloakAdmin
|
|
125
129
|
execute_actions_email(user_id, ["UPDATE_PASSWORD"], lifespan)
|
126
130
|
end
|
127
131
|
|
128
|
-
def execute_actions_email(user_id, actions=[], lifespan=nil)
|
132
|
+
def execute_actions_email(user_id, actions=[], lifespan=nil, redirect_uri=nil, client_id=nil)
|
133
|
+
raise ArgumentError.new("client_id must be defined") if client_id.nil? && !redirect_uri.nil?
|
129
134
|
execute_http do
|
130
|
-
lifespan_param = lifespan.nil? ? "" : "lifespan=#{lifespan.seconds}"
|
131
|
-
|
135
|
+
lifespan_param = lifespan.nil? ? "" : "&lifespan=#{lifespan.seconds}"
|
136
|
+
redirect_uri_param = redirect_uri.nil? ? "" : "&redirect_uri=#{redirect_uri}"
|
137
|
+
client_id_param = client_id.nil? ? "" : "client_id=#{client_id}"
|
138
|
+
RestClient.put("#{execute_actions_email_url(user_id)}?#{client_id_param}#{redirect_uri_param}#{lifespan_param}", create_payload(actions), headers)
|
132
139
|
end
|
133
140
|
user_id
|
134
141
|
end
|
@@ -148,6 +155,30 @@ module KeycloakAdmin
|
|
148
155
|
ImpersonationRepresentation.from_response(response, @configuration.server_domain)
|
149
156
|
end
|
150
157
|
|
158
|
+
def sessions(user_id)
|
159
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
160
|
+
|
161
|
+
response = execute_http do
|
162
|
+
RestClient::Resource.new("#{users_url(user_id)}/sessions", @configuration.rest_client_options).get(headers)
|
163
|
+
end
|
164
|
+
JSON.parse(response).map { |session_as_hash| SessionRepresentation.from_hash(session_as_hash) }
|
165
|
+
end
|
166
|
+
|
167
|
+
def logout(user_id)
|
168
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
169
|
+
|
170
|
+
execute_http do
|
171
|
+
RestClient::Request.execute(
|
172
|
+
@configuration.rest_client_options.merge(
|
173
|
+
method: :post,
|
174
|
+
url: logout_url(user_id),
|
175
|
+
headers: headers
|
176
|
+
)
|
177
|
+
)
|
178
|
+
end
|
179
|
+
true
|
180
|
+
end
|
181
|
+
|
151
182
|
def get_redirect_impersonation(user_id)
|
152
183
|
ImpersonationRedirectionRepresentation.from_url(impersonation_url(user_id), headers)
|
153
184
|
end
|
@@ -214,6 +245,12 @@ module KeycloakAdmin
|
|
214
245
|
"#{users_url(user_id)}/federated-identity/#{identity_provider}"
|
215
246
|
end
|
216
247
|
|
248
|
+
def logout_url(user_id)
|
249
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
250
|
+
|
251
|
+
"#{users_url(user_id)}/logout"
|
252
|
+
end
|
253
|
+
|
217
254
|
private
|
218
255
|
|
219
256
|
def build(username, email, password, email_verified, locale, attributes={})
|
@@ -224,7 +261,7 @@ module KeycloakAdmin
|
|
224
261
|
user.enabled = true
|
225
262
|
user.attributes = attributes || {}
|
226
263
|
user.attributes[:locale] = locale if locale
|
227
|
-
user.add_credential(CredentialRepresentation.from_password(password))
|
264
|
+
user.add_credential(CredentialRepresentation.from_password(password)) if !password.nil?
|
228
265
|
user
|
229
266
|
end
|
230
267
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module KeycloakAdmin
|
2
|
+
class AttackDetectionRepresentation < Representation
|
3
|
+
attr_accessor :num_failures,
|
4
|
+
:disabled,
|
5
|
+
:last_ip_failure,
|
6
|
+
:last_failure
|
7
|
+
|
8
|
+
def self.from_hash(hash)
|
9
|
+
rep = new
|
10
|
+
rep.num_failures = hash["numFailures"]
|
11
|
+
rep.disabled = hash["disabled"]
|
12
|
+
rep.last_ip_failure = hash["lastIPFailure"]
|
13
|
+
rep.last_failure = hash["lastFailure"]
|
14
|
+
rep
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,9 +6,9 @@ module KeycloakAdmin
|
|
6
6
|
|
7
7
|
def self.from_hash(hash)
|
8
8
|
rep = new
|
9
|
-
rep.identity_provider = hash[
|
10
|
-
rep.user_id = hash[
|
11
|
-
rep.user_name = hash[
|
9
|
+
rep.identity_provider = hash["identityProvider"]
|
10
|
+
rep.user_id = hash["userId"]
|
11
|
+
rep.user_name = hash["userName"]
|
12
12
|
rep
|
13
13
|
end
|
14
14
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module KeycloakAdmin
|
2
|
+
class SessionRepresentation < Representation
|
3
|
+
attr_accessor :id,
|
4
|
+
:username,
|
5
|
+
:user_id,
|
6
|
+
:ip_address,
|
7
|
+
:start,
|
8
|
+
:last_access,
|
9
|
+
:remember_me,
|
10
|
+
|
11
|
+
def self.from_hash(hash)
|
12
|
+
rep = new
|
13
|
+
rep.id = hash["id"]
|
14
|
+
rep.username = hash["username"]
|
15
|
+
rep.user_id = hash["userId"]
|
16
|
+
rep.ip_address = hash["ipAddress"]
|
17
|
+
rep.start = hash["start"]
|
18
|
+
rep.last_access = hash["lastAccess"]
|
19
|
+
rep.remember_me = hash["rememberMe"]
|
20
|
+
rep
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/keycloak-admin.rb
CHANGED
@@ -13,6 +13,7 @@ require_relative "keycloak-admin/client/token_client"
|
|
13
13
|
require_relative "keycloak-admin/client/user_client"
|
14
14
|
require_relative "keycloak-admin/client/identity_provider_client"
|
15
15
|
require_relative "keycloak-admin/client/configurable_token_client"
|
16
|
+
require_relative "keycloak-admin/client/attack_detection_client"
|
16
17
|
require_relative "keycloak-admin/representation/camel_json"
|
17
18
|
require_relative "keycloak-admin/representation/representation"
|
18
19
|
require_relative "keycloak-admin/representation/protocol_mapper_representation"
|
@@ -28,6 +29,8 @@ require_relative "keycloak-admin/representation/federated_identity_representatio
|
|
28
29
|
require_relative "keycloak-admin/representation/user_representation"
|
29
30
|
require_relative "keycloak-admin/representation/identity_provider_mapper_representation"
|
30
31
|
require_relative "keycloak-admin/representation/identity_provider_representation"
|
32
|
+
require_relative "keycloak-admin/representation/attack_detection_representation"
|
33
|
+
require_relative "keycloak-admin/representation/session_representation"
|
31
34
|
require_relative "keycloak-admin/resource/base_role_containing_resource"
|
32
35
|
require_relative "keycloak-admin/resource/group_resource"
|
33
36
|
require_relative "keycloak-admin/resource/user_resource"
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe KeycloakAdmin::AttackDetectionClient do
|
4
|
+
describe "#initialize" do
|
5
|
+
let(:realm_name) { nil }
|
6
|
+
before(:each) do
|
7
|
+
@realm = KeycloakAdmin.realm(realm_name)
|
8
|
+
end
|
9
|
+
context "when realm_name is defined" do
|
10
|
+
let(:realm_name) { "master" }
|
11
|
+
it "does not raise any error" do
|
12
|
+
expect { @realm.attack_detections }.to_not raise_error
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when realm_name is not defined" do
|
17
|
+
it "raise argument error" do
|
18
|
+
expect { @realm.attack_detections }.to raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#lock_status" do
|
24
|
+
let(:realm_name) { "valid-realm" }
|
25
|
+
before(:each) do
|
26
|
+
@attack_detections = KeycloakAdmin.realm(realm_name).attack_detections
|
27
|
+
stub_token_client
|
28
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return '{"numFailures":1,"disabled":true, "lastFailure":123456}'
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when user_id is defined" do
|
32
|
+
let(:user_id) { "test_user_id" }
|
33
|
+
it "returns lock details" do
|
34
|
+
response = @attack_detections.lock_status(user_id)
|
35
|
+
expect(response.num_failures).to eq 1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when user_id is not defined" do
|
40
|
+
let(:user_id) { nil }
|
41
|
+
it "raise argument error" do
|
42
|
+
expect { @attack_detections.lock_status(user_id) }.to raise_error(ArgumentError)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#unlock_user" do
|
48
|
+
let(:realm_name) { "valid-realm" }
|
49
|
+
before(:each) do
|
50
|
+
@attack_detections = KeycloakAdmin.realm(realm_name).attack_detections
|
51
|
+
stub_token_client
|
52
|
+
allow_any_instance_of(RestClient::Resource).to receive(:delete)
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when user_id is defined" do
|
56
|
+
let(:user_id) { "test_user_id" }
|
57
|
+
it "returns true" do
|
58
|
+
expect(@attack_detections.unlock_user(user_id)).to be_truthy
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when user_id is not defined" do
|
63
|
+
let(:user_id) { nil }
|
64
|
+
it "raise argument error" do
|
65
|
+
expect { @attack_detections.unlock_user(user_id) }.to raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#unlock_users" do
|
71
|
+
let(:realm_name) { "valid-realm" }
|
72
|
+
before(:each) do
|
73
|
+
@attack_detections = KeycloakAdmin.realm(realm_name).attack_detections
|
74
|
+
stub_token_client
|
75
|
+
allow_any_instance_of(RestClient::Resource).to receive(:delete)
|
76
|
+
end
|
77
|
+
it "returns true" do
|
78
|
+
expect(@attack_detections.unlock_users).to be_truthy
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#brute_force_url" do
|
83
|
+
let(:realm_name) { "valid-realm" }
|
84
|
+
let(:user_id) { nil }
|
85
|
+
before(:each) do
|
86
|
+
@attack_detections_url = KeycloakAdmin.realm(realm_name).attack_detections.brute_force_url(user_id)
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when user_id is defined" do
|
90
|
+
let(:user_id) { "95985b21-d884-4bbd-b852-cb8cd365afc2" }
|
91
|
+
it "returns user specific url" do
|
92
|
+
expect(@attack_detections_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/attack-detection/brute-force/users/#{user_id}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when user_id is not defined" do
|
97
|
+
it "returns url without user" do
|
98
|
+
expect(@attack_detections_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/attack-detection/brute-force/users"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -282,4 +282,81 @@ RSpec.describe KeycloakAdmin::TokenClient do
|
|
282
282
|
@user_client.delete('test_user_id')
|
283
283
|
end
|
284
284
|
end
|
285
|
+
|
286
|
+
describe '#update' do
|
287
|
+
let(:realm_name) { 'valid-realm' }
|
288
|
+
before(:each) do
|
289
|
+
@user_client = KeycloakAdmin.realm(realm_name).users
|
290
|
+
|
291
|
+
stub_token_client
|
292
|
+
allow_any_instance_of(RestClient::Resource).to receive(:put)
|
293
|
+
end
|
294
|
+
|
295
|
+
context 'when user_id is defined' do
|
296
|
+
let(:user_id) { '95985b21-d884-4bbd-b852-cb8cd365afc2' }
|
297
|
+
|
298
|
+
it 'updates the user details' do
|
299
|
+
response = @user_client.update(user_id, { name: 'Test', enabled: false })
|
300
|
+
expect(response).to be_truthy
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
context 'when user_id is not defined' do
|
305
|
+
let(:user_id) { '95985b21-d884-4bbd-b852-cb8cd365afc2' }
|
306
|
+
|
307
|
+
let(:user_id) { nil }
|
308
|
+
it 'raise argument error' do
|
309
|
+
expect { @user_client.update(user_id, { name: 'Test', enabled: false }) }.to raise_error(ArgumentError)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
describe '#sessions' do
|
315
|
+
let(:realm_name) { "valid-realm" }
|
316
|
+
|
317
|
+
before(:each) do
|
318
|
+
@user_client = KeycloakAdmin.realm(realm_name).users
|
319
|
+
stub_token_client
|
320
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return '[{"id":"95985b21-d884-4bbd-b852-dsfsdfsd","username":"test_username", "ip_address":"0.0.0.0"}]'
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'when user_id is defined' do
|
324
|
+
let(:user_id) { '95985b21-d884-4bbd-b852-cb8cd365afc2' }
|
325
|
+
it 'returns list of active sessions' do
|
326
|
+
response = @user_client.sessions(user_id)
|
327
|
+
expect(response[0].id).to eq '95985b21-d884-4bbd-b852-dsfsdfsd'
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
context 'when user_id is not defined' do
|
332
|
+
let(:user_id) { nil }
|
333
|
+
it 'raise argument error' do
|
334
|
+
expect { @user_client.sessions(user_id) }.to raise_error(ArgumentError)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
describe '#logout' do
|
340
|
+
let(:realm_name) { 'valid-realm' }
|
341
|
+
|
342
|
+
before(:each) do
|
343
|
+
@user_client = KeycloakAdmin.realm(realm_name).users
|
344
|
+
stub_token_client
|
345
|
+
allow_any_instance_of(RestClient::Request).to receive(:execute)
|
346
|
+
end
|
347
|
+
|
348
|
+
context 'when user_id is defined' do
|
349
|
+
let(:user_id) { '95985b21-d884-4bbd-b852-cb8cd365afc2' }
|
350
|
+
it 'logout user and return true' do
|
351
|
+
expect(@user_client.logout(user_id)).to be_truthy
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
context 'when user_id is not defined' do
|
356
|
+
let(:user_id) { nil }
|
357
|
+
it 'raise argument error' do
|
358
|
+
expect { @user_client.logout(user_id) }.to raise_error(ArgumentError)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
285
362
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe KeycloakAdmin::AttackDetectionRepresentation do
|
4
|
+
describe '.from_hash' do
|
5
|
+
it 'converts json response to class structure' do
|
6
|
+
rep = described_class.from_hash({
|
7
|
+
'numFailures' => 2,
|
8
|
+
'disabled' => true,
|
9
|
+
'lastIPFailure' => 12345,
|
10
|
+
'last_failure' => 12345678
|
11
|
+
})
|
12
|
+
expect(rep.num_failures).to eq 2
|
13
|
+
expect(rep).to be_a described_class
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe KeycloakAdmin::SessionRepresentation do
|
4
|
+
describe '.from_hash' do
|
5
|
+
it 'converts json response to class structure' do
|
6
|
+
rep = described_class.from_hash({
|
7
|
+
'username' => 'test_username',
|
8
|
+
'userId' => '95985b21-d884-4bbd-b852-cb8cd365afc2',
|
9
|
+
'ipAddress' => '1.1.1.1',
|
10
|
+
'start' => 12345678
|
11
|
+
})
|
12
|
+
expect(rep.user_id).to eq '95985b21-d884-4bbd-b852-cb8cd365afc2'
|
13
|
+
expect(rep).to be_a described_class
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -23,8 +23,8 @@ end
|
|
23
23
|
|
24
24
|
def stub_token_client
|
25
25
|
allow_any_instance_of(KeycloakAdmin::TokenClient).to receive(:get).and_return KeycloakAdmin::TokenRepresentation.new(
|
26
|
-
|
27
|
-
|
26
|
+
"test_access_token", "token_type", "expires_in", "refresh_token",
|
27
|
+
"refresh_expires_in", "id_token", "not_before_policy", "session_state"
|
28
28
|
)
|
29
29
|
end
|
30
30
|
|
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.0.
|
4
|
+
version: 1.0.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorent Lempereur
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-cookie
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- README.md
|
90
90
|
- keycloak-admin.gemspec
|
91
91
|
- lib/keycloak-admin.rb
|
92
|
+
- lib/keycloak-admin/client/attack_detection_client.rb
|
92
93
|
- lib/keycloak-admin/client/client.rb
|
93
94
|
- lib/keycloak-admin/client/client_client.rb
|
94
95
|
- lib/keycloak-admin/client/client_role_client.rb
|
@@ -102,6 +103,7 @@ files:
|
|
102
103
|
- lib/keycloak-admin/client/token_client.rb
|
103
104
|
- lib/keycloak-admin/client/user_client.rb
|
104
105
|
- lib/keycloak-admin/configuration.rb
|
106
|
+
- lib/keycloak-admin/representation/attack_detection_representation.rb
|
105
107
|
- lib/keycloak-admin/representation/camel_json.rb
|
106
108
|
- lib/keycloak-admin/representation/client_representation.rb
|
107
109
|
- lib/keycloak-admin/representation/credential_representation.rb
|
@@ -115,12 +117,14 @@ files:
|
|
115
117
|
- lib/keycloak-admin/representation/realm_representation.rb
|
116
118
|
- lib/keycloak-admin/representation/representation.rb
|
117
119
|
- lib/keycloak-admin/representation/role_representation.rb
|
120
|
+
- lib/keycloak-admin/representation/session_representation.rb
|
118
121
|
- lib/keycloak-admin/representation/token_representation.rb
|
119
122
|
- lib/keycloak-admin/representation/user_representation.rb
|
120
123
|
- lib/keycloak-admin/resource/base_role_containing_resource.rb
|
121
124
|
- lib/keycloak-admin/resource/group_resource.rb
|
122
125
|
- lib/keycloak-admin/resource/user_resource.rb
|
123
126
|
- lib/keycloak-admin/version.rb
|
127
|
+
- spec/client/attack_detection_client_spec.rb
|
124
128
|
- spec/client/client_client_spec.rb
|
125
129
|
- spec/client/client_role_mappings_client_spec.rb
|
126
130
|
- spec/client/client_spec.rb
|
@@ -133,6 +137,7 @@ files:
|
|
133
137
|
- spec/client/token_client_spec.rb
|
134
138
|
- spec/client/user_client_spec.rb
|
135
139
|
- spec/configuration_spec.rb
|
140
|
+
- spec/representation/attack_detection_representation_spec.rb
|
136
141
|
- spec/representation/client_representation_spec.rb
|
137
142
|
- spec/representation/group_representation_spec.rb
|
138
143
|
- spec/representation/identity_provider_mapper_representation_spec.rb
|
@@ -140,6 +145,7 @@ files:
|
|
140
145
|
- spec/representation/impersonation_representation_spec.rb
|
141
146
|
- spec/representation/protocol_mapper_representation_spec.rb
|
142
147
|
- spec/representation/role_representation_spec.rb
|
148
|
+
- spec/representation/session_representation_spec.rb
|
143
149
|
- spec/representation/user_representation_spec.rb
|
144
150
|
- spec/resource/group_resource_spec.rb
|
145
151
|
- spec/resource/user_resource_spec.rb
|
@@ -148,7 +154,7 @@ homepage: https://github.com/looorent/keycloak-admin-ruby
|
|
148
154
|
licenses:
|
149
155
|
- MIT
|
150
156
|
metadata: {}
|
151
|
-
post_install_message:
|
157
|
+
post_install_message:
|
152
158
|
rdoc_options: []
|
153
159
|
require_paths:
|
154
160
|
- lib
|
@@ -163,8 +169,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
169
|
- !ruby/object:Gem::Version
|
164
170
|
version: '0'
|
165
171
|
requirements: []
|
166
|
-
rubygems_version: 3.
|
167
|
-
signing_key:
|
172
|
+
rubygems_version: 3.4.10
|
173
|
+
signing_key:
|
168
174
|
specification_version: 4
|
169
175
|
summary: Keycloak Admin REST API client written in Ruby
|
170
176
|
test_files: []
|