keycloak-admin 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e6887f2f57beb2339c74a7600a787b3f19cc5eaa171cbf43e94c1c899b75152
4
- data.tar.gz: 10639852645add2d77c73719f5ab315ccb0bf9f5e34a4e716b72a919c087d5a5
3
+ metadata.gz: 832e114e10e83ff18cfb5eaad1c157248da889b5041137ebf28fd30e610ee07d
4
+ data.tar.gz: e1151d727d5d6d8320db86024e7f10ad81f35a23dc13312aac065757e8664be5
5
5
  SHA512:
6
- metadata.gz: ea1fded8289d7d3cd89d816cf0949eed2aa07f2cab0bf86afb2a56e26d60dc30d218ce40ef51a4091e3d9c27369c7e4c8316997aa2a5fbed129c457728056de4
7
- data.tar.gz: 65301ff7dd19a5240bdd389f61e23615b8aeee911e08d833fac0c9102a27d5ed279c5bf7ba2adc7726fa12583c4b18ab2d297b38e17555beab1b47caa7b5fcdd
6
+ metadata.gz: eae1ed6f49db46eec2b4463acbd7cf164948aeba4e672f30703f8724bb70d9d441ff469dfd0fa81645821d5d0bfb19ed0bd7376407026fa1467b66c20069c006
7
+ data.tar.gz: 26818a04afbc95c05e878881d1b7c38e336f5e18a926995390b5e629786c395807276e6ef18c466e61f1600e65cbdd6b4ea6f80ff6e3af5a3ea070c77f18c655
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+
9
+ ## [1.0.1] - 2021-10-14
10
+
11
+ * List all `Identity Providers`
12
+ * Add Group on Users (thanks to @tomuench)
13
+ * Remove Group from Users (thanks to @tomuench)
14
+
8
15
  ## [1.0.0] - 2021-08-03
9
16
 
10
17
  * Add `totp` on Users
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keycloak-admin (1.0.0)
4
+ keycloak-admin (1.0.1)
5
5
  http-cookie (~> 1.0, >= 1.0.3)
6
6
  rest-client (~> 2.0)
7
7
 
data/README.md CHANGED
@@ -12,7 +12,7 @@ This gem *does not* require Rails.
12
12
  For example, using `bundle`, add this line to your Gemfile.
13
13
 
14
14
  ```ruby
15
- gem "keycloak-admin", "1.0.0"
15
+ gem "keycloak-admin", "1.0.1"
16
16
  ```
17
17
 
18
18
  ## Login
@@ -120,6 +120,9 @@ All options have a default value. However, all of them can be changed in your in
120
120
  * Get list of client role mappings for a user/group
121
121
  * Save client role mappings for a user/group
122
122
  * Save realm-level role mappings for a user/group
123
+ * Add a Group on a User
124
+ * Remove a Group from a User
125
+ * Get list of Identity Providers
123
126
  * Link/Unlink users to federated identity provider brokers
124
127
  * Execute actions emails
125
128
  * Send forgot passsword mail
@@ -367,6 +370,16 @@ group_id = "3a63b5c0-ef8a-47fd-86ed-b5fead18d9b8"
367
370
  KeycloakAdmin.realm("a_realm").group(group_id).role_mapper.save_realm_level(role_list)
368
371
  ```
369
372
 
373
+ ### Get list of identity providers
374
+
375
+ Note: This client requires the `realm-management.view-identity-providers` role.
376
+
377
+ Returns an array of `KeycloakAdmin::IdentityProviderRepresentation`.
378
+
379
+ ```ruby
380
+ KeycloakAdmin.realm("a_realm").identity_providers.list
381
+ ```
382
+
370
383
  ## How to execute library tests
371
384
 
372
385
  From the `keycloak-admin-api` directory:
@@ -374,4 +387,5 @@ From the `keycloak-admin-api` directory:
374
387
  ```
375
388
  $ docker build . -t keycloak-admin:test
376
389
  $ docker run -v `pwd`:/usr/src/app/ keycloak-admin:test bundle exec rspec spec
377
- ```
390
+ ```
391
+
@@ -0,0 +1,31 @@
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 list
10
+ response = execute_http do
11
+ RestClient::Resource.new(identity_providers_url, @configuration.rest_client_options).get(headers)
12
+ end
13
+ JSON.parse(response).map { |provider_as_hash| IdentityProviderRepresentation.from_hash(provider_as_hash) }
14
+ end
15
+
16
+ def get(internal_id_or_alias=nil)
17
+ response = execute_http do
18
+ RestClient::Resource.new(identity_providers_url, @configuration.rest_client_options).get(headers)
19
+ end
20
+ IdentityProviderRepresentation.from_hash(JSON.parse(response))
21
+ end
22
+
23
+ def identity_providers_url(internal_id_or_alias=nil)
24
+ if internal_id_or_alias
25
+ "#{@realm_client.realm_admin_url}/identity-provider/instances/#{internal_id_or_alias}"
26
+ else
27
+ "#{@realm_client.realm_admin_url}/identity-provider/instances"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -83,6 +83,10 @@ module KeycloakAdmin
83
83
  UserClient.new(@configuration, self)
84
84
  end
85
85
 
86
+ def identity_providers
87
+ IdentityProviderClient.new(@configuration, self)
88
+ end
89
+
86
90
  def user(user_id)
87
91
  UserResource.new(@configuration, self, user_id)
88
92
  end
@@ -31,6 +31,27 @@ module KeycloakAdmin
31
31
  )
32
32
  end
33
33
 
34
+ def add_group(user_id, group_id)
35
+ RestClient::Request.execute(
36
+ @configuration.rest_client_options.merge(
37
+ method: :put,
38
+ url: "#{users_url(user_id)}/groups/#{group_id}",
39
+ payload: {},
40
+ headers: headers
41
+ )
42
+ )
43
+ end
44
+
45
+ def remove_group(user_id, group_id)
46
+ RestClient::Request.execute(
47
+ @configuration.rest_client_options.merge(
48
+ method: :delete,
49
+ url: "#{users_url(user_id)}/groups/#{group_id}",
50
+ headers: headers
51
+ )
52
+ )
53
+ end
54
+
34
55
  def get(user_id)
35
56
  response = execute_http do
36
57
  RestClient::Resource.new(users_url(user_id), @configuration.rest_client_options).get(headers)
@@ -0,0 +1,67 @@
1
+ module KeycloakAdmin
2
+ class IdentityProviderRepresentation < Representation
3
+ attr_accessor :alias,
4
+ :display_name,
5
+ :internal_id,
6
+ :provider_id,
7
+ :enabled,
8
+ :update_profile_first_login_mode,
9
+ :trust_email,
10
+ :store_token,
11
+ :add_read_token_role_on_create,
12
+ :authenticate_by_default,
13
+ :link_only,
14
+ :first_broker_login_flow_alias,
15
+ :configuration
16
+
17
+ def self.from_hash(hash)
18
+ if hash.nil?
19
+ nil
20
+ else
21
+ new(
22
+ hash["alias"],
23
+ hash["displayName"],
24
+ hash["internalId"],
25
+ hash["providerId"],
26
+ hash["enabled"],
27
+ hash["updateProfileFirstLoginMode"],
28
+ hash["trustEmail"],
29
+ hash["storeToken"],
30
+ hash["addReadTokenRoleOnCreate"],
31
+ hash["authenticateByDefault"],
32
+ hash["linkOnly"],
33
+ hash["firstBrokerLoginFlowAlias"],
34
+ hash["config"]
35
+ )
36
+ end
37
+ end
38
+
39
+ def initialize(alias_name,
40
+ display_name,
41
+ internal_id,
42
+ provider_id,
43
+ enabled,
44
+ update_profile_first_login_mode,
45
+ trust_email,
46
+ store_token,
47
+ add_read_token_role_on_create,
48
+ authenticate_by_default,
49
+ link_only,
50
+ first_broker_login_flow_alias,
51
+ configuration)
52
+ @alias = alias_name
53
+ @display_name = display_name
54
+ @internal_id = internal_id
55
+ @provider_id = provider_id
56
+ @enabled = enabled
57
+ @update_profile_first_login_mode = update_profile_first_login_mode
58
+ @trust_email = trust_email
59
+ @store_token = store_token
60
+ @add_read_token_role_on_create = add_read_token_role_on_create
61
+ @authenticate_by_default = authenticate_by_default
62
+ @link_only = link_only
63
+ @first_broker_login_flow_alias = first_broker_login_flow_alias
64
+ @configuration = configuration
65
+ end
66
+ end
67
+ end
@@ -1,3 +1,3 @@
1
1
  module KeycloakAdmin
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -10,6 +10,7 @@ require_relative "keycloak-admin/client/role_client"
10
10
  require_relative "keycloak-admin/client/role_mapper_client"
11
11
  require_relative "keycloak-admin/client/token_client"
12
12
  require_relative "keycloak-admin/client/user_client"
13
+ require_relative "keycloak-admin/client/identity_provider_client"
13
14
  require_relative "keycloak-admin/client/configurable_token_client"
14
15
  require_relative "keycloak-admin/representation/camel_json"
15
16
  require_relative "keycloak-admin/representation/representation"
@@ -23,6 +24,7 @@ require_relative "keycloak-admin/representation/realm_representation"
23
24
  require_relative "keycloak-admin/representation/role_representation"
24
25
  require_relative "keycloak-admin/representation/federated_identity_representation"
25
26
  require_relative "keycloak-admin/representation/user_representation"
27
+ require_relative "keycloak-admin/representation/identity_provider_representation"
26
28
  require_relative "keycloak-admin/resource/base_role_containing_resource"
27
29
  require_relative "keycloak-admin/resource/group_resource"
28
30
  require_relative "keycloak-admin/resource/user_resource"
@@ -0,0 +1,92 @@
1
+ RSpec.describe KeycloakAdmin::IdentityProviderClient do
2
+ describe "#identity_providers_url" do
3
+ let(:realm_name) { "valid-realm" }
4
+ let(:provider_id) { nil }
5
+
6
+ before(:each) do
7
+ @built_url = KeycloakAdmin.realm(realm_name).identity_providers.identity_providers_url(provider_id)
8
+ end
9
+
10
+ context "when provider_id is not defined" do
11
+ let(:provider_id) { nil }
12
+ it "returns a proper url without provider id" do
13
+ expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/identity-provider/instances"
14
+ end
15
+ end
16
+
17
+ context "when provider_id is defined" do
18
+ let(:provider_id) { "95985b21-d884-4bbd-b852-cb8cd365afc2" }
19
+ it "returns a proper url with the provider id" do
20
+ expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/identity-provider/instances/95985b21-d884-4bbd-b852-cb8cd365afc2"
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#list" do
26
+ let(:realm_name) { "valid-realm" }
27
+ let(:json_response) do
28
+ <<-JSON
29
+ [
30
+ {
31
+ "alias": "acme",
32
+ "displayName": "ACME",
33
+ "internalId": "20fea77e-ae3d-411e-9467-2b3a20cd3e6d",
34
+ "providerId": "saml",
35
+ "enabled": true,
36
+ "updateProfileFirstLoginMode": "on",
37
+ "trustEmail": true,
38
+ "storeToken": false,
39
+ "addReadTokenRoleOnCreate": false,
40
+ "authenticateByDefault": false,
41
+ "linkOnly": false,
42
+ "firstBrokerLoginFlowAlias": "first broker login",
43
+ "config": {
44
+ "hideOnLoginPage": "",
45
+ "validateSignature": "true",
46
+ "samlXmlKeyNameTranformer": "KEY_ID",
47
+ "signingCertificate": "",
48
+ "postBindingLogout": "false",
49
+ "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
50
+ "postBindingResponse": "true",
51
+ "backchannelSupported": "",
52
+ "signatureAlgorithm": "RSA_SHA256",
53
+ "wantAssertionsEncrypted": "false",
54
+ "xmlSigKeyInfoKeyNameTransformer": "CERT_SUBJECT",
55
+ "useJwksUrl": "true",
56
+ "wantAssertionsSigned": "true",
57
+ "postBindingAuthnRequest": "true",
58
+ "forceAuthn": "",
59
+ "wantAuthnRequestsSigned": "true",
60
+ "singleSignOnServiceUrl": "https://login.microsoftonline.com/test/saml2",
61
+ "addExtensionsElementWithKeyInfo": "false"
62
+ }
63
+ }
64
+ ]
65
+ JSON
66
+ end
67
+ before(:each) do
68
+ @identity_provider_client = KeycloakAdmin.realm(realm_name).identity_providers
69
+
70
+ stub_token_client
71
+ allow_any_instance_of(RestClient::Resource).to receive(:get).and_return json_response
72
+ end
73
+
74
+ it "lists identity providers" do
75
+ identity_providers = @identity_provider_client.list
76
+ expect(identity_providers.length).to eq 1
77
+ expect(identity_providers[0].alias).to eq "acme"
78
+ end
79
+
80
+ it "passes rest client options" do
81
+ rest_client_options = {verify_ssl: OpenSSL::SSL::VERIFY_NONE}
82
+ allow_any_instance_of(KeycloakAdmin::Configuration).to receive(:rest_client_options).and_return rest_client_options
83
+
84
+ expect(RestClient::Resource).to receive(:new).with(
85
+ "http://auth.service.io/auth/admin/realms/valid-realm/identity-provider/instances", rest_client_options).and_call_original
86
+
87
+ identity_providers = @identity_provider_client.list
88
+ expect(identity_providers.length).to eq 1
89
+ expect(identity_providers[0].alias).to eq "acme"
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,113 @@
1
+ RSpec.describe KeycloakAdmin::IdentityProviderRepresentation do
2
+ describe "#from_hash" do
3
+ before(:each) do
4
+ json = <<-JSON
5
+ {
6
+ "alias": "acme",
7
+ "displayName": "ACME",
8
+ "internalId": "20fea77e-ae3d-411e-9467-2b3a20cd3e6d",
9
+ "providerId": "saml",
10
+ "enabled": true,
11
+ "updateProfileFirstLoginMode": "on",
12
+ "trustEmail": true,
13
+ "storeToken": false,
14
+ "addReadTokenRoleOnCreate": false,
15
+ "authenticateByDefault": false,
16
+ "linkOnly": false,
17
+ "firstBrokerLoginFlowAlias": "first broker login",
18
+ "config": {
19
+ "hideOnLoginPage": "",
20
+ "validateSignature": "true",
21
+ "samlXmlKeyNameTranformer": "KEY_ID",
22
+ "signingCertificate": "",
23
+ "postBindingLogout": "false",
24
+ "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
25
+ "postBindingResponse": "true",
26
+ "backchannelSupported": "",
27
+ "signatureAlgorithm": "RSA_SHA256",
28
+ "wantAssertionsEncrypted": "false",
29
+ "xmlSigKeyInfoKeyNameTransformer": "CERT_SUBJECT",
30
+ "useJwksUrl": "true",
31
+ "wantAssertionsSigned": "true",
32
+ "postBindingAuthnRequest": "true",
33
+ "forceAuthn": "",
34
+ "wantAuthnRequestsSigned": "true",
35
+ "singleSignOnServiceUrl": "https://login.microsoftonline.com/test/saml2",
36
+ "addExtensionsElementWithKeyInfo": "false"
37
+ }
38
+ }
39
+ JSON
40
+ payload = JSON.parse(json)
41
+ @identity_provider = KeycloakAdmin::IdentityProviderRepresentation.from_hash(payload)
42
+ end
43
+
44
+ it "parses the alias" do
45
+ expect(@identity_provider.alias).to eq "acme"
46
+ end
47
+
48
+ it "parses the display name" do
49
+ expect(@identity_provider.display_name).to eq "ACME"
50
+ end
51
+
52
+ it "parses the internalId" do
53
+ expect(@identity_provider.internal_id).to eq "20fea77e-ae3d-411e-9467-2b3a20cd3e6d"
54
+ end
55
+
56
+ it "parses the provider id" do
57
+ expect(@identity_provider.provider_id).to eq "saml"
58
+ end
59
+
60
+ it "parses the enabled" do
61
+ expect(@identity_provider.enabled).to eq true
62
+ end
63
+
64
+ it "parses the update_profile_first_login_mode" do
65
+ expect(@identity_provider.update_profile_first_login_mode).to eq "on"
66
+ end
67
+
68
+ it "parses the trust_email" do
69
+ expect(@identity_provider.trust_email).to eq true
70
+ end
71
+
72
+ it "parses the store_token" do
73
+ expect(@identity_provider.store_token).to eq false
74
+ end
75
+
76
+ it "parses the add_read_token_role_on_create" do
77
+ expect(@identity_provider.add_read_token_role_on_create).to eq false
78
+ end
79
+
80
+ it "parses the authenticate_by_default" do
81
+ expect(@identity_provider.authenticate_by_default).to eq false
82
+ end
83
+
84
+ it "parses the link_only" do
85
+ expect(@identity_provider.link_only).to eq false
86
+ end
87
+
88
+ it "parses the first_broker_login_flow_alias" do
89
+ expect(@identity_provider.first_broker_login_flow_alias).to eq "first broker login"
90
+ end
91
+
92
+ it "parses the configuration as a hash with camel properties" do
93
+ expect(@identity_provider.configuration["hideOnLoginPage"]).to eq ""
94
+ expect(@identity_provider.configuration["validateSignature"]).to eq "true"
95
+ expect(@identity_provider.configuration["samlXmlKeyNameTranformer"]).to eq "KEY_ID"
96
+ expect(@identity_provider.configuration["signingCertificate"]).to eq ""
97
+ expect(@identity_provider.configuration["postBindingLogout"]).to eq "false"
98
+ expect(@identity_provider.configuration["nameIDPolicyFormat"]).to eq "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
99
+ expect(@identity_provider.configuration["postBindingResponse"]).to eq "true"
100
+ expect(@identity_provider.configuration["backchannelSupported"]).to eq ""
101
+ expect(@identity_provider.configuration["signatureAlgorithm"]).to eq "RSA_SHA256"
102
+ expect(@identity_provider.configuration["wantAssertionsEncrypted"]).to eq "false"
103
+ expect(@identity_provider.configuration["xmlSigKeyInfoKeyNameTransformer"]).to eq "CERT_SUBJECT"
104
+ expect(@identity_provider.configuration["useJwksUrl"]).to eq "true"
105
+ expect(@identity_provider.configuration["wantAssertionsSigned"]).to eq "true"
106
+ expect(@identity_provider.configuration["postBindingAuthnRequest"]).to eq "true"
107
+ expect(@identity_provider.configuration["forceAuthn"]).to eq ""
108
+ expect(@identity_provider.configuration["wantAuthnRequestsSigned"]).to eq "true"
109
+ expect(@identity_provider.configuration["singleSignOnServiceUrl"]).to eq "https://login.microsoftonline.com/test/saml2"
110
+ expect(@identity_provider.configuration["addExtensionsElementWithKeyInfo"]).to eq "false"
111
+ end
112
+ end
113
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keycloak-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorent Lempereur
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-03 00:00:00.000000000 Z
11
+ date: 2021-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-cookie
@@ -94,6 +94,7 @@ files:
94
94
  - lib/keycloak-admin/client/client_role_mappings_client.rb
95
95
  - lib/keycloak-admin/client/configurable_token_client.rb
96
96
  - lib/keycloak-admin/client/group_client.rb
97
+ - lib/keycloak-admin/client/identity_provider_client.rb
97
98
  - lib/keycloak-admin/client/realm_client.rb
98
99
  - lib/keycloak-admin/client/role_client.rb
99
100
  - lib/keycloak-admin/client/role_mapper_client.rb
@@ -105,6 +106,7 @@ files:
105
106
  - lib/keycloak-admin/representation/credential_representation.rb
106
107
  - lib/keycloak-admin/representation/federated_identity_representation.rb
107
108
  - lib/keycloak-admin/representation/group_representation.rb
109
+ - lib/keycloak-admin/representation/identity_provider_representation.rb
108
110
  - lib/keycloak-admin/representation/impersonation_redirection_representation.rb
109
111
  - lib/keycloak-admin/representation/impersonation_representation.rb
110
112
  - lib/keycloak-admin/representation/realm_representation.rb
@@ -121,12 +123,14 @@ files:
121
123
  - spec/client/client_spec.rb
122
124
  - spec/client/configurable_token_client_spec.rb
123
125
  - spec/client/group_client_spec.rb
126
+ - spec/client/identity_provider_client_spec.rb
124
127
  - spec/client/realm_client_spec.rb
125
128
  - spec/client/role_client_spec.rb
126
129
  - spec/client/role_mapper_client_spec.rb
127
130
  - spec/client/token_client_spec.rb
128
131
  - spec/client/user_client_spec.rb
129
132
  - spec/configuration_spec.rb
133
+ - spec/representation/identity_provider_representation_spec.rb
130
134
  - spec/representation/impersonation_representation_spec.rb
131
135
  - spec/representation/user_representation_spec.rb
132
136
  - spec/resource/group_resource_spec.rb
@@ -136,7 +140,7 @@ homepage: https://github.com/looorent/keycloak-admin-ruby
136
140
  licenses:
137
141
  - MIT
138
142
  metadata: {}
139
- post_install_message:
143
+ post_install_message:
140
144
  rdoc_options: []
141
145
  require_paths:
142
146
  - lib
@@ -151,8 +155,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
155
  - !ruby/object:Gem::Version
152
156
  version: '0'
153
157
  requirements: []
154
- rubygems_version: 3.0.3
155
- signing_key:
158
+ rubygems_version: 3.2.3
159
+ signing_key:
156
160
  specification_version: 4
157
161
  summary: Keycloak Admin REST API client written in Ruby
158
162
  test_files: []