keycloak-admin 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/Dockerfile +24 -0
  3. data/.github/workflows/ci.yml +83 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile.lock +3 -3
  6. data/README.md +267 -1
  7. data/lib/keycloak-admin/client/client_authz_permission_client.rb +81 -0
  8. data/lib/keycloak-admin/client/client_authz_policy_client.rb +76 -0
  9. data/lib/keycloak-admin/client/client_authz_resource_client.rb +93 -0
  10. data/lib/keycloak-admin/client/client_authz_scope_client.rb +71 -0
  11. data/lib/keycloak-admin/client/realm_client.rb +16 -0
  12. data/lib/keycloak-admin/representation/client_authz_permission_representation.rb +34 -0
  13. data/lib/keycloak-admin/representation/client_authz_policy_config_representation.rb +15 -0
  14. data/lib/keycloak-admin/representation/client_authz_policy_representation.rb +27 -0
  15. data/lib/keycloak-admin/representation/client_authz_resource_representation.rb +26 -0
  16. data/lib/keycloak-admin/representation/client_authz_scope_representation.rb +17 -0
  17. data/lib/keycloak-admin/version.rb +1 -1
  18. data/lib/keycloak-admin.rb +9 -0
  19. data/spec/client/client_authz_permission_client_spec.rb +170 -0
  20. data/spec/client/client_authz_policy_client_spec.rb +170 -0
  21. data/spec/client/client_authz_resource_client_spec.rb +150 -0
  22. data/spec/client/client_authz_scope_client_spec.rb +134 -0
  23. data/spec/integration/client_authorization_spec.rb +95 -0
  24. data/spec/representation/client_authz_permission_representation_spec.rb +52 -0
  25. data/spec/representation/client_authz_policy_representation_spec.rb +47 -0
  26. data/spec/representation/client_authz_resource_representation_spec.rb +33 -0
  27. data/spec/representation/client_authz_scope_representation_spec.rb +19 -0
  28. metadata +23 -3
@@ -0,0 +1,93 @@
1
+ module KeycloakAdmin
2
+ class ClientAuthzResourceClient < Client
3
+ def initialize(configuration, realm_client, client_id)
4
+ super(configuration)
5
+ raise ArgumentError.new("realm must be defined") unless realm_client.name_defined?
6
+ @realm_client = realm_client
7
+ @client_id = client_id
8
+ end
9
+
10
+ def list
11
+ response = execute_http do
12
+ RestClient::Resource.new(authz_resources_url(@client_id), @configuration.rest_client_options).get(headers)
13
+ end
14
+ JSON.parse(response).map { |role_as_hash| ClientAuthzResourceRepresentation.from_hash(role_as_hash) }
15
+ end
16
+
17
+ def get(resource_id)
18
+ response = execute_http do
19
+ RestClient::Resource.new(authz_resources_url(@client_id, resource_id), @configuration.rest_client_options).get(headers)
20
+ end
21
+ ClientAuthzResourceRepresentation.from_hash(JSON.parse(response))
22
+ end
23
+
24
+ def update(resource_id, client_authz_resource_representation)
25
+ raise "scope[:name] is mandatory and the only necessary attribute to add scope to resource" if client_authz_resource_representation[:scopes] && client_authz_resource_representation[:scopes].any?{|a| !a[:name]}
26
+
27
+ existing_resource = get(resource_id)
28
+ new_resource = build(
29
+ client_authz_resource_representation[:name] || existing_resource.name,
30
+ client_authz_resource_representation[:type] || existing_resource.type,
31
+ (client_authz_resource_representation[:uris] || [] ) + existing_resource.uris,
32
+ client_authz_resource_representation[:owner_managed_access] || existing_resource.owner_managed_access,
33
+ client_authz_resource_representation[:display_name] || existing_resource.display_name,
34
+ (client_authz_resource_representation[:scopes] || []) + existing_resource.scopes.map{|s| {name: s.name}},
35
+ client_authz_resource_representation[:attributes] || existing_resource.attributes
36
+ )
37
+
38
+ execute_http do
39
+ RestClient::Resource.new(authz_resources_url(@client_id, resource_id), @configuration.rest_client_options).put(new_resource.to_json, headers)
40
+ end
41
+ get(resource_id)
42
+ end
43
+
44
+ def create!(name, type, uris, owner_managed_access, display_name, scopes, attributes = {})
45
+ save(build(name, type, uris, owner_managed_access, display_name, scopes, attributes))
46
+ end
47
+
48
+ def find_by(name, type, uris, owner, scope)
49
+ response = execute_http do
50
+ url = "#{authz_resources_url(@client_id)}?name=#{name}&type=#{type}&uris=#{uris}&owner=#{owner}&scope=#{scope}&deep=true&first=0&max=100"
51
+ RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
52
+ end
53
+ JSON.parse(response).map { |role_as_hash| ClientAuthzResourceRepresentation.from_hash(role_as_hash) }
54
+ end
55
+
56
+ def save(client_authz_resource_representation)
57
+ response = execute_http do
58
+ RestClient::Resource.new(authz_resources_url(@client_id), @configuration.rest_client_options).post(client_authz_resource_representation.to_json, headers)
59
+ end
60
+ ClientAuthzResourceRepresentation.from_hash(JSON.parse(response))
61
+ end
62
+
63
+ def delete(resource_id)
64
+ execute_http do
65
+ RestClient::Resource.new(authz_resources_url(@client_id, resource_id), @configuration.rest_client_options).delete(headers)
66
+ end
67
+ true
68
+ end
69
+
70
+ def authz_resources_url(client_id, id = nil)
71
+ if id
72
+ "#{@realm_client.realm_admin_url}/clients/#{client_id}/authz/resource-server/resource/#{id}"
73
+ else
74
+ "#{@realm_client.realm_admin_url}/clients/#{client_id}/authz/resource-server/resource"
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def build(name, type, uris, owner_managed_access, display_name, scopes, attributes={})
81
+ resource = ClientAuthzResourceRepresentation.new
82
+ resource.name = name
83
+ resource.type = type
84
+ resource.uris = uris
85
+ resource.owner_managed_access = owner_managed_access
86
+ resource.display_name = display_name
87
+ resource.scopes = scopes
88
+ resource.attributes = attributes || {}
89
+ resource
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,71 @@
1
+ module KeycloakAdmin
2
+ class ClientAuthzScopeClient < Client
3
+ def initialize(configuration, realm_client, client_id, resource_id = nil)
4
+ super(configuration)
5
+ raise ArgumentError.new("realm must be defined") unless realm_client.name_defined?
6
+ @realm_client = realm_client
7
+ @client_id = client_id
8
+ @resource_id = resource_id
9
+ end
10
+
11
+ def create!(name, display_name, icon_uri)
12
+ response = save(build(name, display_name, icon_uri))
13
+ ClientAuthzScopeRepresentation.from_hash(JSON.parse(response))
14
+ end
15
+
16
+ def list
17
+ response = execute_http do
18
+ RestClient::Resource.new(authz_scopes_url(@client_id, @resource_id), @configuration.rest_client_options).get(headers)
19
+ end
20
+ JSON.parse(response).map { |role_as_hash| ClientAuthzScopeRepresentation.from_hash(role_as_hash) }
21
+ end
22
+
23
+ def delete(scope_id)
24
+ execute_http do
25
+ RestClient::Resource.new(authz_scopes_url(@client_id, nil, scope_id), @configuration.rest_client_options).delete(headers)
26
+ end
27
+ true
28
+ end
29
+
30
+ def get(scope_id)
31
+ response = execute_http do
32
+ RestClient::Resource.new(authz_scopes_url(@client_id, nil, scope_id), @configuration.rest_client_options).get(headers)
33
+ end
34
+ ClientAuthzScopeRepresentation.from_hash(JSON.parse(response))
35
+ end
36
+
37
+ def search(name)
38
+ url = "#{authz_scopes_url(@client_id)}?first=0&max=11&deep=false&name=#{name}"
39
+ response = execute_http do
40
+ RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
41
+ end
42
+ JSON.parse(response).map { |role_as_hash| ClientAuthzScopeRepresentation.from_hash(role_as_hash) }
43
+ end
44
+
45
+ def authz_scopes_url(client_id, resource_id = nil, id = nil)
46
+ if resource_id
47
+ "#{@realm_client.realm_admin_url}/clients/#{client_id}/authz/resource-server/resource/#{resource_id}/scopes"
48
+ elsif id
49
+ "#{@realm_client.realm_admin_url}/clients/#{client_id}/authz/resource-server/scope/#{id}"
50
+ else
51
+ "#{@realm_client.realm_admin_url}/clients/#{client_id}/authz/resource-server/scope"
52
+ end
53
+ end
54
+
55
+ def save(scope_representation)
56
+ execute_http do
57
+ RestClient::Resource.new(authz_scopes_url(@client_id), @configuration.rest_client_options).post(
58
+ create_payload(scope_representation), headers
59
+ )
60
+ end
61
+ end
62
+
63
+ def build(name, display_name, icon_uri)
64
+ scope = ClientAuthzScopeRepresentation.new
65
+ scope.name = name
66
+ scope.icon_uri = icon_uri
67
+ scope.display_name = display_name
68
+ scope
69
+ end
70
+ end
71
+ end
@@ -99,6 +99,22 @@ module KeycloakAdmin
99
99
  UserResource.new(@configuration, self, user_id)
100
100
  end
101
101
 
102
+ def authz_scopes(client_id, resource_id = nil)
103
+ ClientAuthzScopeClient.new(@configuration, self, client_id, resource_id)
104
+ end
105
+
106
+ def authz_resources(client_id)
107
+ ClientAuthzResourceClient.new(@configuration, self, client_id)
108
+ end
109
+
110
+ def authz_permissions(client_id, type, resource_id = nil)
111
+ ClientAuthzPermissionClient.new(@configuration, self, client_id, type, resource_id)
112
+ end
113
+
114
+ def authz_policies(client_id, type)
115
+ ClientAuthzPolicyClient.new(@configuration, self, client_id, type)
116
+ end
117
+
102
118
  def name_defined?
103
119
  !@realm_name.nil?
104
120
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ ## ### {"resources":["4f55e984-d1ec-405c-a25c-1387f88acd5c"],"policies":["e9e3bc49-fe11-4287-b6fc-fa8be4930ffa"],"name":"delme policy","description":"delme polidy ","decisionStrategy":"UNANIMOUS","resourceType":""}
5
+ #
6
+ module KeycloakAdmin
7
+ class ClientAuthzPermissionRepresentation < Representation
8
+ attr_accessor :id,
9
+ :name,
10
+ :description,
11
+ :decision_strategy,
12
+ :resource_type,
13
+ :resources,
14
+ :policies,
15
+ :scopes,
16
+ :logic,
17
+ :type
18
+
19
+ def self.from_hash(hash)
20
+ resource = new
21
+ resource.id = hash["id"]
22
+ resource.name = hash["name"]
23
+ resource.description = hash["description"]
24
+ resource.decision_strategy = hash["decisionStrategy"]
25
+ resource.resource_type = hash["resourceType"]
26
+ resource.resources = hash["resources"]
27
+ resource.policies = hash["policies"]
28
+ resource.scopes = hash["scopes"]
29
+ resource.logic = hash["logic"]
30
+ resource.type = hash["type"]
31
+ resource
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ module KeycloakAdmin
2
+ class ClientAuthzPolicyConfigRepresentation < Representation
3
+ attr_accessor :roles,
4
+ :code
5
+
6
+ def self.from_hash(hash)
7
+ resource = new
8
+ resource.code = hash["code"]
9
+ resource.roles = JSON.parse(hash["roles"] || '[]').map do |str|
10
+ RoleRepresentation.from_hash(str)
11
+ end
12
+ resource
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module KeycloakAdmin
2
+ class ClientAuthzPolicyRepresentation < Representation
3
+ attr_accessor :id,
4
+ :name,
5
+ :description,
6
+ :type,
7
+ :logic,
8
+ :decision_strategy,
9
+ :config,
10
+ :fetch_roles,
11
+ :roles
12
+
13
+ def self.from_hash(hash)
14
+ resource = new
15
+ resource.id = hash["id"]
16
+ resource.name = hash["name"]
17
+ resource.description = hash["description"]
18
+ resource.type = hash["type"]
19
+ resource.logic = hash["logic"]
20
+ resource.decision_strategy = hash["decisionStrategy"]
21
+ resource.roles = hash["roles"]
22
+ resource.fetch_roles = hash["fetchRoles"]
23
+ resource.config = ClientAuthzPolicyConfigRepresentation.from_hash((hash["config"] || {}))
24
+ resource
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ module KeycloakAdmin
2
+
3
+ class ClientAuthzResourceRepresentation < Representation
4
+ attr_accessor :id,
5
+ :name,
6
+ :type,
7
+ :uris,
8
+ :owner_managed_access,
9
+ :display_name,
10
+ :attributes,
11
+ :scopes
12
+
13
+ def self.from_hash(hash)
14
+ resource = new
15
+ resource.id = hash["_id"]
16
+ resource.type = hash["type"]
17
+ resource.name = hash["name"]
18
+ resource.owner_managed_access = hash["ownerManagedAccess"]
19
+ resource.uris = hash["uris"]
20
+ resource.display_name = hash["displayName"]
21
+ resource.attributes = hash.fetch("attributes", {}).map { |k, v| [k.to_sym, Array(v)] }.to_h
22
+ resource.scopes = (hash["scopes"] || []).map { |scope_hash| ClientAuthzScopeRepresentation.from_hash(scope_hash) }
23
+ resource
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ module KeycloakAdmin
2
+ class ClientAuthzScopeRepresentation < Representation
3
+ attr_accessor :id,
4
+ :name,
5
+ :icon_uri,
6
+ :display_name
7
+
8
+ def self.from_hash(hash)
9
+ scope = new
10
+ scope.id = hash["id"]
11
+ scope.name = hash["name"]
12
+ scope.icon_uri = hash["iconUri"]
13
+ scope.display_name = hash["displayName"]
14
+ scope
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module KeycloakAdmin
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.3"
3
3
  end
@@ -14,6 +14,10 @@ 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
16
  require_relative "keycloak-admin/client/attack_detection_client"
17
+ require_relative "keycloak-admin/client/client_authz_scope_client"
18
+ require_relative "keycloak-admin/client/client_authz_resource_client"
19
+ require_relative "keycloak-admin/client/client_authz_policy_client"
20
+ require_relative "keycloak-admin/client/client_authz_permission_client"
17
21
  require_relative "keycloak-admin/representation/camel_json"
18
22
  require_relative "keycloak-admin/representation/representation"
19
23
  require_relative "keycloak-admin/representation/protocol_mapper_representation"
@@ -31,6 +35,11 @@ require_relative "keycloak-admin/representation/identity_provider_mapper_represe
31
35
  require_relative "keycloak-admin/representation/identity_provider_representation"
32
36
  require_relative "keycloak-admin/representation/attack_detection_representation"
33
37
  require_relative "keycloak-admin/representation/session_representation"
38
+ require_relative "keycloak-admin/representation/client_authz_scope_representation"
39
+ require_relative "keycloak-admin/representation/client_authz_resource_representation"
40
+ require_relative "keycloak-admin/representation/client_authz_policy_representation"
41
+ require_relative "keycloak-admin/representation/client_authz_policy_config_representation"
42
+ require_relative "keycloak-admin/representation/client_authz_permission_representation"
34
43
  require_relative "keycloak-admin/resource/base_role_containing_resource"
35
44
  require_relative "keycloak-admin/resource/group_resource"
36
45
  require_relative "keycloak-admin/resource/user_resource"
@@ -0,0 +1,170 @@
1
+ RSpec.describe KeycloakAdmin::ClientAuthzPermissionClient do
2
+
3
+ describe "#initialize" do
4
+ let(:realm_name) { nil }
5
+ let(:type) { :scope }
6
+ before(:each) do
7
+ @realm = KeycloakAdmin.realm(realm_name)
8
+ end
9
+
10
+ context "when realm_name is defined" do
11
+ let(:realm_name) { "master" }
12
+ it "does not raise any error" do
13
+ expect {
14
+ @realm.authz_permissions("", type)
15
+ }.to_not raise_error
16
+ end
17
+ end
18
+
19
+ context "when realm_name is not defined" do
20
+ let(:realm_name) { nil }
21
+ it "raises any error" do
22
+ expect {
23
+ @realm.authz_permissions("", type)
24
+ }.to raise_error(ArgumentError)
25
+ end
26
+ end
27
+
28
+ context "when type is bad value" do
29
+ let(:realm_name) { "master" }
30
+ let(:type) { "bad-type" }
31
+ it "does not raise any error" do
32
+ expect {
33
+ @realm.authz_permissions("", type)
34
+ }.to raise_error
35
+ end
36
+ end
37
+ end
38
+
39
+ describe '#delete' do
40
+ let(:realm_name) { "valid-realm" }
41
+ let(:client_id) { "valid-client-id" }
42
+ let(:client_authz_permission) { KeycloakAdmin.realm(realm_name).authz_permissions(client_id, "resource") }
43
+ before(:each) do
44
+ stub_token_client
45
+ allow_any_instance_of(RestClient::Resource).to receive(:delete).and_return 'true'
46
+ end
47
+
48
+ it "deletes a permission" do
49
+ expect(client_authz_permission.delete("valid-permission-id")).to be_truthy
50
+ end
51
+ end
52
+
53
+ describe '#find_by' do
54
+ let(:realm_name) { "valid-realm" }
55
+ let(:client_id) { "valid-client-id" }
56
+ let(:client_authz_permission) { KeycloakAdmin.realm(realm_name).authz_permissions(client_id, "resource") }
57
+ before(:each) do
58
+ stub_token_client
59
+ allow_any_instance_of(RestClient::Resource).to receive(:get).and_return '[{"id":"245ce612-ccdc-4426-8ea7-e0e29a718033","name":"Default Permission","description":"A permission that applies to the default resource type","type":"resource","logic":"POSITIVE","decisionStrategy":"UNANIMOUS","resourceType":"urn:dummy-client:resources:default"},{"id":"06a21e38-4e92-466d-8647-ffcd9c7b51c3","name":"delme policy","description":"delme polidy ","type":"resource","logic":"POSITIVE","decisionStrategy":"UNANIMOUS","resourceType":"asdfasdf"}]'
60
+ end
61
+
62
+ it "finds permissions" do
63
+ response = client_authz_permission.find_by("name", "resource", "scope")
64
+ expect(response[0].id).to eql "245ce612-ccdc-4426-8ea7-e0e29a718033"
65
+ expect(response[1].id).to eql "06a21e38-4e92-466d-8647-ffcd9c7b51c3"
66
+ end
67
+ end
68
+
69
+ describe '#create!' do
70
+ let(:realm_name) { "valid-realm" }
71
+ let(:client_id) { "valid-client-id" }
72
+ let(:client_authz_permission) { KeycloakAdmin.realm(realm_name).authz_permissions(client_id, "resource") }
73
+ before(:each) do
74
+ stub_token_client
75
+ allow_any_instance_of(RestClient::Resource).to receive(:post).and_return '{"id":"245ce612-ccdc-4426-8ea7-e0e29a718033","name":"Default Permission","description":"A permission that applies to the default resource type","type":"resource","logic":"POSITIVE","decisionStrategy":"UNANIMOUS","resourceType":"urn:dummy-client:resources:default"}'
76
+ end
77
+
78
+ it "creates a permission" do
79
+ response = client_authz_permission.create!("name", "description", "UNANIMOUS", "POSITIVE", [], [], [], "resource")
80
+ expect(response.id).to eql "245ce612-ccdc-4426-8ea7-e0e29a718033"
81
+ expect(response.name).to eql "Default Permission"
82
+ expect(response.description).to eql "A permission that applies to the default resource type"
83
+ expect(response.logic).to eql "POSITIVE"
84
+ expect(response.decision_strategy).to eql "UNANIMOUS"
85
+ expect(response.resource_type).to eql "urn:dummy-client:resources:default"
86
+ end
87
+ end
88
+
89
+ describe '#list' do
90
+ let(:realm_name) { "valid-realm" }
91
+ let(:client_id) { "valid-client-id" }
92
+ before(:each) do
93
+ @client_authz_permission = KeycloakAdmin.realm(realm_name).authz_permissions(client_id, "resource")
94
+ stub_token_client
95
+ allow_any_instance_of(RestClient::Resource).to receive(:get).and_return '[{"id":"245ce612-ccdc-4426-8ea7-e0e29a718033","name":"Default Permission","description":"A permission that applies to the default resource type","type":"resource","logic":"POSITIVE","decisionStrategy":"UNANIMOUS","resourceType":"urn:dummy-client:resources:default"},{"id":"06a21e38-4e92-466d-8647-ffcd9c7b51c3","name":"delme policy","description":"delme polidy ","type":"resource","logic":"POSITIVE","decisionStrategy":"UNANIMOUS","resourceType":"asdfasdf"}]'
96
+
97
+ end
98
+
99
+ it "returns list of authz permissions" do
100
+ response = @client_authz_permission.list
101
+ expect(response.size).to eq 2
102
+ expect(response[0].id).to eq "245ce612-ccdc-4426-8ea7-e0e29a718033"
103
+ expect(response[0].name).to eq "Default Permission"
104
+ expect(response[0].description).to eq "A permission that applies to the default resource type"
105
+ expect(response[0].logic).to eq "POSITIVE"
106
+ expect(response[0].decision_strategy).to eq "UNANIMOUS"
107
+ expect(response[0].resource_type).to eq "urn:dummy-client:resources:default"
108
+ end
109
+ end
110
+
111
+ describe '#get' do
112
+ let(:realm_name) { "valid-realm" }
113
+ let(:client_id) { "valid-client-id" }
114
+ let(:client_authz_permission) { KeycloakAdmin.realm(realm_name).authz_permissions(client_id, "resource") }
115
+ before(:each) do
116
+ stub_token_client
117
+ allow_any_instance_of(RestClient::Resource).to receive(:get).and_return '{"id":"245ce612-ccdc-4426-8ea7-e0e29a718033","name":"Default Permission","description":"A permission that applies to the default resource type","type":"resource","logic":"POSITIVE","decisionStrategy":"UNANIMOUS","resourceType":"urn:dummy-client:resources:default"}'
118
+ end
119
+
120
+ it "gets a permission" do
121
+ response = client_authz_permission.get("245ce612-ccdc-4426-8ea7-e0e29a718033")
122
+ expect(response.id).to eql "245ce612-ccdc-4426-8ea7-e0e29a718033"
123
+ expect(response.name).to eql "Default Permission"
124
+ expect(response.description).to eql "A permission that applies to the default resource type"
125
+ expect(response.logic).to eql "POSITIVE"
126
+ expect(response.decision_strategy).to eql "UNANIMOUS"
127
+ expect(response.resource_type).to eql "urn:dummy-client:resources:default"
128
+ end
129
+ end
130
+
131
+ describe '#authz_permission_url' do
132
+ let(:realm_name) { "valid-realm" }
133
+ let(:client_id) { "valid-client-id" }
134
+ let(:resource_id){ "valid-resource-id" }
135
+ let(:type){ "resource" }
136
+ let(:client_authz_permission) { KeycloakAdmin.realm(realm_name).authz_permissions(client_id, type, resource_id) }
137
+ context 'when resource_id is nil' do
138
+ it "return a proper url" do
139
+ expect(client_authz_permission.authz_permission_url(client_id)).to eq "http://auth.service.io/auth/admin/realms/valid-realm/clients/valid-client-id/authz/resource-server/permission/"
140
+ end
141
+ end
142
+ context 'when resource_id is not nil' do
143
+ it "return a proper url" do
144
+ expect(client_authz_permission.authz_permission_url(client_id, resource_id)).to eq "http://auth.service.io/auth/admin/realms/valid-realm/clients/valid-client-id/authz/resource-server/resource/valid-resource-id/permissions"
145
+ end
146
+ end
147
+ context 'when id is not nil' do
148
+ it "return a proper url" do
149
+ expect(client_authz_permission.authz_permission_url(client_id, nil, :resource, "valid-permission-id")).to eq "http://auth.service.io/auth/admin/realms/valid-realm/clients/valid-client-id/authz/resource-server/permission/resource/valid-permission-id"
150
+ end
151
+ end
152
+ context 'when resource_id and id are nil' do
153
+ it "return a proper url" do
154
+ expect(client_authz_permission.authz_permission_url(client_id, nil, :resource)).to eq "http://auth.service.io/auth/admin/realms/valid-realm/clients/valid-client-id/authz/resource-server/permission/resource"
155
+ end
156
+ end
157
+ end
158
+
159
+ describe '#authz_permission_url' do
160
+ let(:realm_name) { "valid-realm" }
161
+ let(:client_id) { "valid-client-id" }
162
+ before(:each) do
163
+ @client_authz_permission = KeycloakAdmin.realm(realm_name).authz_permissions(client_id, "resource")
164
+ end
165
+
166
+ it "return a proper url" do
167
+ expect(@client_authz_permission.authz_permission_url(client_id)).to eq "http://auth.service.io/auth/admin/realms/valid-realm/clients/valid-client-id/authz/resource-server/permission/"
168
+ end
169
+ end
170
+ end