keycloak-admin 1.1.5 → 1.1.7
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 -1
- data/CHANGELOG.md +22 -0
- data/Gemfile.lock +10 -6
- data/README.md +128 -1
- data/keycloak-admin.gemspec +1 -1
- data/lib/keycloak-admin/client/client_scope_client.rb +65 -0
- data/lib/keycloak-admin/client/client_scope_protocol_mapper_client.rb +62 -0
- data/lib/keycloak-admin/client/organization_client.rb +245 -0
- data/lib/keycloak-admin/client/realm_client.rb +12 -0
- data/lib/keycloak-admin/representation/client_scope_representation.rb +21 -0
- data/lib/keycloak-admin/representation/identity_provider_representation.rb +4 -0
- data/lib/keycloak-admin/representation/member_representation.rb +11 -0
- data/lib/keycloak-admin/representation/organization_domain_representation.rb +18 -0
- data/lib/keycloak-admin/representation/organization_representation.rb +30 -0
- data/lib/keycloak-admin/version.rb +1 -1
- data/lib/keycloak-admin.rb +7 -0
- data/spec/client/client_scope_client_spec.rb +220 -0
- data/spec/client/client_scope_protocol_mapper_client_spec.rb +230 -0
- data/spec/client/organization_client_spec.rb +595 -0
- data/spec/representation/client_scope_representation_spec.rb +125 -0
- data/spec/representation/organization_representation_spec.rb +64 -0
- metadata +20 -8
|
@@ -11,6 +11,7 @@ module KeycloakAdmin
|
|
|
11
11
|
:add_read_token_role_on_create,
|
|
12
12
|
:authenticate_by_default,
|
|
13
13
|
:link_only,
|
|
14
|
+
:organization_id,
|
|
14
15
|
:first_broker_login_flow_alias,
|
|
15
16
|
:config
|
|
16
17
|
|
|
@@ -30,6 +31,7 @@ module KeycloakAdmin
|
|
|
30
31
|
hash["addReadTokenRoleOnCreate"],
|
|
31
32
|
hash["authenticateByDefault"],
|
|
32
33
|
hash["linkOnly"],
|
|
34
|
+
hash["organizationId"],
|
|
33
35
|
hash["firstBrokerLoginFlowAlias"],
|
|
34
36
|
hash["config"]
|
|
35
37
|
)
|
|
@@ -47,6 +49,7 @@ module KeycloakAdmin
|
|
|
47
49
|
add_read_token_role_on_create,
|
|
48
50
|
authenticate_by_default,
|
|
49
51
|
link_only,
|
|
52
|
+
organization_id,
|
|
50
53
|
first_broker_login_flow_alias,
|
|
51
54
|
config)
|
|
52
55
|
@alias = alias_name
|
|
@@ -60,6 +63,7 @@ module KeycloakAdmin
|
|
|
60
63
|
@add_read_token_role_on_create = add_read_token_role_on_create
|
|
61
64
|
@authenticate_by_default = authenticate_by_default
|
|
62
65
|
@link_only = link_only
|
|
66
|
+
@organization_id = organization_id
|
|
63
67
|
@first_broker_login_flow_alias = first_broker_login_flow_alias
|
|
64
68
|
@config = config || {}
|
|
65
69
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module KeycloakAdmin
|
|
2
|
+
class OrganizationDomainRepresentation < Representation
|
|
3
|
+
attr_accessor :name, :verified
|
|
4
|
+
|
|
5
|
+
def initialize(name, verified)
|
|
6
|
+
@name = name
|
|
7
|
+
@verified = verified
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.from_hash(hash)
|
|
11
|
+
new(hash["name"], hash["verified"])
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module KeycloakAdmin
|
|
2
|
+
class OrganizationRepresentation < Representation
|
|
3
|
+
attr_accessor :id,
|
|
4
|
+
:name,
|
|
5
|
+
:alias,
|
|
6
|
+
:enabled,
|
|
7
|
+
:description,
|
|
8
|
+
:redirect_url,
|
|
9
|
+
:attributes,
|
|
10
|
+
:domains,
|
|
11
|
+
:members,
|
|
12
|
+
:attributes,
|
|
13
|
+
:identity_providers
|
|
14
|
+
|
|
15
|
+
def self.from_hash(hash)
|
|
16
|
+
role = new
|
|
17
|
+
role.id = hash["id"]
|
|
18
|
+
role.name = hash["name"]
|
|
19
|
+
role.alias = hash["alias"]
|
|
20
|
+
role.enabled = hash["enabled"]
|
|
21
|
+
role.description = hash["description"]
|
|
22
|
+
role.redirect_url = hash["redirectUrl"]
|
|
23
|
+
role.attributes = hash["attributes"] || {}
|
|
24
|
+
role.domains = hash["domains"].nil? ? [] : hash["domains"].map { |domain| KeycloakAdmin::OrganizationDomainRepresentation.from_hash(domain) }
|
|
25
|
+
role.members = hash["members"].nil? ? [] : hash["members"].map { |member| KeycloakAdmin::MemberRepresentation.from_hash(member) }
|
|
26
|
+
role.identity_providers = hash["identityProviders"].nil? ? [] : hash["identityProviders"].map { |provider| KeycloakAdmin::IdentityProviderRepresentation.from_hash(provider) }
|
|
27
|
+
role
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/keycloak-admin.rb
CHANGED
|
@@ -7,6 +7,7 @@ require_relative "keycloak-admin/client/client_role_client"
|
|
|
7
7
|
require_relative "keycloak-admin/client/client_role_mappings_client"
|
|
8
8
|
require_relative "keycloak-admin/client/group_client"
|
|
9
9
|
require_relative "keycloak-admin/client/realm_client"
|
|
10
|
+
require_relative "keycloak-admin/client/organization_client"
|
|
10
11
|
require_relative "keycloak-admin/client/role_client"
|
|
11
12
|
require_relative "keycloak-admin/client/role_mapper_client"
|
|
12
13
|
require_relative "keycloak-admin/client/token_client"
|
|
@@ -15,6 +16,8 @@ require_relative "keycloak-admin/client/identity_provider_client"
|
|
|
15
16
|
require_relative "keycloak-admin/client/configurable_token_client"
|
|
16
17
|
require_relative "keycloak-admin/client/attack_detection_client"
|
|
17
18
|
require_relative "keycloak-admin/client/client_authz_scope_client"
|
|
19
|
+
require_relative "keycloak-admin/client/client_scope_client"
|
|
20
|
+
require_relative "keycloak-admin/client/client_scope_protocol_mapper_client"
|
|
18
21
|
require_relative "keycloak-admin/client/client_authz_resource_client"
|
|
19
22
|
require_relative "keycloak-admin/client/client_authz_policy_client"
|
|
20
23
|
require_relative "keycloak-admin/client/client_authz_permission_client"
|
|
@@ -27,14 +30,18 @@ require_relative "keycloak-admin/representation/token_representation"
|
|
|
27
30
|
require_relative "keycloak-admin/representation/impersonation_redirection_representation"
|
|
28
31
|
require_relative "keycloak-admin/representation/impersonation_representation"
|
|
29
32
|
require_relative "keycloak-admin/representation/credential_representation"
|
|
33
|
+
require_relative "keycloak-admin/representation/organization_domain_representation"
|
|
34
|
+
require_relative "keycloak-admin/representation/organization_representation"
|
|
30
35
|
require_relative "keycloak-admin/representation/realm_representation"
|
|
31
36
|
require_relative "keycloak-admin/representation/role_representation"
|
|
32
37
|
require_relative "keycloak-admin/representation/federated_identity_representation"
|
|
33
38
|
require_relative "keycloak-admin/representation/user_representation"
|
|
39
|
+
require_relative "keycloak-admin/representation/member_representation"
|
|
34
40
|
require_relative "keycloak-admin/representation/identity_provider_mapper_representation"
|
|
35
41
|
require_relative "keycloak-admin/representation/identity_provider_representation"
|
|
36
42
|
require_relative "keycloak-admin/representation/attack_detection_representation"
|
|
37
43
|
require_relative "keycloak-admin/representation/session_representation"
|
|
44
|
+
require_relative "keycloak-admin/representation/client_scope_representation"
|
|
38
45
|
require_relative "keycloak-admin/representation/client_authz_scope_representation"
|
|
39
46
|
require_relative "keycloak-admin/representation/client_authz_resource_representation"
|
|
40
47
|
require_relative "keycloak-admin/representation/client_authz_policy_representation"
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
RSpec.describe KeycloakAdmin::ClientScopeClient do
|
|
2
|
+
let(:realm_name) { "valid-realm" }
|
|
3
|
+
let(:client_scope_id) { "valid-scope-id" }
|
|
4
|
+
|
|
5
|
+
let(:scope_json) do
|
|
6
|
+
<<~JSON
|
|
7
|
+
{"id":"valid-scope-id","name":"my-scope","description":"A test scope","protocol":"openid-connect","attributes":{"display.on.consent.screen":"true","include.in.token.scope":"true"}}
|
|
8
|
+
JSON
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:scope_with_mappers_json) do
|
|
12
|
+
<<~JSON
|
|
13
|
+
{"id":"valid-scope-id","name":"my-scope","description":"A test scope","protocol":"openid-connect","attributes":{},"protocolMappers":[{"id":"mapper-id","name":"my-claim","protocol":"openid-connect","protocolMapper":"oidc-hardcoded-claim-mapper","config":{"claim.name":"my_claim","claim.value":"bar","access.token.claim":"true"}}]}
|
|
14
|
+
JSON
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#initialize" do
|
|
18
|
+
context "when realm_name is defined" do
|
|
19
|
+
it "does not raise any error" do
|
|
20
|
+
expect { KeycloakAdmin.realm(realm_name).client_scopes }.to_not raise_error
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "when realm_name is not defined" do
|
|
25
|
+
it "raises an argument error" do
|
|
26
|
+
expect { KeycloakAdmin.realm(nil).client_scopes }.to raise_error(ArgumentError)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe "#list" do
|
|
32
|
+
before(:each) do
|
|
33
|
+
@client = KeycloakAdmin.realm(realm_name).client_scopes
|
|
34
|
+
stub_token_client
|
|
35
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return stub_response
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "with one scope" do
|
|
39
|
+
let(:stub_response) { "[#{scope_json}]" }
|
|
40
|
+
|
|
41
|
+
it "returns one scope" do
|
|
42
|
+
expect(@client.list.size).to eq 1
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "returns the correct scope attributes" do
|
|
46
|
+
expect(@client.list.first).to have_attributes(
|
|
47
|
+
id: "valid-scope-id",
|
|
48
|
+
name: "my-scope",
|
|
49
|
+
description: "A test scope",
|
|
50
|
+
protocol: "openid-connect"
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "returns attributes map" do
|
|
55
|
+
expect(@client.list.first.attributes).to include(
|
|
56
|
+
"display.on.consent.screen" => "true",
|
|
57
|
+
"include.in.token.scope" => "true"
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "with multiple scopes" do
|
|
63
|
+
let(:second_scope_json) { '{"id":"other-scope-id","name":"other-scope","protocol":"openid-connect"}' }
|
|
64
|
+
let(:stub_response) { "[#{scope_json},#{second_scope_json}]" }
|
|
65
|
+
|
|
66
|
+
it "returns two scopes" do
|
|
67
|
+
expect(@client.list.size).to eq 2
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "includes both scope names" do
|
|
71
|
+
expect(@client.list.map(&:name)).to include("my-scope", "other-scope")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe "#get" do
|
|
77
|
+
before(:each) do
|
|
78
|
+
@client = KeycloakAdmin.realm(realm_name).client_scopes
|
|
79
|
+
stub_token_client
|
|
80
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return stub_response
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "without protocol mappers" do
|
|
84
|
+
let(:stub_response) { scope_json }
|
|
85
|
+
|
|
86
|
+
it "returns the correct id" do
|
|
87
|
+
expect(@client.get(client_scope_id).id).to eq "valid-scope-id"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "returns the correct name" do
|
|
91
|
+
expect(@client.get(client_scope_id).name).to eq "my-scope"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "returns the correct description" do
|
|
95
|
+
expect(@client.get(client_scope_id).description).to eq "A test scope"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "returns the correct protocol" do
|
|
99
|
+
expect(@client.get(client_scope_id).protocol).to eq "openid-connect"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "returns an empty protocolMappers list" do
|
|
103
|
+
expect(@client.get(client_scope_id).protocol_mappers).to eq []
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context "with protocol mappers" do
|
|
108
|
+
let(:stub_response) { scope_with_mappers_json }
|
|
109
|
+
|
|
110
|
+
it "returns protocol mappers" do
|
|
111
|
+
expect(@client.get(client_scope_id).protocol_mappers.size).to eq 1
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "returns the correct mapper name" do
|
|
115
|
+
expect(@client.get(client_scope_id).protocol_mappers.first.name).to eq "my-claim"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
describe "#create!" do
|
|
121
|
+
before(:each) do
|
|
122
|
+
@client = KeycloakAdmin.realm(realm_name).client_scopes
|
|
123
|
+
stub_token_client
|
|
124
|
+
allow_any_instance_of(RestClient::Resource).to receive(:post).and_return ""
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
let(:scope_representation) do
|
|
128
|
+
scope = KeycloakAdmin::ClientScopeRepresentation.new
|
|
129
|
+
scope.name = "my-scope"
|
|
130
|
+
scope.description = "A test scope"
|
|
131
|
+
scope.protocol = "openid-connect"
|
|
132
|
+
scope.attributes = { "display.on.consent.screen" => "true", "include.in.token.scope" => "true" }
|
|
133
|
+
scope
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "creates successfully" do
|
|
137
|
+
expect(@client.create!(scope_representation)).to be true
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "#save" do
|
|
142
|
+
before(:each) do
|
|
143
|
+
@client = KeycloakAdmin.realm(realm_name).client_scopes
|
|
144
|
+
stub_token_client
|
|
145
|
+
allow_any_instance_of(RestClient::Resource).to receive(:put).and_return ""
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
let(:scope_representation) { KeycloakAdmin::ClientScopeRepresentation.from_hash(JSON.parse(scope_json)) }
|
|
149
|
+
|
|
150
|
+
it "calls put on the scope url" do
|
|
151
|
+
expect_any_instance_of(RestClient::Resource).to receive(:put).with(anything, anything)
|
|
152
|
+
@client.save(scope_representation)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "returns true" do
|
|
156
|
+
expect(@client.save(scope_representation)).to be true
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
describe "#search" do
|
|
161
|
+
let(:second_scope_json) { '{"id":"other-scope-id","name":"other-scope","protocol":"openid-connect"}' }
|
|
162
|
+
|
|
163
|
+
before(:each) do
|
|
164
|
+
@client = KeycloakAdmin.realm(realm_name).client_scopes
|
|
165
|
+
stub_token_client
|
|
166
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return "[#{scope_json},#{second_scope_json}]"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
context "when the name matches one scope" do
|
|
170
|
+
it "returns only the matching scope" do
|
|
171
|
+
expect(@client.search("my-scope").size).to eq 1
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "returns the correct scope" do
|
|
175
|
+
expect(@client.search("my-scope").first).to have_attributes(id: "valid-scope-id", name: "my-scope")
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
context "when the name is a partial match" do
|
|
180
|
+
it "returns all scopes containing the substring" do
|
|
181
|
+
expect(@client.search("scope").size).to eq 2
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context "when no scope matches" do
|
|
186
|
+
it "returns an empty array" do
|
|
187
|
+
expect(@client.search("unknown")).to eq []
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
describe "#delete" do
|
|
193
|
+
before(:each) do
|
|
194
|
+
@client = KeycloakAdmin.realm(realm_name).client_scopes
|
|
195
|
+
stub_token_client
|
|
196
|
+
allow_any_instance_of(RestClient::Resource).to receive(:delete).and_return ""
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "returns true" do
|
|
200
|
+
expect(@client.delete(client_scope_id)).to eq true
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe "#client_scopes_url" do
|
|
205
|
+
let(:client) { KeycloakAdmin.realm(realm_name).client_scopes }
|
|
206
|
+
let(:base_url) { "http://auth.service.io/auth/admin/realms/valid-realm/client-scopes" }
|
|
207
|
+
|
|
208
|
+
context "without a client_scope_id" do
|
|
209
|
+
it "returns the base url" do
|
|
210
|
+
expect(client.client_scopes_url).to eq base_url
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
context "with a client_scope_id" do
|
|
215
|
+
it "returns the url with client_scope_id appended" do
|
|
216
|
+
expect(client.client_scopes_url(client_scope_id)).to eq "#{base_url}/valid-scope-id"
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
RSpec.describe KeycloakAdmin::ClientScopeProtocolMapperClient do
|
|
2
|
+
let(:realm_name) { "valid-realm" }
|
|
3
|
+
let(:client_scope_id) { "valid-scope-id" }
|
|
4
|
+
let(:mapper_id) { "valid-mapper-id" }
|
|
5
|
+
|
|
6
|
+
let(:mapper_json) do
|
|
7
|
+
<<~JSON
|
|
8
|
+
{"id":"valid-mapper-id","name":"my-claim","protocol":"openid-connect","protocolMapper":"oidc-hardcoded-claim-mapper","config":{"claim.name":"my_claim","claim.value":"bar","access.token.claim":"true"}}
|
|
9
|
+
JSON
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:audience_mapper_json) do
|
|
13
|
+
<<~JSON
|
|
14
|
+
{"protocol":"openid-connect","protocolMapper":"oidc-audience-mapper","name":"audience-config-rvw-123","config":{"included.client.audience":"","included.custom.audience":"https://api.example.com","id.token.claim":"false","access.token.claim":"true","lightweight.claim":"false","introspection.token.claim":"true"}}
|
|
15
|
+
JSON
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#initialize" do
|
|
19
|
+
context "when realm_name is defined" do
|
|
20
|
+
it "does not raise any error" do
|
|
21
|
+
expect { KeycloakAdmin.realm(realm_name).client_scope_protocol_mappers(client_scope_id) }.to_not raise_error
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "when realm_name is not defined" do
|
|
26
|
+
it "raises an argument error" do
|
|
27
|
+
expect { KeycloakAdmin.realm(nil).client_scope_protocol_mappers(client_scope_id) }.to raise_error(ArgumentError)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#list" do
|
|
33
|
+
before(:each) do
|
|
34
|
+
@client = KeycloakAdmin.realm(realm_name).client_scope_protocol_mappers(client_scope_id)
|
|
35
|
+
stub_token_client
|
|
36
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return stub_response
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "with a hardcoded claim mapper" do
|
|
40
|
+
let(:stub_response) { "[#{mapper_json}]" }
|
|
41
|
+
|
|
42
|
+
it "returns one mapper" do
|
|
43
|
+
expect(@client.list.size).to eq 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "returns the correct mapper attributes" do
|
|
47
|
+
expect(@client.list.first).to have_attributes(id: "valid-mapper-id", name: "my-claim", protocol: "openid-connect", protocolMapper: "oidc-hardcoded-claim-mapper")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "with an audience mapper" do
|
|
52
|
+
let(:stub_response) { "[#{audience_mapper_json}]" }
|
|
53
|
+
|
|
54
|
+
it "returns one mapper" do
|
|
55
|
+
expect(@client.list.size).to eq 1
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "returns the correct mapper attributes" do
|
|
59
|
+
expect(@client.list.first).to have_attributes(name: "audience-config-rvw-123", protocol: "openid-connect", protocolMapper: "oidc-audience-mapper")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "with multiple mappers" do
|
|
64
|
+
let(:stub_response) { "[#{mapper_json},#{audience_mapper_json}]" }
|
|
65
|
+
|
|
66
|
+
it "returns two mappers" do
|
|
67
|
+
expect(@client.list.size).to eq 2
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "includes both mapper names" do
|
|
71
|
+
expect(@client.list.map(&:name)).to include("my-claim", "audience-config-rvw-123")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe "#get" do
|
|
77
|
+
before(:each) do
|
|
78
|
+
@client = KeycloakAdmin.realm(realm_name).client_scope_protocol_mappers(client_scope_id)
|
|
79
|
+
stub_token_client
|
|
80
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return stub_response
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "with a hardcoded claim mapper" do
|
|
84
|
+
let(:stub_response) { mapper_json }
|
|
85
|
+
|
|
86
|
+
it "returns the correct id" do
|
|
87
|
+
expect(@client.get(mapper_id).id).to eq "valid-mapper-id"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "returns the correct name" do
|
|
91
|
+
expect(@client.get(mapper_id).name).to eq "my-claim"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "returns the correct protocol" do
|
|
95
|
+
expect(@client.get(mapper_id).protocol).to eq "openid-connect"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "returns the correct protocolMapper" do
|
|
99
|
+
expect(@client.get(mapper_id).protocolMapper).to eq "oidc-hardcoded-claim-mapper"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "with an audience mapper" do
|
|
104
|
+
let(:stub_response) { audience_mapper_json }
|
|
105
|
+
|
|
106
|
+
it "returns the correct name" do
|
|
107
|
+
expect(@client.get(mapper_id).name).to eq "audience-config-rvw-123"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "returns the correct protocol" do
|
|
111
|
+
expect(@client.get(mapper_id).protocol).to eq "openid-connect"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "returns the correct protocolMapper" do
|
|
115
|
+
expect(@client.get(mapper_id).protocolMapper).to eq "oidc-audience-mapper"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "returns the correct config" do
|
|
119
|
+
expect(@client.get(mapper_id).config).to include(
|
|
120
|
+
"included.custom.audience" => "https://api.example.com",
|
|
121
|
+
"access.token.claim" => "true",
|
|
122
|
+
"introspection.token.claim" => "true",
|
|
123
|
+
"id.token.claim" => "false"
|
|
124
|
+
)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe "#create!" do
|
|
130
|
+
before(:each) do
|
|
131
|
+
@client = KeycloakAdmin.realm(realm_name).client_scope_protocol_mappers(client_scope_id)
|
|
132
|
+
stub_token_client
|
|
133
|
+
allow_any_instance_of(RestClient::Resource).to receive(:post).and_return stub_response
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context "with a hardcoded claim mapper" do
|
|
137
|
+
let(:stub_response) { mapper_json }
|
|
138
|
+
let(:mapper_representation) do
|
|
139
|
+
mapper = KeycloakAdmin::ProtocolMapperRepresentation.new
|
|
140
|
+
mapper.name = "my-claim"
|
|
141
|
+
mapper.protocol = "openid-connect"
|
|
142
|
+
mapper.protocolMapper = "oidc-hardcoded-claim-mapper"
|
|
143
|
+
mapper.config = { "claim.name" => "my_claim", "claim.value" => "bar", "access.token.claim" => "true" }
|
|
144
|
+
mapper
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "creates successfully" do
|
|
148
|
+
expect(@client.create!(mapper_representation)).to be true
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context "with an audience mapper" do
|
|
153
|
+
let(:stub_response) { audience_mapper_json }
|
|
154
|
+
let(:mapper_representation) do
|
|
155
|
+
mapper = KeycloakAdmin::ProtocolMapperRepresentation.new
|
|
156
|
+
mapper.name = "audience-config-rvw-123"
|
|
157
|
+
mapper.protocol = "openid-connect"
|
|
158
|
+
mapper.protocolMapper = "oidc-audience-mapper"
|
|
159
|
+
mapper.config = {
|
|
160
|
+
"included.client.audience" => "",
|
|
161
|
+
"included.custom.audience" => "https://api.example.com",
|
|
162
|
+
"id.token.claim" => "false",
|
|
163
|
+
"access.token.claim" => "true",
|
|
164
|
+
"lightweight.claim" => "false",
|
|
165
|
+
"introspection.token.claim" => "true"
|
|
166
|
+
}
|
|
167
|
+
mapper
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "creates successfully" do
|
|
171
|
+
expect(@client.create!(mapper_representation)).to be true
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
describe "#save" do
|
|
177
|
+
before(:each) do
|
|
178
|
+
@client = KeycloakAdmin.realm(realm_name).client_scope_protocol_mappers(client_scope_id)
|
|
179
|
+
stub_token_client
|
|
180
|
+
allow_any_instance_of(RestClient::Resource).to receive(:put).and_return ""
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context "with a hardcoded claim mapper" do
|
|
184
|
+
let(:mapper_representation) { KeycloakAdmin::ProtocolMapperRepresentation.from_hash(JSON.parse(mapper_json)) }
|
|
185
|
+
|
|
186
|
+
it "calls put on the mapper url" do
|
|
187
|
+
expect_any_instance_of(RestClient::Resource).to receive(:put).with(anything, anything)
|
|
188
|
+
@client.save(mapper_representation)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
context "with an audience mapper" do
|
|
193
|
+
let(:mapper_representation) { KeycloakAdmin::ProtocolMapperRepresentation.from_hash(JSON.parse(audience_mapper_json)) }
|
|
194
|
+
|
|
195
|
+
it "calls put on the mapper url" do
|
|
196
|
+
expect_any_instance_of(RestClient::Resource).to receive(:put).with(anything, anything)
|
|
197
|
+
@client.save(mapper_representation)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe "#delete" do
|
|
203
|
+
before(:each) do
|
|
204
|
+
@client = KeycloakAdmin.realm(realm_name).client_scope_protocol_mappers(client_scope_id)
|
|
205
|
+
stub_token_client
|
|
206
|
+
allow_any_instance_of(RestClient::Resource).to receive(:delete).and_return ""
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it "returns true" do
|
|
210
|
+
expect(@client.delete(mapper_id)).to eq true
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
describe "#protocol_mappers_url" do
|
|
215
|
+
let(:client) { KeycloakAdmin.realm(realm_name).client_scope_protocol_mappers(client_scope_id) }
|
|
216
|
+
let(:base_url) { "http://auth.service.io/auth/admin/realms/valid-realm/client-scopes/valid-scope-id/protocol-mappers/models" }
|
|
217
|
+
|
|
218
|
+
context "without a mapper_id" do
|
|
219
|
+
it "returns the base url" do
|
|
220
|
+
expect(client.protocol_mappers_url).to eq base_url
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
context "with a mapper_id" do
|
|
225
|
+
it "returns the url with mapper_id appended" do
|
|
226
|
+
expect(client.protocol_mappers_url(mapper_id)).to eq "#{base_url}/valid-mapper-id"
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|