keycloak-admin 1.1.4 → 1.1.6
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/Dockerfile +24 -24
- data/.github/workflows/ci.yml +80 -80
- data/.gitignore +9 -9
- data/.rspec +2 -2
- data/CHANGELOG.md +23 -0
- data/Dockerfile +12 -12
- data/Gemfile +3 -3
- data/Gemfile.lock +1 -1
- data/MIT-LICENSE +20 -20
- data/README.md +20 -1
- data/bin/console +9 -9
- data/keycloak-admin.gemspec +24 -24
- data/lib/keycloak-admin/client/attack_detection_client.rb +41 -41
- data/lib/keycloak-admin/client/client.rb +56 -56
- data/lib/keycloak-admin/client/client_authz_permission_client.rb +80 -80
- data/lib/keycloak-admin/client/client_authz_policy_client.rb +75 -75
- data/lib/keycloak-admin/client/client_authz_resource_client.rb +92 -92
- data/lib/keycloak-admin/client/client_authz_scope_client.rb +70 -70
- data/lib/keycloak-admin/client/client_client.rb +71 -71
- data/lib/keycloak-admin/client/client_role_client.rb +20 -20
- data/lib/keycloak-admin/client/client_role_mappings_client.rb +32 -32
- data/lib/keycloak-admin/client/configurable_token_client.rb +35 -35
- data/lib/keycloak-admin/client/group_client.rb +148 -148
- data/lib/keycloak-admin/client/identity_provider_client.rb +51 -51
- data/lib/keycloak-admin/client/organization_client.rb +245 -0
- data/lib/keycloak-admin/client/realm_client.rb +126 -122
- data/lib/keycloak-admin/client/role_client.rb +59 -59
- data/lib/keycloak-admin/client/role_mapper_client.rb +47 -47
- data/lib/keycloak-admin/client/token_client.rb +29 -29
- data/lib/keycloak-admin/client/user_client.rb +278 -266
- data/lib/keycloak-admin/configuration.rb +52 -52
- data/lib/keycloak-admin/representation/attack_detection_representation.rb +17 -17
- data/lib/keycloak-admin/representation/camel_json.rb +12 -12
- data/lib/keycloak-admin/representation/client_authz_permission_representation.rb +33 -33
- data/lib/keycloak-admin/representation/client_authz_policy_config_representation.rb +14 -14
- data/lib/keycloak-admin/representation/client_authz_policy_representation.rb +26 -26
- data/lib/keycloak-admin/representation/client_authz_resource_representation.rb +25 -25
- data/lib/keycloak-admin/representation/client_authz_scope_representation.rb +16 -16
- data/lib/keycloak-admin/representation/client_representation.rb +71 -71
- data/lib/keycloak-admin/representation/credential_representation.rb +71 -38
- data/lib/keycloak-admin/representation/federated_identity_representation.rb +15 -15
- data/lib/keycloak-admin/representation/group_representation.rb +21 -21
- data/lib/keycloak-admin/representation/identity_provider_mapper_representation.rb +19 -19
- data/lib/keycloak-admin/representation/identity_provider_representation.rb +71 -67
- data/lib/keycloak-admin/representation/impersonation_redirection_representation.rb +16 -16
- data/lib/keycloak-admin/representation/impersonation_representation.rb +43 -43
- 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/representation/protocol_mapper_representation.rb +19 -19
- data/lib/keycloak-admin/representation/realm_representation.rb +14 -14
- data/lib/keycloak-admin/representation/representation.rb +23 -23
- data/lib/keycloak-admin/representation/role_representation.rb +19 -19
- data/lib/keycloak-admin/representation/session_representation.rb +22 -22
- data/lib/keycloak-admin/representation/token_representation.rb +39 -39
- data/lib/keycloak-admin/representation/user_representation.rb +47 -47
- data/lib/keycloak-admin/resource/base_role_containing_resource.rb +28 -28
- data/lib/keycloak-admin/resource/group_resource.rb +11 -11
- data/lib/keycloak-admin/resource/user_resource.rb +7 -7
- data/lib/keycloak-admin/version.rb +3 -3
- data/lib/keycloak-admin.rb +88 -84
- data/spec/client/attack_detection_client_spec.rb +102 -102
- data/spec/client/client_authz_permission_client_spec.rb +170 -170
- data/spec/client/client_authz_policy_client_spec.rb +169 -169
- data/spec/client/client_authz_resource_client_spec.rb +150 -150
- data/spec/client/client_authz_scope_client_spec.rb +133 -133
- data/spec/client/client_client_spec.rb +133 -133
- data/spec/client/client_role_mappings_client_spec.rb +82 -82
- data/spec/client/client_spec.rb +28 -28
- data/spec/client/configurable_token_client_spec.rb +34 -34
- data/spec/client/group_client_spec.rb +328 -328
- data/spec/client/identity_provider_client_spec.rb +92 -92
- data/spec/client/organization_client_spec.rb +595 -0
- data/spec/client/realm_client_spec.rb +155 -155
- data/spec/client/role_client_spec.rb +79 -79
- data/spec/client/role_mapper_client_spec.rb +113 -113
- data/spec/client/token_client_spec.rb +68 -68
- data/spec/client/user_client_spec.rb +418 -373
- data/spec/configuration_spec.rb +113 -113
- data/spec/integration/client_authorization_spec.rb +93 -93
- data/spec/representation/attack_detection_representation_spec.rb +15 -15
- data/spec/representation/client_authz_permission_representation_spec.rb +52 -52
- data/spec/representation/client_authz_policy_representation_spec.rb +46 -46
- data/spec/representation/client_authz_resource_representation_spec.rb +33 -33
- data/spec/representation/client_authz_scope_representation_spec.rb +18 -18
- data/spec/representation/client_representation_spec.rb +119 -119
- data/spec/representation/credential_representation_spec.rb +68 -0
- data/spec/representation/group_representation_spec.rb +22 -22
- data/spec/representation/identity_provider_mapper_representation_spec.rb +24 -24
- data/spec/representation/identity_provider_representation_spec.rb +113 -113
- data/spec/representation/impersonation_representation_spec.rb +163 -163
- data/spec/representation/organization_representation_spec.rb +64 -0
- data/spec/representation/protocol_mapper_representation_spec.rb +57 -57
- data/spec/representation/role_representation_spec.rb +37 -37
- data/spec/representation/session_representation_spec.rb +15 -15
- data/spec/representation/user_representation_spec.rb +15 -15
- data/spec/resource/group_resource_spec.rb +14 -14
- data/spec/resource/user_resource_spec.rb +14 -14
- data/spec/spec_helper.rb +37 -37
- metadata +13 -6
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
module KeycloakAdmin
|
|
2
|
-
class GroupClient < 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 get(group_id)
|
|
10
|
-
response = execute_http do
|
|
11
|
-
RestClient::Resource.new(groups_url(group_id), @configuration.rest_client_options).get(headers)
|
|
12
|
-
end
|
|
13
|
-
GroupRepresentation.from_hash(JSON.parse(response))
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def children(parent_id)
|
|
17
|
-
response = execute_http do
|
|
18
|
-
url = "#{groups_url(parent_id)}/children"
|
|
19
|
-
RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
|
|
20
|
-
end
|
|
21
|
-
JSON.parse(response).map { |group_as_hash| GroupRepresentation.from_hash(group_as_hash) }
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def list
|
|
25
|
-
search(nil)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def search(query)
|
|
29
|
-
derived_headers = case query
|
|
30
|
-
when String
|
|
31
|
-
headers.merge({params: { search: query }})
|
|
32
|
-
when Hash
|
|
33
|
-
headers.merge({params: query })
|
|
34
|
-
else
|
|
35
|
-
headers
|
|
36
|
-
end
|
|
37
|
-
response = execute_http do
|
|
38
|
-
RestClient::Resource.new(groups_url, @configuration.rest_client_options).get(derived_headers)
|
|
39
|
-
end
|
|
40
|
-
JSON.parse(response).map { |group_as_hash| GroupRepresentation.from_hash(group_as_hash) }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def create!(name, path = nil, attributes = {})
|
|
44
|
-
response = save(build(name, path, attributes))
|
|
45
|
-
created_id(response)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def save(group_representation)
|
|
49
|
-
execute_http do
|
|
50
|
-
payload = create_payload(group_representation)
|
|
51
|
-
if group_representation.id
|
|
52
|
-
RestClient::Resource.new(groups_url(group_representation.id), @configuration.rest_client_options).put(payload, headers)
|
|
53
|
-
else
|
|
54
|
-
RestClient::Resource.new(groups_url, @configuration.rest_client_options).post(payload, headers)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def create_subgroup!(parent_id, name, attributes = {})
|
|
60
|
-
url = "#{groups_url(parent_id)}/children"
|
|
61
|
-
response = execute_http do
|
|
62
|
-
RestClient::Resource.new(url, @configuration.rest_client_options).post(
|
|
63
|
-
create_payload(build(name, nil, attributes)), headers
|
|
64
|
-
)
|
|
65
|
-
end
|
|
66
|
-
created_id(response)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def delete(group_id)
|
|
70
|
-
execute_http do
|
|
71
|
-
RestClient::Resource.new(groups_url(group_id), @configuration.rest_client_options).delete(headers)
|
|
72
|
-
end
|
|
73
|
-
true
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def members(group_id, first=0, max=100)
|
|
77
|
-
url = "#{groups_url(group_id)}/members"
|
|
78
|
-
query = {first: first.try(:to_i), max: max.try(:to_i)}.compact
|
|
79
|
-
unless query.empty?
|
|
80
|
-
query_string = query.to_a.map { |e| "#{e[0]}=#{e[1]}" }.join("&")
|
|
81
|
-
url = "#{url}?#{query_string}"
|
|
82
|
-
end
|
|
83
|
-
response = execute_http do
|
|
84
|
-
RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
|
|
85
|
-
end
|
|
86
|
-
JSON.parse(response).map { |user_as_hash| UserRepresentation.from_hash(user_as_hash) }
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# Gets all realm-level roles for a group
|
|
90
|
-
def get_realm_level_roles(group_id)
|
|
91
|
-
url = "#{groups_url(group_id)}/role-mappings/realm"
|
|
92
|
-
response = execute_http do
|
|
93
|
-
RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
|
|
94
|
-
end
|
|
95
|
-
JSON.parse(response).map { |role_as_hash| RoleRepresentation.from_hash(role_as_hash) }
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# Adds a realm-level role to a group via the role name
|
|
99
|
-
def add_realm_level_role_name!(group_id, role_name)
|
|
100
|
-
# creates a full role-representation object needed by the keycloak api to work
|
|
101
|
-
role_representation = RoleClient.new(@configuration, @realm_client).get(role_name)
|
|
102
|
-
url = "#{groups_url(group_id)}/role-mappings/realm"
|
|
103
|
-
response = execute_http do
|
|
104
|
-
RestClient::Resource.new(url, @configuration.rest_client_options).post(
|
|
105
|
-
create_payload([role_representation]), headers
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
role_representation
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# Remove a realm-level role from a group by the role name
|
|
112
|
-
def remove_realm_level_role_name!(group_id, role_name)
|
|
113
|
-
role_representation = RoleClient.new(@configuration, @realm_client).get(role_name)
|
|
114
|
-
url = "#{groups_url(group_id)}/role-mappings/realm"
|
|
115
|
-
execute_http do
|
|
116
|
-
RestClient::Request.execute(
|
|
117
|
-
@configuration.rest_client_options.merge(
|
|
118
|
-
url:,
|
|
119
|
-
method: :delete,
|
|
120
|
-
payload: create_payload([role_representation]),
|
|
121
|
-
headers: headers
|
|
122
|
-
)
|
|
123
|
-
)
|
|
124
|
-
end
|
|
125
|
-
true
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def groups_url(id=nil)
|
|
129
|
-
if id
|
|
130
|
-
"#{@realm_client.realm_admin_url}/groups/#{id}"
|
|
131
|
-
else
|
|
132
|
-
"#{@realm_client.realm_admin_url}/groups"
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
private
|
|
137
|
-
|
|
138
|
-
def build(name, path, attributes)
|
|
139
|
-
GroupRepresentation.from_hash(
|
|
140
|
-
{
|
|
141
|
-
"name" => name,
|
|
142
|
-
"path" => path,
|
|
143
|
-
"attributes" => attributes
|
|
144
|
-
}
|
|
145
|
-
)
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
1
|
+
module KeycloakAdmin
|
|
2
|
+
class GroupClient < 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 get(group_id)
|
|
10
|
+
response = execute_http do
|
|
11
|
+
RestClient::Resource.new(groups_url(group_id), @configuration.rest_client_options).get(headers)
|
|
12
|
+
end
|
|
13
|
+
GroupRepresentation.from_hash(JSON.parse(response))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def children(parent_id)
|
|
17
|
+
response = execute_http do
|
|
18
|
+
url = "#{groups_url(parent_id)}/children"
|
|
19
|
+
RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
|
|
20
|
+
end
|
|
21
|
+
JSON.parse(response).map { |group_as_hash| GroupRepresentation.from_hash(group_as_hash) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def list
|
|
25
|
+
search(nil)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def search(query)
|
|
29
|
+
derived_headers = case query
|
|
30
|
+
when String
|
|
31
|
+
headers.merge({params: { search: query }})
|
|
32
|
+
when Hash
|
|
33
|
+
headers.merge({params: query })
|
|
34
|
+
else
|
|
35
|
+
headers
|
|
36
|
+
end
|
|
37
|
+
response = execute_http do
|
|
38
|
+
RestClient::Resource.new(groups_url, @configuration.rest_client_options).get(derived_headers)
|
|
39
|
+
end
|
|
40
|
+
JSON.parse(response).map { |group_as_hash| GroupRepresentation.from_hash(group_as_hash) }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def create!(name, path = nil, attributes = {})
|
|
44
|
+
response = save(build(name, path, attributes))
|
|
45
|
+
created_id(response)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def save(group_representation)
|
|
49
|
+
execute_http do
|
|
50
|
+
payload = create_payload(group_representation)
|
|
51
|
+
if group_representation.id
|
|
52
|
+
RestClient::Resource.new(groups_url(group_representation.id), @configuration.rest_client_options).put(payload, headers)
|
|
53
|
+
else
|
|
54
|
+
RestClient::Resource.new(groups_url, @configuration.rest_client_options).post(payload, headers)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create_subgroup!(parent_id, name, attributes = {})
|
|
60
|
+
url = "#{groups_url(parent_id)}/children"
|
|
61
|
+
response = execute_http do
|
|
62
|
+
RestClient::Resource.new(url, @configuration.rest_client_options).post(
|
|
63
|
+
create_payload(build(name, nil, attributes)), headers
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
created_id(response)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def delete(group_id)
|
|
70
|
+
execute_http do
|
|
71
|
+
RestClient::Resource.new(groups_url(group_id), @configuration.rest_client_options).delete(headers)
|
|
72
|
+
end
|
|
73
|
+
true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def members(group_id, first=0, max=100)
|
|
77
|
+
url = "#{groups_url(group_id)}/members"
|
|
78
|
+
query = {first: first.try(:to_i), max: max.try(:to_i)}.compact
|
|
79
|
+
unless query.empty?
|
|
80
|
+
query_string = query.to_a.map { |e| "#{e[0]}=#{e[1]}" }.join("&")
|
|
81
|
+
url = "#{url}?#{query_string}"
|
|
82
|
+
end
|
|
83
|
+
response = execute_http do
|
|
84
|
+
RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
|
|
85
|
+
end
|
|
86
|
+
JSON.parse(response).map { |user_as_hash| UserRepresentation.from_hash(user_as_hash) }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Gets all realm-level roles for a group
|
|
90
|
+
def get_realm_level_roles(group_id)
|
|
91
|
+
url = "#{groups_url(group_id)}/role-mappings/realm"
|
|
92
|
+
response = execute_http do
|
|
93
|
+
RestClient::Resource.new(url, @configuration.rest_client_options).get(headers)
|
|
94
|
+
end
|
|
95
|
+
JSON.parse(response).map { |role_as_hash| RoleRepresentation.from_hash(role_as_hash) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Adds a realm-level role to a group via the role name
|
|
99
|
+
def add_realm_level_role_name!(group_id, role_name)
|
|
100
|
+
# creates a full role-representation object needed by the keycloak api to work
|
|
101
|
+
role_representation = RoleClient.new(@configuration, @realm_client).get(role_name)
|
|
102
|
+
url = "#{groups_url(group_id)}/role-mappings/realm"
|
|
103
|
+
response = execute_http do
|
|
104
|
+
RestClient::Resource.new(url, @configuration.rest_client_options).post(
|
|
105
|
+
create_payload([role_representation]), headers
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
role_representation
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Remove a realm-level role from a group by the role name
|
|
112
|
+
def remove_realm_level_role_name!(group_id, role_name)
|
|
113
|
+
role_representation = RoleClient.new(@configuration, @realm_client).get(role_name)
|
|
114
|
+
url = "#{groups_url(group_id)}/role-mappings/realm"
|
|
115
|
+
execute_http do
|
|
116
|
+
RestClient::Request.execute(
|
|
117
|
+
@configuration.rest_client_options.merge(
|
|
118
|
+
url:,
|
|
119
|
+
method: :delete,
|
|
120
|
+
payload: create_payload([role_representation]),
|
|
121
|
+
headers: headers
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
true
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def groups_url(id=nil)
|
|
129
|
+
if id
|
|
130
|
+
"#{@realm_client.realm_admin_url}/groups/#{id}"
|
|
131
|
+
else
|
|
132
|
+
"#{@realm_client.realm_admin_url}/groups"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
|
|
138
|
+
def build(name, path, attributes)
|
|
139
|
+
GroupRepresentation.from_hash(
|
|
140
|
+
{
|
|
141
|
+
"name" => name,
|
|
142
|
+
"path" => path,
|
|
143
|
+
"attributes" => attributes
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
module KeycloakAdmin
|
|
2
|
-
class IdentityProviderClient < 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 create(identity_provider_representation)
|
|
10
|
-
execute_http do
|
|
11
|
-
RestClient::Resource.new(identity_providers_url, @configuration.rest_client_options).post(
|
|
12
|
-
create_payload(identity_provider_representation), headers
|
|
13
|
-
)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def add_mapping(identity_provider_alias, identity_provider_mapping_representation)
|
|
18
|
-
execute_http do
|
|
19
|
-
RestClient::Resource.new(identity_provider_mappers_url(identity_provider_alias), @configuration.rest_client_options).post(
|
|
20
|
-
create_payload(identity_provider_mapping_representation), headers
|
|
21
|
-
)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def list
|
|
26
|
-
response = execute_http do
|
|
27
|
-
RestClient::Resource.new(identity_providers_url, @configuration.rest_client_options).get(headers)
|
|
28
|
-
end
|
|
29
|
-
JSON.parse(response).map { |provider_as_hash| IdentityProviderRepresentation.from_hash(provider_as_hash) }
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def get(internal_id_or_alias=nil)
|
|
33
|
-
response = execute_http do
|
|
34
|
-
RestClient::Resource.new(identity_providers_url(internal_id_or_alias), @configuration.rest_client_options).get(headers)
|
|
35
|
-
end
|
|
36
|
-
IdentityProviderRepresentation.from_hash(JSON.parse(response))
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def identity_providers_url(internal_id_or_alias=nil)
|
|
40
|
-
if internal_id_or_alias
|
|
41
|
-
"#{@realm_client.realm_admin_url}/identity-provider/instances/#{internal_id_or_alias}"
|
|
42
|
-
else
|
|
43
|
-
"#{@realm_client.realm_admin_url}/identity-provider/instances"
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def identity_provider_mappers_url(internal_id_or_alias)
|
|
48
|
-
"#{identity_providers_url(internal_id_or_alias)}/mappers"
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
1
|
+
module KeycloakAdmin
|
|
2
|
+
class IdentityProviderClient < 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 create(identity_provider_representation)
|
|
10
|
+
execute_http do
|
|
11
|
+
RestClient::Resource.new(identity_providers_url, @configuration.rest_client_options).post(
|
|
12
|
+
create_payload(identity_provider_representation), headers
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_mapping(identity_provider_alias, identity_provider_mapping_representation)
|
|
18
|
+
execute_http do
|
|
19
|
+
RestClient::Resource.new(identity_provider_mappers_url(identity_provider_alias), @configuration.rest_client_options).post(
|
|
20
|
+
create_payload(identity_provider_mapping_representation), headers
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def list
|
|
26
|
+
response = execute_http do
|
|
27
|
+
RestClient::Resource.new(identity_providers_url, @configuration.rest_client_options).get(headers)
|
|
28
|
+
end
|
|
29
|
+
JSON.parse(response).map { |provider_as_hash| IdentityProviderRepresentation.from_hash(provider_as_hash) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get(internal_id_or_alias=nil)
|
|
33
|
+
response = execute_http do
|
|
34
|
+
RestClient::Resource.new(identity_providers_url(internal_id_or_alias), @configuration.rest_client_options).get(headers)
|
|
35
|
+
end
|
|
36
|
+
IdentityProviderRepresentation.from_hash(JSON.parse(response))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def identity_providers_url(internal_id_or_alias=nil)
|
|
40
|
+
if internal_id_or_alias
|
|
41
|
+
"#{@realm_client.realm_admin_url}/identity-provider/instances/#{internal_id_or_alias}"
|
|
42
|
+
else
|
|
43
|
+
"#{@realm_client.realm_admin_url}/identity-provider/instances"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def identity_provider_mappers_url(internal_id_or_alias)
|
|
48
|
+
"#{identity_providers_url(internal_id_or_alias)}/mappers"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
module KeycloakAdmin
|
|
2
|
+
class OrganizationClient < 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
|
+
# This endpoint does not return members
|
|
10
|
+
def list(brief_representation=true, exact=nil, first=nil, max=nil, query=nil, search=nil)
|
|
11
|
+
response = execute_http do
|
|
12
|
+
RestClient::Resource.new(organizations_url_with_parameters(brief_representation, exact, first, max, query, search), @configuration.rest_client_options).get(headers)
|
|
13
|
+
end
|
|
14
|
+
JSON.parse(response).map { |organization_as_hash| OrganizationRepresentation.from_hash(organization_as_hash) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def count(exact=nil, query=nil, search=nil)
|
|
18
|
+
response = execute_http do
|
|
19
|
+
RestClient::Resource.new(count_url(exact, query, search), @configuration.rest_client_options).get(headers)
|
|
20
|
+
end
|
|
21
|
+
response.to_i
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def delete(organization_id)
|
|
25
|
+
execute_http do
|
|
26
|
+
RestClient::Resource.new(organization_url(organization_id), @configuration.rest_client_options).delete(headers)
|
|
27
|
+
end
|
|
28
|
+
true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def update(organization_representation)
|
|
32
|
+
execute_http do
|
|
33
|
+
RestClient::Resource.new(organization_url(organization_representation.id), @configuration.rest_client_options).put(
|
|
34
|
+
create_payload(organization_representation), headers
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
get(organization_representation.id)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def create!(name, alias_name, enabled, description, redirect_url=nil, domains=[], attributes={})
|
|
42
|
+
save(build(name, alias_name, enabled, description, redirect_url, domains, attributes))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# This operation does not associate members and identity providers
|
|
46
|
+
def save(organization_representation)
|
|
47
|
+
execute_http do
|
|
48
|
+
RestClient::Resource.new(organizations_url, @configuration.rest_client_options).post(
|
|
49
|
+
create_payload(organization_representation), headers
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def get(organization_id)
|
|
56
|
+
response = execute_http do
|
|
57
|
+
RestClient::Resource.new(organization_url(organization_id), @configuration.rest_client_options).get(headers)
|
|
58
|
+
end
|
|
59
|
+
OrganizationRepresentation.from_hash(JSON.parse(response))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def identity_providers(organization_id)
|
|
63
|
+
response = execute_http do
|
|
64
|
+
RestClient::Resource.new(identity_providers_url(organization_id), @configuration.rest_client_options).get(headers)
|
|
65
|
+
end
|
|
66
|
+
JSON.parse(response).map { |idp_as_hash| IdentityProviderRepresentation.from_hash(idp_as_hash) }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def get_identity_provider(organization_id, identity_provider_alias)
|
|
70
|
+
raise ArgumentError.new("identity_provider_alias must be defined") if identity_provider_alias.nil?
|
|
71
|
+
response = execute_http do
|
|
72
|
+
RestClient::Resource.new("#{identity_providers_url(organization_id)}/#{identity_provider_alias}", @configuration.rest_client_options).get(headers)
|
|
73
|
+
end
|
|
74
|
+
IdentityProviderRepresentation.from_hash(JSON.parse(response))
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def add_identity_provider(organization_id, identity_provider_alias)
|
|
78
|
+
raise ArgumentError.new("identity_provider_alias must be defined") if identity_provider_alias.nil?
|
|
79
|
+
execute_http do
|
|
80
|
+
RestClient::Resource.new(identity_providers_url(organization_id), @configuration.rest_client_options).post(identity_provider_alias, headers)
|
|
81
|
+
end
|
|
82
|
+
true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def delete_identity_provider(organization_id, identity_provider_alias)
|
|
86
|
+
execute_http do
|
|
87
|
+
RestClient::Resource.new(identity_provider_url(organization_id, identity_provider_alias), @configuration.rest_client_options).delete(headers)
|
|
88
|
+
end
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def members_count(organization_id)
|
|
93
|
+
response = execute_http do
|
|
94
|
+
RestClient::Resource.new(members_count_url(organization_id), @configuration.rest_client_options).get(headers)
|
|
95
|
+
end
|
|
96
|
+
response.to_i
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def members(organization_id, exact=nil, first=nil, max=nil, membership_type=nil, search=nil)
|
|
100
|
+
response = execute_http do
|
|
101
|
+
RestClient::Resource.new(members_url_with_query_parameters(organization_id, exact, first, max, membership_type, search), @configuration.rest_client_options).get(headers)
|
|
102
|
+
end
|
|
103
|
+
JSON.parse(response).map { |member_as_hash| MemberRepresentation.from_hash(member_as_hash) }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def invite_existing_user(organization_id, user_id)
|
|
107
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
|
108
|
+
execute_http do
|
|
109
|
+
RestClient::Resource.new(invite_existing_user_url(organization_id), @configuration.rest_client_options).post({id: user_id}, headers.merge(content_type: "application/x-www-form-urlencoded"))
|
|
110
|
+
end
|
|
111
|
+
true
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def invite_user(organization_id, email, first_name, last_name)
|
|
115
|
+
execute_http do
|
|
116
|
+
RestClient::Resource.new(invite_user_url(organization_id), @configuration.rest_client_options).post({
|
|
117
|
+
email: email,
|
|
118
|
+
firstName: first_name,
|
|
119
|
+
lastName: last_name
|
|
120
|
+
}, headers.merge(content_type: "application/x-www-form-urlencoded"))
|
|
121
|
+
end
|
|
122
|
+
true
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def add_member(organization_id, user_id)
|
|
126
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
|
127
|
+
execute_http do
|
|
128
|
+
RestClient::Resource.new(members_url(organization_id), @configuration.rest_client_options).post(user_id, headers)
|
|
129
|
+
end
|
|
130
|
+
true
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def delete_member(organization_id, member_id)
|
|
134
|
+
execute_http do
|
|
135
|
+
RestClient::Resource.new(member_url(organization_id, member_id), @configuration.rest_client_options).delete(headers)
|
|
136
|
+
end
|
|
137
|
+
true
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def get_member(organization_id, member_id)
|
|
141
|
+
response = execute_http do
|
|
142
|
+
RestClient::Resource.new(member_url(organization_id, member_id), @configuration.rest_client_options).get(headers)
|
|
143
|
+
end
|
|
144
|
+
MemberRepresentation.from_hash(JSON.parse(response))
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def associated_with_member(member_id, brief_representation=true)
|
|
148
|
+
response = execute_http do
|
|
149
|
+
RestClient::Resource.new(associated_with_member_url(member_id, brief_representation), @configuration.rest_client_options).get(headers)
|
|
150
|
+
end
|
|
151
|
+
JSON.parse(response).map { |organization_as_hash| OrganizationRepresentation.from_hash(organization_as_hash) }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def organizations_url
|
|
155
|
+
"#{@realm_client.realm_admin_url}/organizations"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def organization_url(organization_id)
|
|
159
|
+
raise ArgumentError.new("organization_id must be defined") if organization_id.nil?
|
|
160
|
+
"#{organizations_url}/#{organization_id}"
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def identity_providers_url(organization_id)
|
|
164
|
+
"#{organization_url(organization_id)}/identity-providers"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def identity_provider_url(organization_id, identity_provider_alias)
|
|
168
|
+
raise ArgumentError.new("identity_provider_alias must be defined") if identity_provider_alias.nil?
|
|
169
|
+
"#{identity_providers_url(organization_id)}/#{identity_provider_alias}"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def count_url(exact, query, search)
|
|
173
|
+
query_parameters = {exact: exact, q: query, search: search}.compact.to_a.map { |e| "#{e[0]}=#{e[1]}" }.join("&")
|
|
174
|
+
"#{organizations_url}/count?#{query_parameters}"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def organizations_url_with_parameters(brief_representation, exact, first, max, query, search)
|
|
178
|
+
query_parameters = {
|
|
179
|
+
briefRepresentation: brief_representation,
|
|
180
|
+
exact: exact,
|
|
181
|
+
first: first,
|
|
182
|
+
max: max,
|
|
183
|
+
q: query,
|
|
184
|
+
search: search
|
|
185
|
+
}.compact.to_a.map { |e| "#{e[0]}=#{e[1]}" }.join("&")
|
|
186
|
+
"#{organizations_url}?#{query_parameters}"
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def associated_with_member_url(member_id, brief_representation=true)
|
|
190
|
+
"#{organizations_url}/members/#{member_id}/organizations?briefRepresentation=#{brief_representation}"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def members_count_url(organization_id)
|
|
194
|
+
"#{organization_url(organization_id)}/members/count"
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def member_url(organization_id, member_id)
|
|
198
|
+
raise ArgumentError.new("member_id must be defined") if member_id.nil?
|
|
199
|
+
"#{organization_url(organization_id)}/members/#{member_id}"
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def invite_existing_user_url(organization_id)
|
|
203
|
+
"#{organization_url(organization_id)}/members/invite-existing-user"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def invite_user_url(organization_id)
|
|
207
|
+
"#{organization_url(organization_id)}/members/invite-user"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def members_url(organization_id)
|
|
211
|
+
"#{organization_url(organization_id)}/members"
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def members_url_with_query_parameters(organization_id, exact, first, max, membership_type, search)
|
|
215
|
+
query_parameters = {
|
|
216
|
+
exact: exact,
|
|
217
|
+
first: first,
|
|
218
|
+
max: max,
|
|
219
|
+
membershipType: membership_type,
|
|
220
|
+
search: search
|
|
221
|
+
}.compact.to_a.map { |e| "#{e[0]}=#{e[1]}" }.join("&")
|
|
222
|
+
"#{organization_url(organization_id)}/members?#{query_parameters}"
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def build(name, alias_name, enabled, description, redirect_url=nil, domains=[], attributes={})
|
|
226
|
+
unless domains.is_a?(Array)
|
|
227
|
+
raise ArgumentError.new("domains must be an Array, got #{new_domains.class}")
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
unless domains.all? { |domain| domain.is_a?(KeycloakAdmin::OrganizationDomainRepresentation) }
|
|
231
|
+
raise ArgumentError.new("All items in domains must be of type OrganizationDomainRepresentation")
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
organization = OrganizationRepresentation.new
|
|
235
|
+
organization.name = name
|
|
236
|
+
organization.alias = alias_name
|
|
237
|
+
organization.enabled = enabled
|
|
238
|
+
organization.description = description
|
|
239
|
+
organization.redirect_url = redirect_url
|
|
240
|
+
organization.domains = domains
|
|
241
|
+
organization.attributes = attributes
|
|
242
|
+
organization
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|