keycloak-admin 2.0.1 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +40 -4
- data/keycloak-admin.gemspec +14 -6
- data/lib/keycloak-admin/client/client.rb +22 -10
- data/lib/keycloak-admin/client/client_authz_permission_client.rb +1 -1
- data/lib/keycloak-admin/client/client_authz_policy_client.rb +1 -1
- data/lib/keycloak-admin/client/client_authz_resource_client.rb +1 -1
- data/lib/keycloak-admin/client/client_authz_scope_client.rb +1 -1
- data/lib/keycloak-admin/client/group_client.rb +2 -5
- data/lib/keycloak-admin/client/organization_client.rb +7 -7
- data/lib/keycloak-admin/client/user_client.rb +8 -4
- data/lib/keycloak-admin/error.rb +62 -0
- data/lib/keycloak-admin/version.rb +1 -1
- data/lib/keycloak-admin.rb +1 -0
- metadata +21 -56
- data/.github/workflows/Dockerfile +0 -24
- data/.github/workflows/ci.yml +0 -94
- data/.github/workflows/release.yml +0 -112
- data/.gitignore +0 -10
- data/.rspec +0 -2
- data/Dockerfile +0 -13
- data/Gemfile +0 -3
- data/Gemfile.lock +0 -54
- data/Rakefile +0 -6
- data/bin/console +0 -9
- data/spec/client/attack_detection_client_spec.rb +0 -102
- data/spec/client/client_authz_permission_client_spec.rb +0 -170
- data/spec/client/client_authz_policy_client_spec.rb +0 -170
- data/spec/client/client_authz_resource_client_spec.rb +0 -150
- data/spec/client/client_authz_scope_client_spec.rb +0 -134
- data/spec/client/client_client_spec.rb +0 -133
- data/spec/client/client_role_mappings_client_spec.rb +0 -83
- data/spec/client/client_scope_client_spec.rb +0 -220
- data/spec/client/client_scope_protocol_mapper_client_spec.rb +0 -230
- data/spec/client/client_spec.rb +0 -101
- data/spec/client/configurable_token_client_spec.rb +0 -34
- data/spec/client/group_client_spec.rb +0 -328
- data/spec/client/identity_provider_client_spec.rb +0 -92
- data/spec/client/organization_client_spec.rb +0 -595
- data/spec/client/realm_client_spec.rb +0 -155
- data/spec/client/resource_spec.rb +0 -223
- data/spec/client/response_spec.rb +0 -68
- data/spec/client/role_client_spec.rb +0 -79
- data/spec/client/role_mapper_client_spec.rb +0 -113
- data/spec/client/token_client_spec.rb +0 -68
- data/spec/client/user_client_spec.rb +0 -418
- data/spec/configuration_spec.rb +0 -150
- data/spec/gemspec_spec.rb +0 -25
- data/spec/integration/client_authorization_spec.rb +0 -93
- data/spec/representation/attack_detection_representation_spec.rb +0 -16
- data/spec/representation/client_authz_permission_representation_spec.rb +0 -52
- data/spec/representation/client_authz_policy_representation_spec.rb +0 -47
- data/spec/representation/client_authz_resource_representation_spec.rb +0 -33
- data/spec/representation/client_authz_scope_representation_spec.rb +0 -19
- data/spec/representation/client_representation_spec.rb +0 -119
- data/spec/representation/client_scope_representation_spec.rb +0 -125
- data/spec/representation/credential_representation_spec.rb +0 -68
- data/spec/representation/group_representation_spec.rb +0 -22
- data/spec/representation/identity_provider_mapper_representation_spec.rb +0 -24
- data/spec/representation/identity_provider_representation_spec.rb +0 -113
- data/spec/representation/impersonation_representation_spec.rb +0 -163
- data/spec/representation/organization_representation_spec.rb +0 -64
- data/spec/representation/protocol_mapper_representation_spec.rb +0 -57
- data/spec/representation/role_representation_spec.rb +0 -37
- data/spec/representation/session_representation_spec.rb +0 -16
- data/spec/representation/user_representation_spec.rb +0 -15
- data/spec/resource/group_resource_spec.rb +0 -14
- data/spec/resource/user_resource_spec.rb +0 -14
- data/spec/spec_helper.rb +0 -36
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
RSpec.describe KeycloakAdmin::RealmClient do
|
|
2
|
-
describe "#realm_url" do
|
|
3
|
-
|
|
4
|
-
let(:realm_name) { nil }
|
|
5
|
-
|
|
6
|
-
before(:each) do
|
|
7
|
-
@built_url = KeycloakAdmin.realm(realm_name).realm_url
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
context "when realm_name is defined" do
|
|
11
|
-
let(:realm_name) { "master2" }
|
|
12
|
-
it "return a proper url with realm_name" do
|
|
13
|
-
expect(@built_url).to eq "http://auth.service.io/auth/realms/master2"
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context "when realm_name is not defined" do
|
|
18
|
-
let(:realm_name) { nil }
|
|
19
|
-
it "return a proper url without realm_name" do
|
|
20
|
-
expect(@built_url).to eq "http://auth.service.io/auth/realms"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
describe "#admin_realm_url" do
|
|
26
|
-
|
|
27
|
-
let(:realm_name) { nil }
|
|
28
|
-
|
|
29
|
-
before(:each) do
|
|
30
|
-
@built_url = KeycloakAdmin.realm(realm_name).realm_admin_url
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
context "when realm_name is defined" do
|
|
34
|
-
let(:realm_name) { "master2" }
|
|
35
|
-
it "return a proper url with realm_name" do
|
|
36
|
-
expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/master2"
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
context "when realm_name is not defined" do
|
|
41
|
-
let(:realm_name) { nil }
|
|
42
|
-
it "return a proper url without realm_name" do
|
|
43
|
-
expect(@built_url).to eq "http://auth.service.io/auth/admin/realms"
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
describe "#list" do
|
|
49
|
-
before(:each) do
|
|
50
|
-
@realm_client = KeycloakAdmin.realm('master')
|
|
51
|
-
|
|
52
|
-
stub_token_client
|
|
53
|
-
allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get).and_return '[{"id":"test_realm","realm":"test_realm"}]'
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "lists realms" do
|
|
57
|
-
realms = @realm_client.list
|
|
58
|
-
expect(realms.length).to eq 1
|
|
59
|
-
expect(realms[0].realm).to eq "test_realm"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "passes rest client options" do
|
|
63
|
-
faraday_options = {timeout: 10}
|
|
64
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
65
|
-
|
|
66
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with(
|
|
67
|
-
"http://auth.service.io/auth/admin/realms", faraday_options, anything).and_call_original
|
|
68
|
-
|
|
69
|
-
realms = @realm_client.list
|
|
70
|
-
expect(realms.length).to eq 1
|
|
71
|
-
expect(realms[0].realm).to eq "test_realm"
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
describe "#delete" do
|
|
76
|
-
let(:realm_name) { "valid-realm" }
|
|
77
|
-
|
|
78
|
-
before(:each) do
|
|
79
|
-
@realm_client = KeycloakAdmin.realm(realm_name)
|
|
80
|
-
|
|
81
|
-
stub_token_client
|
|
82
|
-
allow_any_instance_of(KeycloakAdmin::Resource).to receive(:delete)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it "delete realm" do
|
|
86
|
-
expect(@realm_client.delete).to be_truthy
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "passes rest client options" do
|
|
90
|
-
faraday_options = {timeout: 10}
|
|
91
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
92
|
-
|
|
93
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with(
|
|
94
|
-
"http://auth.service.io/auth/admin/realms/valid-realm", faraday_options, anything).and_call_original
|
|
95
|
-
|
|
96
|
-
expect(@realm_client.delete).to be_truthy
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
describe "#save" do
|
|
101
|
-
let(:realm_name) { "valid-realm" }
|
|
102
|
-
let(:realm) { KeycloakAdmin::RealmRepresentation.from_hash(
|
|
103
|
-
"id" => realm_name,
|
|
104
|
-
"realm" => realm_name
|
|
105
|
-
)}
|
|
106
|
-
|
|
107
|
-
before(:each) do
|
|
108
|
-
@realm_client = KeycloakAdmin.realm(nil)
|
|
109
|
-
|
|
110
|
-
stub_token_client
|
|
111
|
-
|
|
112
|
-
expect_any_instance_of(KeycloakAdmin::Resource).to receive(:post).with(realm.to_json, anything)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
it "saves a realm" do
|
|
116
|
-
@realm_client.save(realm)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it "passes rest client options" do
|
|
120
|
-
faraday_options = {timeout: 10}
|
|
121
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
122
|
-
|
|
123
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with(
|
|
124
|
-
"http://auth.service.io/auth/admin/realms", faraday_options, anything).and_call_original
|
|
125
|
-
|
|
126
|
-
@realm_client.save(realm)
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
describe "#update" do
|
|
131
|
-
let(:realm_name) { "valid-realm" }
|
|
132
|
-
let(:realm_json) { { smtpServer: { host: 'test_host' } } }
|
|
133
|
-
|
|
134
|
-
before(:each) do
|
|
135
|
-
@realm_client = KeycloakAdmin.realm(realm_name)
|
|
136
|
-
|
|
137
|
-
stub_token_client
|
|
138
|
-
expect_any_instance_of(KeycloakAdmin::Resource).to receive(:put).with(realm_json.to_json, anything)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
it "updates a realm" do
|
|
142
|
-
@realm_client.update(realm_json)
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
it "passes rest client options" do
|
|
146
|
-
faraday_options = {timeout: 10}
|
|
147
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
148
|
-
|
|
149
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with(
|
|
150
|
-
"http://auth.service.io/auth/admin/realms/valid-realm", faraday_options, anything).and_call_original
|
|
151
|
-
|
|
152
|
-
@realm_client.update(realm_json)
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
RSpec.describe KeycloakAdmin::Resource do
|
|
2
|
-
# A real, mutable stand-in for the Faraday::Request builder yielded by
|
|
3
|
-
# connection.get/post/put/delete { |req| ... }.
|
|
4
|
-
FakeRequest = Struct.new(:params, :headers) do
|
|
5
|
-
attr_accessor :body
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
let(:fake_request) { FakeRequest.new({}, {}) }
|
|
9
|
-
let(:fake_response) { double(status: 200, body: "ok", headers: {}, reason_phrase: "OK") }
|
|
10
|
-
|
|
11
|
-
def stub_connection(resource, verb)
|
|
12
|
-
connection = double
|
|
13
|
-
allow(connection).to receive(verb) do |&block|
|
|
14
|
-
block.call(fake_request) if block
|
|
15
|
-
fake_response
|
|
16
|
-
end
|
|
17
|
-
allow(resource).to receive(:connection).and_return(connection)
|
|
18
|
-
connection
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe "#connection (the real Faraday connection, not stubbed)" do
|
|
22
|
-
def middleware_classes(resource)
|
|
23
|
-
resource.send(:connection).builder.handlers
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "does not register the logger middleware when no logger is configured" do
|
|
27
|
-
resource = KeycloakAdmin::Resource.new("http://example.com")
|
|
28
|
-
expect(middleware_classes(resource)).to_not include(Faraday::Response::Logger)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "registers the logger middleware when a logger is configured" do
|
|
32
|
-
resource = KeycloakAdmin::Resource.new("http://example.com", {}, Logger.new(IO::NULL))
|
|
33
|
-
expect(middleware_classes(resource)).to include(Faraday::Response::Logger)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "orders :raise_error before :logger, so a response is logged even when it raises" do
|
|
37
|
-
resource = KeycloakAdmin::Resource.new("http://example.com", {}, Logger.new(IO::NULL))
|
|
38
|
-
handlers = middleware_classes(resource)
|
|
39
|
-
expect(handlers.index(Faraday::Response::RaiseError)).to be < handlers.index(Faraday::Response::Logger)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "logs method/url/status but never headers, since Faraday logs headers by default and one of them is the bearer token" do
|
|
43
|
-
log_output = StringIO.new
|
|
44
|
-
logger = Logger.new(log_output)
|
|
45
|
-
stubs = Faraday::Adapter::Test::Stubs.new
|
|
46
|
-
stubs.get(//) { [200, {}, "ok"] }
|
|
47
|
-
|
|
48
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/x", {}, logger)
|
|
49
|
-
allow(resource).to receive(:connection) do
|
|
50
|
-
Faraday.new(url: "http://example.com/x") do |f|
|
|
51
|
-
f.response :raise_error
|
|
52
|
-
f.response :logger, logger, headers: false
|
|
53
|
-
f.adapter :test, stubs
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
resource.get(Authorization: "Bearer super-secret-token")
|
|
58
|
-
|
|
59
|
-
expect(log_output.string).to include("request: GET")
|
|
60
|
-
expect(log_output.string).to include("response: Status 200")
|
|
61
|
-
expect(log_output.string).to_not include("super-secret-token")
|
|
62
|
-
expect(log_output.string).to_not include("Authorization")
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
describe "#get" do
|
|
67
|
-
it "humanizes symbol header keys into HTTP header names" do
|
|
68
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
69
|
-
stub_connection(resource, :get)
|
|
70
|
-
|
|
71
|
-
resource.get(Authorization: "Bearer token", content_type: :json, accept: :json)
|
|
72
|
-
|
|
73
|
-
expect(fake_request.headers).to eq(
|
|
74
|
-
"Authorization" => "Bearer token",
|
|
75
|
-
"Content-Type" => "application/json",
|
|
76
|
-
"Accept" => "application/json"
|
|
77
|
-
)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it "extracts :params into the query string instead of sending it as a header" do
|
|
81
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
82
|
-
stub_connection(resource, :get)
|
|
83
|
-
|
|
84
|
-
resource.get(Authorization: "Bearer token", params: { search: "jean" })
|
|
85
|
-
|
|
86
|
-
expect(fake_request.params).to eq(search: "jean")
|
|
87
|
-
expect(fake_request.headers).to eq("Authorization" => "Bearer token")
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it "passes a string content_type through unchanged" do
|
|
91
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
92
|
-
stub_connection(resource, :get)
|
|
93
|
-
|
|
94
|
-
resource.get(content_type: "application/x-www-form-urlencoded")
|
|
95
|
-
|
|
96
|
-
expect(fake_request.headers["Content-Type"]).to eq "application/x-www-form-urlencoded"
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
it "does not set a body" do
|
|
100
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
101
|
-
stub_connection(resource, :get)
|
|
102
|
-
|
|
103
|
-
resource.get({})
|
|
104
|
-
|
|
105
|
-
expect(fake_request.body).to be_nil
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
it "wraps the Faraday response in a KeycloakAdmin::Response" do
|
|
109
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
110
|
-
stub_connection(resource, :get)
|
|
111
|
-
|
|
112
|
-
expect(resource.get({})).to be_a KeycloakAdmin::Response
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
describe "#post" do
|
|
117
|
-
it "sends a pre-serialized string payload as the body unchanged" do
|
|
118
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
119
|
-
stub_connection(resource, :post)
|
|
120
|
-
|
|
121
|
-
resource.post('{"username":"jean"}', content_type: :json)
|
|
122
|
-
|
|
123
|
-
expect(fake_request.body).to eq '{"username":"jean"}'
|
|
124
|
-
expect(fake_request.headers["Content-Type"]).to eq "application/json"
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it "form-encodes a Hash payload" do
|
|
128
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
129
|
-
stub_connection(resource, :post)
|
|
130
|
-
|
|
131
|
-
resource.post({ email: "a@b.com", firstName: "Jean Yves" }, {})
|
|
132
|
-
|
|
133
|
-
expect(fake_request.body).to eq "email=a%40b.com&firstName=Jean+Yves"
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it "stamps Content-Type: application/x-www-form-urlencoded for a Hash payload when none was set" do
|
|
137
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
138
|
-
stub_connection(resource, :post)
|
|
139
|
-
|
|
140
|
-
resource.post({ id: "42" }, {})
|
|
141
|
-
|
|
142
|
-
expect(fake_request.headers["Content-Type"]).to eq "application/x-www-form-urlencoded"
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
it "does not override an explicit Content-Type for a Hash payload" do
|
|
146
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users")
|
|
147
|
-
stub_connection(resource, :post)
|
|
148
|
-
|
|
149
|
-
resource.post({ id: "42" }, content_type: "application/vnd.custom+form")
|
|
150
|
-
|
|
151
|
-
expect(fake_request.headers["Content-Type"]).to eq "application/vnd.custom+form"
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
describe "#delete" do
|
|
156
|
-
it "sends no body and only the given headers" do
|
|
157
|
-
resource = KeycloakAdmin::Resource.new("http://example.com/users/1")
|
|
158
|
-
stub_connection(resource, :delete)
|
|
159
|
-
|
|
160
|
-
resource.delete(Authorization: "Bearer token")
|
|
161
|
-
|
|
162
|
-
expect(fake_request.body).to be_nil
|
|
163
|
-
expect(fake_request.headers).to eq("Authorization" => "Bearer token")
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
describe ".execute (RestClient::Request.execute equivalent)" do
|
|
168
|
-
it "dispatches an arbitrary method with a payload, including DELETE with a body" do
|
|
169
|
-
resource_instance = KeycloakAdmin::Resource.new("http://example.com/mappings")
|
|
170
|
-
allow(KeycloakAdmin::Resource).to receive(:new).and_return(resource_instance)
|
|
171
|
-
stub_connection(resource_instance, :delete)
|
|
172
|
-
|
|
173
|
-
KeycloakAdmin::Resource.execute(
|
|
174
|
-
method: :delete,
|
|
175
|
-
url: "http://example.com/mappings",
|
|
176
|
-
payload: '[{"id":"1"}]',
|
|
177
|
-
headers: { content_type: :json }
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
expect(fake_request.body).to eq '[{"id":"1"}]'
|
|
181
|
-
expect(fake_request.headers["Content-Type"]).to eq "application/json"
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
it "forwards non-method/url/payload/headers keys as connection options" do
|
|
185
|
-
resource_instance = KeycloakAdmin::Resource.new("http://example.com/x")
|
|
186
|
-
expected_options = { timeout: 5 }
|
|
187
|
-
stub_connection(resource_instance, :get)
|
|
188
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with("http://example.com/x", expected_options, nil).and_return(resource_instance)
|
|
189
|
-
|
|
190
|
-
KeycloakAdmin::Resource.execute(method: :get, url: "http://example.com/x", headers: {}, timeout: 5)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
it "extracts :logger and passes it positionally instead of leaving it in connection options" do
|
|
194
|
-
resource_instance = KeycloakAdmin::Resource.new("http://example.com/x")
|
|
195
|
-
logger = Logger.new(IO::NULL)
|
|
196
|
-
stub_connection(resource_instance, :get)
|
|
197
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with("http://example.com/x", {}, logger).and_return(resource_instance)
|
|
198
|
-
|
|
199
|
-
KeycloakAdmin::Resource.execute(method: :get, url: "http://example.com/x", headers: {}, logger: logger)
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
describe ".put (RestClient.put shorthand)" do
|
|
204
|
-
it "posts without requiring any connection options" do
|
|
205
|
-
resource_instance = KeycloakAdmin::Resource.new("http://example.com/x")
|
|
206
|
-
allow(KeycloakAdmin::Resource).to receive(:new).and_return(resource_instance)
|
|
207
|
-
stub_connection(resource_instance, :put)
|
|
208
|
-
|
|
209
|
-
KeycloakAdmin::Resource.put("http://example.com/x", "body", {})
|
|
210
|
-
|
|
211
|
-
expect(fake_request.body).to eq "body"
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
it "forwards the given logger to the underlying Resource" do
|
|
215
|
-
resource_instance = KeycloakAdmin::Resource.new("http://example.com/x")
|
|
216
|
-
logger = Logger.new(IO::NULL)
|
|
217
|
-
stub_connection(resource_instance, :put)
|
|
218
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with("http://example.com/x", {}, logger).and_return(resource_instance)
|
|
219
|
-
|
|
220
|
-
KeycloakAdmin::Resource.put("http://example.com/x", "body", {}, logger)
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
RSpec.describe KeycloakAdmin::Response do
|
|
2
|
-
def fake_faraday_response(status: 200, body: "", headers: {}, reason_phrase: "OK")
|
|
3
|
-
double(status: status, body: body, headers: headers, reason_phrase: reason_phrase)
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
describe "body-as-string behavior (RestClient::Response was a String subclass)" do
|
|
7
|
-
it "behaves like the raw body string" do
|
|
8
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(body: '{"a":1}'))
|
|
9
|
-
expect(response).to eq '{"a":1}'
|
|
10
|
-
expect(JSON.parse(response)).to eq({ "a" => 1 })
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "supports String methods relied on by callers, e.g. #to_i" do
|
|
14
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(body: "42"))
|
|
15
|
-
expect(response.to_i).to eq 42
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "exposes #body returning the same content" do
|
|
19
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(body: "hello"))
|
|
20
|
-
expect(response.body).to eq "hello"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe "#status / #code / #reason_phrase" do
|
|
25
|
-
it "exposes the HTTP status" do
|
|
26
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(status: 201))
|
|
27
|
-
expect(response.status).to eq 201
|
|
28
|
-
expect(response.code).to eq 201
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "exposes the reason phrase" do
|
|
32
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(reason_phrase: "Created"))
|
|
33
|
-
expect(response.reason_phrase).to eq "Created"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
describe "#headers" do
|
|
38
|
-
it "symbolizes header names the way RestClient did (downcased, dash to underscore)" do
|
|
39
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(headers: { "Location" => "/users/42", "Content-Type" => "application/json" }))
|
|
40
|
-
expect(response.headers[:location]).to eq "/users/42"
|
|
41
|
-
expect(response.headers[:content_type]).to eq "application/json"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "splits a single Set-Cookie header into a one-element array" do
|
|
45
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(headers: { "Set-Cookie" => "a=1; Path=/" }))
|
|
46
|
-
expect(response.headers[:set_cookie]).to eq ["a=1; Path=/"]
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it "splits multiple Set-Cookie headers joined by Faraday's net_http adapter" do
|
|
50
|
-
joined = "KEYCLOAK_SESSION=abc; Path=/, KEYCLOAK_IDENTITY=def; Path=/, AUTH_SESSION_ID=ghi; Path=/"
|
|
51
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(headers: { "Set-Cookie" => joined }))
|
|
52
|
-
expect(response.headers[:set_cookie]).to eq [
|
|
53
|
-
"KEYCLOAK_SESSION=abc; Path=/",
|
|
54
|
-
"KEYCLOAK_IDENTITY=def; Path=/",
|
|
55
|
-
"AUTH_SESSION_ID=ghi; Path=/"
|
|
56
|
-
]
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it "does not split on a comma embedded in a cookie's own Expires attribute" do
|
|
60
|
-
joined = "a=1; Expires=Wed, 09 Jun 2027 10:18:14 GMT; Path=/, b=2; Path=/"
|
|
61
|
-
response = KeycloakAdmin::Response.new(fake_faraday_response(headers: { "Set-Cookie" => joined }))
|
|
62
|
-
expect(response.headers[:set_cookie]).to eq [
|
|
63
|
-
"a=1; Expires=Wed, 09 Jun 2027 10:18:14 GMT; Path=/",
|
|
64
|
-
"b=2; Path=/"
|
|
65
|
-
]
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
RSpec.describe KeycloakAdmin::RoleClient do
|
|
2
|
-
describe "#roles_url" do
|
|
3
|
-
let(:realm_name) { "valid-realm" }
|
|
4
|
-
|
|
5
|
-
it "return a proper url without role id" do
|
|
6
|
-
@built_url = KeycloakAdmin.realm(realm_name).roles.roles_url
|
|
7
|
-
expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/roles"
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
describe "#role_id_url" do
|
|
12
|
-
let(:realm_name) { "valid-realm" }
|
|
13
|
-
let(:role_id) { "95985b21-d884-4bbd-b852-cb8cd365afc2" }
|
|
14
|
-
|
|
15
|
-
it "return a proper url with the role id" do
|
|
16
|
-
@built_url = KeycloakAdmin.realm(realm_name).roles.role_id_url(role_id)
|
|
17
|
-
expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/roles-by-id/95985b21-d884-4bbd-b852-cb8cd365afc2"
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe "#list" do
|
|
22
|
-
let(:realm_name) { "valid-realm" }
|
|
23
|
-
|
|
24
|
-
before(:each) do
|
|
25
|
-
@role_client = KeycloakAdmin.realm(realm_name).roles
|
|
26
|
-
|
|
27
|
-
stub_token_client
|
|
28
|
-
allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get).and_return '[{"id":"test_role_id","name":"test_role_name"}]'
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "lists roles" do
|
|
32
|
-
roles = @role_client.list
|
|
33
|
-
expect(roles.length).to eq 1
|
|
34
|
-
expect(roles[0].name).to eq "test_role_name"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it "passes rest client options" do
|
|
38
|
-
faraday_options = {timeout: 10}
|
|
39
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
40
|
-
|
|
41
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with(
|
|
42
|
-
"http://auth.service.io/auth/admin/realms/valid-realm/roles", faraday_options, anything).and_call_original
|
|
43
|
-
|
|
44
|
-
roles = @role_client.list
|
|
45
|
-
expect(roles.length).to eq 1
|
|
46
|
-
expect(roles[0].name).to eq "test_role_name"
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
describe "#save" do
|
|
51
|
-
let(:realm_name) { "valid-realm" }
|
|
52
|
-
let(:role) { KeycloakAdmin::RoleRepresentation.from_hash(
|
|
53
|
-
"name" => "test_role_name",
|
|
54
|
-
"composite" => false,
|
|
55
|
-
"clientRole" => false
|
|
56
|
-
)}
|
|
57
|
-
|
|
58
|
-
before(:each) do
|
|
59
|
-
@role_client = KeycloakAdmin.realm(realm_name).roles
|
|
60
|
-
|
|
61
|
-
stub_token_client
|
|
62
|
-
expect_any_instance_of(KeycloakAdmin::Resource).to receive(:post).with(role.to_json, anything)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it "saves a role" do
|
|
66
|
-
@role_client.save(role)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it "passes rest client options" do
|
|
70
|
-
faraday_options = {timeout: 10}
|
|
71
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
72
|
-
|
|
73
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with(
|
|
74
|
-
"http://auth.service.io/auth/admin/realms/valid-realm/roles", faraday_options, anything).and_call_original
|
|
75
|
-
|
|
76
|
-
@role_client.save(role)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
RSpec.describe KeycloakAdmin::RoleMapperClient do
|
|
2
|
-
describe "#available_url" do
|
|
3
|
-
let(:realm_name) { "valid-realm" }
|
|
4
|
-
let(:user_id) { "test_user" }
|
|
5
|
-
|
|
6
|
-
before(:each) do
|
|
7
|
-
@built_url = KeycloakAdmin.realm(realm_name).user(user_id).role_mapper.realm_level_url
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "return a proper url" do
|
|
11
|
-
expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/users/test_user/role-mappings/realm"
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
describe "#list" do
|
|
16
|
-
let(:realm_name) { "valid-realm" }
|
|
17
|
-
let(:user_id) { "test_user" }
|
|
18
|
-
|
|
19
|
-
before(:each) do
|
|
20
|
-
@role_mapper_client = KeycloakAdmin.realm(realm_name).user(user_id).role_mapper
|
|
21
|
-
|
|
22
|
-
stub_token_client
|
|
23
|
-
allow_any_instance_of(KeycloakAdmin::Resource).to receive(:get)
|
|
24
|
-
.and_return '[{"id":"test_role_id","name":"test_role_name","composite": false}]'
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "list user realm-level role mappings" do
|
|
28
|
-
roles = @role_mapper_client.list
|
|
29
|
-
expect(roles.length).to eq 1
|
|
30
|
-
expect(roles[0].id).to eq "test_role_id"
|
|
31
|
-
expect(roles[0].name).to eq "test_role_name"
|
|
32
|
-
expect(roles[0].composite).to be false
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
describe "#save_realm_level" do
|
|
37
|
-
let(:realm_name) { "valid-realm" }
|
|
38
|
-
let(:user_id) { "test_user" }
|
|
39
|
-
let(:role_list) { [
|
|
40
|
-
KeycloakAdmin::RoleRepresentation.from_hash(
|
|
41
|
-
"name" => "test_role_name",
|
|
42
|
-
"composite" => false,
|
|
43
|
-
"clientRole" => false
|
|
44
|
-
)
|
|
45
|
-
] }
|
|
46
|
-
|
|
47
|
-
before(:each) do
|
|
48
|
-
@role_mapper_client = KeycloakAdmin.realm(realm_name).user(user_id).role_mapper
|
|
49
|
-
|
|
50
|
-
stub_token_client
|
|
51
|
-
expect_any_instance_of(KeycloakAdmin::Resource).to receive(:post).with(role_list.to_json, anything)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "saves realm-elevel role mappings" do
|
|
55
|
-
@role_mapper_client.save_realm_level(role_list)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it "passes rest client options" do
|
|
59
|
-
faraday_options = {timeout: 10}
|
|
60
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
61
|
-
|
|
62
|
-
expect(KeycloakAdmin::Resource).to receive(:new).with(
|
|
63
|
-
"http://auth.service.io/auth/admin/realms/valid-realm/users/test_user/role-mappings/realm", faraday_options, anything).and_call_original
|
|
64
|
-
|
|
65
|
-
@role_mapper_client.save_realm_level(role_list)
|
|
66
|
-
end
|
|
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(KeycloakAdmin::Resource).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
|
-
faraday_options = {timeout: 10}
|
|
99
|
-
allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:faraday_options).and_return faraday_options
|
|
100
|
-
|
|
101
|
-
expect(KeycloakAdmin::Resource).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
|
|
113
|
-
end
|