keycloak-admin 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +40 -4
  4. data/keycloak-admin.gemspec +14 -6
  5. data/lib/keycloak-admin/client/client.rb +22 -10
  6. data/lib/keycloak-admin/client/client_authz_permission_client.rb +1 -1
  7. data/lib/keycloak-admin/client/client_authz_policy_client.rb +1 -1
  8. data/lib/keycloak-admin/client/client_authz_resource_client.rb +1 -1
  9. data/lib/keycloak-admin/client/client_authz_scope_client.rb +1 -1
  10. data/lib/keycloak-admin/client/group_client.rb +2 -5
  11. data/lib/keycloak-admin/client/organization_client.rb +7 -7
  12. data/lib/keycloak-admin/client/user_client.rb +8 -4
  13. data/lib/keycloak-admin/error.rb +62 -0
  14. data/lib/keycloak-admin/version.rb +1 -1
  15. data/lib/keycloak-admin.rb +1 -0
  16. metadata +21 -56
  17. data/.github/workflows/Dockerfile +0 -24
  18. data/.github/workflows/ci.yml +0 -94
  19. data/.github/workflows/release.yml +0 -112
  20. data/.gitignore +0 -10
  21. data/.rspec +0 -2
  22. data/Dockerfile +0 -13
  23. data/Gemfile +0 -3
  24. data/Gemfile.lock +0 -54
  25. data/Rakefile +0 -6
  26. data/bin/console +0 -9
  27. data/spec/client/attack_detection_client_spec.rb +0 -102
  28. data/spec/client/client_authz_permission_client_spec.rb +0 -170
  29. data/spec/client/client_authz_policy_client_spec.rb +0 -170
  30. data/spec/client/client_authz_resource_client_spec.rb +0 -150
  31. data/spec/client/client_authz_scope_client_spec.rb +0 -134
  32. data/spec/client/client_client_spec.rb +0 -133
  33. data/spec/client/client_role_mappings_client_spec.rb +0 -83
  34. data/spec/client/client_scope_client_spec.rb +0 -220
  35. data/spec/client/client_scope_protocol_mapper_client_spec.rb +0 -230
  36. data/spec/client/client_spec.rb +0 -101
  37. data/spec/client/configurable_token_client_spec.rb +0 -34
  38. data/spec/client/group_client_spec.rb +0 -328
  39. data/spec/client/identity_provider_client_spec.rb +0 -92
  40. data/spec/client/organization_client_spec.rb +0 -595
  41. data/spec/client/realm_client_spec.rb +0 -155
  42. data/spec/client/resource_spec.rb +0 -223
  43. data/spec/client/response_spec.rb +0 -68
  44. data/spec/client/role_client_spec.rb +0 -79
  45. data/spec/client/role_mapper_client_spec.rb +0 -113
  46. data/spec/client/token_client_spec.rb +0 -68
  47. data/spec/client/user_client_spec.rb +0 -418
  48. data/spec/configuration_spec.rb +0 -150
  49. data/spec/gemspec_spec.rb +0 -25
  50. data/spec/integration/client_authorization_spec.rb +0 -93
  51. data/spec/representation/attack_detection_representation_spec.rb +0 -16
  52. data/spec/representation/client_authz_permission_representation_spec.rb +0 -52
  53. data/spec/representation/client_authz_policy_representation_spec.rb +0 -47
  54. data/spec/representation/client_authz_resource_representation_spec.rb +0 -33
  55. data/spec/representation/client_authz_scope_representation_spec.rb +0 -19
  56. data/spec/representation/client_representation_spec.rb +0 -119
  57. data/spec/representation/client_scope_representation_spec.rb +0 -125
  58. data/spec/representation/credential_representation_spec.rb +0 -68
  59. data/spec/representation/group_representation_spec.rb +0 -22
  60. data/spec/representation/identity_provider_mapper_representation_spec.rb +0 -24
  61. data/spec/representation/identity_provider_representation_spec.rb +0 -113
  62. data/spec/representation/impersonation_representation_spec.rb +0 -163
  63. data/spec/representation/organization_representation_spec.rb +0 -64
  64. data/spec/representation/protocol_mapper_representation_spec.rb +0 -57
  65. data/spec/representation/role_representation_spec.rb +0 -37
  66. data/spec/representation/session_representation_spec.rb +0 -16
  67. data/spec/representation/user_representation_spec.rb +0 -15
  68. data/spec/resource/group_resource_spec.rb +0 -14
  69. data/spec/resource/user_resource_spec.rb +0 -14
  70. data/spec/spec_helper.rb +0 -36
@@ -1,93 +0,0 @@
1
- RSpec.describe 'ClientAuthorization' do
2
-
3
- before(:each) do
4
- skip("This test requires to be run in a Github action.") unless ENV["GITHUB_ACTIONS"]
5
-
6
- KeycloakAdmin.configure do |config|
7
- config.use_service_account = false
8
- config.server_url = "http://localhost:8080/"
9
- config.client_id = "admin-cli"
10
- config.client_realm_name = "master"
11
- config.username = "admin"
12
- config.password = "admin"
13
- config.faraday_options = { request: { timeout: 5 }, ssl: { verify: false } }
14
- end
15
- end
16
-
17
- after(:each) do
18
- configure
19
- end
20
-
21
- describe "ClientAuthorization Suite" do
22
- it do
23
- realm_name = "dummy"
24
-
25
- client = KeycloakAdmin.realm(realm_name).clients.find_by_client_id("dummy-client")
26
- client.authorization_services_enabled = true
27
- KeycloakAdmin.realm(realm_name).clients.update(client)
28
-
29
- expect(KeycloakAdmin.realm(realm_name).authz_scopes(client.id).list.size).to eql(0)
30
- expect(KeycloakAdmin.realm(realm_name).authz_resources(client.id).list.size).to eql(0)
31
- expect(KeycloakAdmin.realm(realm_name).authz_policies(client.id, 'role').list.size).to eql(0)
32
-
33
- realm_role = KeycloakAdmin.realm(realm_name).roles.get("default-roles-dummy")
34
-
35
- scope_1 = KeycloakAdmin.realm(realm_name).authz_scopes(client.id).create!("POST_1", "POST 1 scope", "http://asdas")
36
- scope_2 = KeycloakAdmin.realm(realm_name).authz_scopes(client.id).create!("POST_2", "POST 2 scope", "http://asdas")
37
- expect(KeycloakAdmin.realm(realm_name).authz_scopes(client.id).search("POST").first.name).to eql("POST_1")
38
- expect(KeycloakAdmin.realm(realm_name).authz_scopes(client.id).get(scope_1.id).name).to eql("POST_1")
39
-
40
- resource = KeycloakAdmin.realm(realm_name).authz_resources(client.id).create!("Dummy Resource", "type", ["/asdf/*", "/tmp/"], true, "display_name", [], {"a": ["b", "c"]})
41
-
42
- expect(KeycloakAdmin.realm(realm_name).authz_resources(client.id).find_by("Dummy Resource", "", "", "", "").first.name).to eql("Dummy Resource")
43
- expect(KeycloakAdmin.realm(realm_name).authz_resources(client.id).find_by("", "type", "", "", "").first.name).to eql("Dummy Resource")
44
-
45
- expect(KeycloakAdmin.realm(realm_name).authz_resources(client.id).get(resource.id).scopes.count).to eql(0)
46
- expect(KeycloakAdmin.realm(realm_name).authz_resources(client.id).get(resource.id).uris.count).to eql(2)
47
- KeycloakAdmin.realm(realm_name).authz_resources(client.id).update(resource.id,
48
- {
49
- "name": "Dummy Resource",
50
- "type": "type",
51
- "owner_managed_access": true,
52
- "display_name": "display_name",
53
- "attributes": {"a":["b","c"]},
54
- "uris": [ "/asdf/*" , "/tmp/45" ],
55
- "scopes":[
56
- {name: scope_1.name},{name: scope_2.name}
57
- ],
58
- "icon_uri": "https://icon.ico"
59
- }
60
- )
61
-
62
- expect(KeycloakAdmin.realm(realm_name).authz_resources(client.id).get(resource.id).scopes.count).to eql(2)
63
-
64
- policy = KeycloakAdmin.realm(realm_name).authz_policies(client.id, 'role').create!("Policy 1", "description", "role", "POSITIVE", "UNANIMOUS", true, [{id: realm_role.id, required: true}])
65
- expect(KeycloakAdmin.realm(realm_name).authz_policies(client.id, 'role').find_by("Policy 1", "role").first.name).to eql("Policy 1")
66
- expect(KeycloakAdmin.realm(realm_name).authz_policies(client.id, 'role').get(policy.id).name).to eql("Policy 1")
67
- scope_permission = KeycloakAdmin.realm(realm_name).authz_permissions(client.id, :scope).create!("Dummy Scope Permission", "scope description", "UNANIMOUS", "POSITIVE", [resource.id], [policy.id], [scope_1.id, scope_2.id], "")
68
- resource_permission = KeycloakAdmin.realm(realm_name).authz_permissions(client.id, :resource).create!("Dummy Resource Permission", "resource description", "UNANIMOUS", "POSITIVE", [resource.id], [policy.id], nil, "")
69
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "", resource.id).list.size).to eql(2)
70
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "resource").get(resource_permission.id).name).to eql("Dummy Resource Permission")
71
- expect(KeycloakAdmin.realm(realm_name).authz_scopes(client.id, resource.id).list.size).to eql(2)
72
-
73
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, 'scope').list.size).to eql(2)
74
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, 'resource').list.size).to eql(2)
75
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "resource").find_by(resource_permission.name, nil).first.name).to eql("Dummy Resource Permission")
76
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "resource").find_by(resource_permission.name, resource.id).first.name).to eql("Dummy Resource Permission")
77
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "scope").find_by(scope_permission.name, resource.id).first.name).to eql("Dummy Scope Permission")
78
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "scope").find_by(scope_permission.name, resource.id, "POST_1").first.name).to eql("Dummy Scope Permission")
79
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "resource").find_by(nil, resource.id).first.name).to eql("Dummy Resource Permission")
80
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "scope").find_by(nil, resource.id).first.name).to eql("Dummy Scope Permission")
81
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "scope").find_by(nil, resource.id, "POST_1").first.name).to eql("Dummy Scope Permission")
82
- expect(KeycloakAdmin.realm(realm_name).authz_permissions(client.id, "scope").find_by(scope_permission.name, nil).first.name).to eql("Dummy Scope Permission")
83
-
84
- KeycloakAdmin.realm(realm_name).authz_permissions(client.id, 'scope').delete(scope_permission.id)
85
- KeycloakAdmin.realm(realm_name).authz_permissions(client.id, 'resource').delete(resource_permission.id)
86
- KeycloakAdmin.realm(realm_name).authz_policies(client.id, 'role').delete(policy.id)
87
- KeycloakAdmin.realm(realm_name).authz_resources(client.id).delete(resource.id)
88
- KeycloakAdmin.realm(realm_name).authz_scopes(client.id).delete(scope_1.id)
89
- KeycloakAdmin.realm(realm_name).authz_scopes(client.id).delete(scope_2.id)
90
-
91
- end
92
- end
93
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe KeycloakAdmin::AttackDetectionRepresentation do
4
- describe '.from_hash' do
5
- it 'converts json response to class structure' do
6
- rep = described_class.from_hash({
7
- 'numFailures' => 2,
8
- 'disabled' => true,
9
- 'lastIPFailure' => 12345,
10
- 'last_failure' => 12345678
11
- })
12
- expect(rep.num_failures).to eq 2
13
- expect(rep).to be_a described_class
14
- end
15
- end
16
- end
@@ -1,52 +0,0 @@
1
- RSpec.describe KeycloakAdmin::ClientAuthzPermissionRepresentation do
2
- describe '.from_hash, #resource based permission' do
3
- it 'converts json response to class structure' do
4
- rep = described_class.from_hash({
5
- "id" => "e9e3bc49-fe11-4287-b6fc-fa8be4930ffa",
6
- "resources" => ["4f55e984-d1ec-405c-a25c-1387f88acd5c"],
7
- "policies" => ["e9e3bc49-fe11-4287-b6fc-fa8be4930ffa"],
8
- "name" => "delme policy",
9
- "description" => "Delme policy description",
10
- "decisionStrategy" => "UNANIMOUS",
11
- "resourceType" => ""
12
- })
13
- expect(rep.id).to eq "e9e3bc49-fe11-4287-b6fc-fa8be4930ffa"
14
- expect(rep.resources).to eq ["4f55e984-d1ec-405c-a25c-1387f88acd5c"]
15
- expect(rep.policies).to eq ["e9e3bc49-fe11-4287-b6fc-fa8be4930ffa"]
16
- expect(rep.name).to eq "delme policy"
17
- expect(rep.description).to eq "Delme policy description"
18
- expect(rep.decision_strategy).to eq "UNANIMOUS"
19
- expect(rep.resource_type).to eq ""
20
- expect(rep).to be_a described_class
21
- end
22
- end
23
-
24
- describe '.from_hash, #scope based permission' do
25
- it 'converts json response to class structure' do
26
- rep = described_class.from_hash(
27
-
28
- { "id" => "4d762e5d-bf3d-4641-8f94-97e8a1869d1d",
29
- "name" => "permission name",
30
- "description" => "permission description",
31
- "type" => "scope",
32
- "policies" => ["e9e3bc49-fe11-4287-b6fc-fa8be4930ffa"],
33
- "resources" => ["4f55e984-d1ec-405c-a25c-1387f88acd5c"],
34
- "scopes" => ["7c4809c5-33b6-4668-a318-19b302214d20"],
35
- "logic" => "POSITIVE",
36
- "decisionStrategy" => "UNANIMOUS"
37
- })
38
- expect(rep.id).to eq "4d762e5d-bf3d-4641-8f94-97e8a1869d1d"
39
- expect(rep.resources).to eq ["4f55e984-d1ec-405c-a25c-1387f88acd5c"]
40
- expect(rep.policies).to eq ["e9e3bc49-fe11-4287-b6fc-fa8be4930ffa"]
41
- expect(rep.scopes).to eq ["7c4809c5-33b6-4668-a318-19b302214d20"]
42
- expect(rep.name).to eq "permission name"
43
- expect(rep.description).to eq "permission description"
44
- expect(rep.decision_strategy).to eq "UNANIMOUS"
45
- expect(rep.logic).to eq "POSITIVE"
46
- expect(rep.type).to eq "scope"
47
- expect(rep.resource_type).to eq nil
48
- expect(rep).to be_a described_class
49
- end
50
- end
51
-
52
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe KeycloakAdmin::ClientAuthzPolicyRepresentation do
4
- let(:realm_name) { "valid-realm" }
5
- let(:client_id) { "valid-client-id" }
6
- let(:policy_id) { "valid-policy-id" }
7
- let(:role_id) { "valid-role-id" }
8
- let(:role_name) { "valid-role-name" }
9
- let(:policy_name) { "valid-policy-name" }
10
- let(:policy_description) { "valid-policy-description" }
11
- let(:policy_type) { "role" }
12
- let(:policy_logic) { "POSITIVE" }
13
- let(:policy_decision_strategy) { "UNANIMOUS" }
14
- let(:policy) do
15
- {
16
- "id": policy_id,
17
- "name": policy_name,
18
- "description": policy_description,
19
- "type": policy_type,
20
- "logic": policy_logic,
21
- "decisionStrategy": policy_decision_strategy,
22
- "roles": [{ "id": role_id, "required": true }]
23
- }
24
- end
25
- let(:client_authz_policy) { KeycloakAdmin.realm(realm_name).authz_policies(client_id, 'role') }
26
-
27
- before(:each) do
28
- stub_token_client
29
- end
30
-
31
- describe "#create!" do
32
- before(:each) do
33
- allow_any_instance_of(KeycloakAdmin::Resource).to receive(:post).and_return policy.to_json
34
- end
35
-
36
- it "returns created authz policy" do
37
- response = client_authz_policy.create!(policy_name, policy_description, policy_type, policy_logic, policy_decision_strategy, true, [{ id: role_id, required: true }])
38
- expect(response.id).to eq policy_id
39
- expect(response.name).to eq policy_name
40
- expect(response.description).to eq policy_description
41
- expect(response.type).to eq policy_type
42
- expect(response.logic).to eq policy_logic
43
- expect(response.decision_strategy).to eq policy_decision_strategy
44
- expect(response.roles).to eq [{ "id" => role_id, "required" => true }]
45
- end
46
- end
47
- end
@@ -1,33 +0,0 @@
1
- RSpec.describe KeycloakAdmin::ClientAuthzResourceRepresentation do
2
- describe '.from_hash' do
3
- it 'converts json response to class structure' do
4
- rep = described_class.from_hash({
5
- "name" => "Default Resource",
6
- "type" => "urn:delme-client-id:resources:default",
7
- "owner" => {
8
- "id" => "d259b451-371b-432a-a526-3508f3a36f3b",
9
- "name" => "delme-client-id"
10
- },
11
- "ownerManagedAccess" => true,
12
- "displayName" => "Display Name",
13
- "attributes" => { "a" => ["b"]},
14
- "_id" => "385966a2-14b9-4cc4-9539-5f2fe1008222",
15
- "uris" => ["/*"],
16
- "scopes" => [{"id"=>"c0779ce3-0900-4ea3-b1d6-b23e1f19c662",
17
- "name" => "GET",
18
- "iconUri" => "http=>//asdfasdf"}],
19
- "icon_uri" => "http://icon"
20
- })
21
- expect(rep.id).to eq "385966a2-14b9-4cc4-9539-5f2fe1008222"
22
- expect(rep.name).to eq "Default Resource"
23
- expect(rep.type).to eq "urn:delme-client-id:resources:default"
24
- expect(rep.uris).to eq ["/*"]
25
- expect(rep.owner_managed_access).to eq true
26
- expect(rep.attributes).to eq({ :"a" => ["b"]})
27
- expect(rep.display_name).to eq "Display Name"
28
- expect(rep.scopes[0].id).to eq "c0779ce3-0900-4ea3-b1d6-b23e1f19c662"
29
- expect(rep.scopes[0].name).to eq "GET"
30
- expect(rep).to be_a described_class
31
- end
32
- end
33
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe KeycloakAdmin::ClientAuthzScopeRepresentation do
4
- describe '.from_hash' do
5
- it 'converts json response to class structure' do
6
- rep = described_class.from_hash({
7
- "id" =>"c0779ce3-0900-4ea3-b1d6-b23e1f19c662",
8
- "name" => "GET",
9
- "iconUri" => "http://asdfasdf/image.png",
10
- "displayName" => "GET authz scope"
11
- })
12
- expect(rep.id).to eq "c0779ce3-0900-4ea3-b1d6-b23e1f19c662"
13
- expect(rep.name).to eq "GET"
14
- expect(rep.icon_uri).to eq "http://asdfasdf/image.png"
15
- expect(rep.display_name).to eq "GET authz scope"
16
- expect(rep).to be_a described_class
17
- end
18
- end
19
- end
@@ -1,119 +0,0 @@
1
- RSpec.describe KeycloakAdmin::ClientRepresentation do
2
- describe "#to_json" do
3
- before(:each) do
4
- @client = KeycloakAdmin::ClientRepresentation.from_hash(
5
- {
6
- "id" => "c9104bc7-04d8-4348-b4df-8d883f9f6095",
7
- "clientId" => "clien-test",
8
- "name" => "Client TEST",
9
- "description" => "Test to parse a client repsentation",
10
- "surrogateAuthRequired" => false,
11
- "enabled" => true,
12
- "alwaysDisplayInConsole" => false,
13
- "clientAuthenticatorType" => "client-secret",
14
- "redirectUris" => [],
15
- "webOrigins" => [],
16
- "notBefore" => 0,
17
- "bearerOnly" => false,
18
- "consentRequired" => false,
19
- "standardFlowEnabled" => false,
20
- "implicitFlowEnabled" => false,
21
- "directAccessGrantsEnabled" => false,
22
- "serviceAccountsEnabled" => true,
23
- "publicClient" => false,
24
- "frontchannelLogout" => false,
25
- "protocol" => "openid-connect",
26
- "attributes" => {
27
- "saml.assertion.signature" => "false",
28
- "access.token.lifespan" => "86400",
29
- "saml.multivalued.roles" => "false",
30
- "saml.force.post.binding" => "false",
31
- "saml.encrypt" => "false",
32
- "saml.server.signature" => "false",
33
- "backchannel.logout.revoke.offline.tokens" => "false",
34
- "saml.server.signature.keyinfo.ext" => "false",
35
- "exclude.session.state.from.auth.response" => "false",
36
- "backchannel.logout.session.required" => "true",
37
- "saml_force_name_id_format" => "false",
38
- "saml.client.signature" => "false",
39
- "tls.client.certificate.bound.access.tokens" => "false",
40
- "saml.authnstatement" => "false",
41
- "display.on.consent.screen" => "false",
42
- "saml.onetimeuse.condition" => "false"
43
- },
44
- "authenticationFlowBindingOverrides" => {},
45
- "fullScopeAllowed" => true,
46
- "nodeReRegistrationTimeout" => -1,
47
- "protocolMappers" => [
48
- {
49
- "id" => "2220432a-e953-422c-b176-62b65e085fe5",
50
- "name" => "Client Host",
51
- "protocol" => "openid-connect",
52
- "protocolMapper" => "oidc-usersessionmodel-note-mapper",
53
- "consentRequired" => false,
54
- "config" => {
55
- "user.session.note" => "clientHost",
56
- "userinfo.token.claim" => "true",
57
- "id.token.claim" => "true",
58
- "access.token.claim" => "true",
59
- "claim.name" => "clientHost",
60
- "jsonType.label" => "String"
61
- }
62
- },
63
- {
64
- "id" => "5509e428-574d-4137-b396-9108244f31ee",
65
- "name" => "Client IP Address",
66
- "protocol" => "openid-connect",
67
- "protocolMapper" => "oidc-usersessionmodel-note-mapper",
68
- "consentRequired" => false,
69
- "config" => {
70
- "user.session.note" => "clientAddress",
71
- "userinfo.token.claim" => "true",
72
- "id.token.claim" => "true",
73
- "access.token.claim" => "true",
74
- "claim.name" => "clientAddress",
75
- "jsonType.label" => "String"
76
- }
77
- },
78
- {
79
- "id" => "44504b93-dbce-48b8-9570-9a48d5421ae9",
80
- "name" => "Client ID",
81
- "protocol" => "openid-connect",
82
- "protocolMapper" => "oidc-usersessionmodel-note-mapper",
83
- "consentRequired" => false,
84
- "config" => {
85
- "user.session.note" => "clientId",
86
- "userinfo.token.claim" => "true",
87
- "id.token.claim" => "true",
88
- "access.token.claim" => "true",
89
- "claim.name" => "clientId",
90
- "jsonType.label" => "String"
91
- }
92
- }
93
- ],
94
- "defaultClientScopes" => [
95
- "web-origins",
96
- "roles",
97
- "profile",
98
- "email"
99
- ],
100
- "optionalClientScopes" => [
101
- "address",
102
- "phone",
103
- "offline_access",
104
- "microprofile-jwt"
105
- ],
106
- "access" => {
107
- "view" => true,
108
- "configure" => true,
109
- "manage" => true
110
- }
111
- }
112
- )
113
- end
114
-
115
- it "can convert to json" do
116
- expect(@client.to_json).to eq "{\"id\":\"c9104bc7-04d8-4348-b4df-8d883f9f6095\",\"name\":\"Client TEST\",\"clientId\":\"clien-test\",\"description\":\"Test to parse a client repsentation\",\"clientAuthenticatorType\":\"client-secret\",\"alwaysDisplayInConsole\":false,\"surrogateAuthRequired\":false,\"redirectUris\":[],\"webOrigins\":[],\"notBefore\":0,\"bearerOnly\":false,\"consentRequired\":false,\"standardFlowEnabled\":false,\"implicitFlowEnabled\":false,\"directAccessGrantsEnabled\":false,\"serviceAccountsEnabled\":true,\"authorizationServicesEnabled\":false,\"publicClient\":false,\"frontchannelLogout\":false,\"protocol\":\"openid-connect\",\"baseUrl\":null,\"rootUrl\":null,\"attributes\":{\"saml.assertion.signature\":\"false\",\"access.token.lifespan\":\"86400\",\"saml.multivalued.roles\":\"false\",\"saml.force.post.binding\":\"false\",\"saml.encrypt\":\"false\",\"saml.server.signature\":\"false\",\"backchannel.logout.revoke.offline.tokens\":\"false\",\"saml.server.signature.keyinfo.ext\":\"false\",\"exclude.session.state.from.auth.response\":\"false\",\"backchannel.logout.session.required\":\"true\",\"saml_force_name_id_format\":\"false\",\"saml.client.signature\":\"false\",\"tls.client.certificate.bound.access.tokens\":\"false\",\"saml.authnstatement\":\"false\",\"display.on.consent.screen\":\"false\",\"saml.onetimeuse.condition\":\"false\"},\"authenticationFlowBindingOverrides\":{},\"fullScopeAllowed\":true,\"nodeReRegistrationTimeout\":-1,\"protocolMappers\":[{\"id\":\"2220432a-e953-422c-b176-62b65e085fe5\",\"config\":{\"user.session.note\":\"clientHost\",\"userinfo.token.claim\":\"true\",\"id.token.claim\":\"true\",\"access.token.claim\":\"true\",\"claim.name\":\"clientHost\",\"jsonType.label\":\"String\"},\"name\":\"Client Host\",\"protocol\":\"openid-connect\",\"protocolMapper\":\"oidc-usersessionmodel-note-mapper\"},{\"id\":\"5509e428-574d-4137-b396-9108244f31ee\",\"config\":{\"user.session.note\":\"clientAddress\",\"userinfo.token.claim\":\"true\",\"id.token.claim\":\"true\",\"access.token.claim\":\"true\",\"claim.name\":\"clientAddress\",\"jsonType.label\":\"String\"},\"name\":\"Client IP Address\",\"protocol\":\"openid-connect\",\"protocolMapper\":\"oidc-usersessionmodel-note-mapper\"},{\"id\":\"44504b93-dbce-48b8-9570-9a48d5421ae9\",\"config\":{\"user.session.note\":\"clientId\",\"userinfo.token.claim\":\"true\",\"id.token.claim\":\"true\",\"access.token.claim\":\"true\",\"claim.name\":\"clientId\",\"jsonType.label\":\"String\"},\"name\":\"Client ID\",\"protocol\":\"openid-connect\",\"protocolMapper\":\"oidc-usersessionmodel-note-mapper\"}],\"defaultClientScopes\":[\"web-origins\",\"roles\",\"profile\",\"email\"],\"optionalClientScopes\":[\"address\",\"phone\",\"offline_access\",\"microprofile-jwt\"],\"access\":{\"view\":true,\"configure\":true,\"manage\":true}}"
117
- end
118
- end
119
- end
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe KeycloakAdmin::ClientScopeRepresentation do
4
- describe ".from_hash" do
5
- context "with all fields" do
6
- let(:hash) do
7
- {
8
- "id" => "valid-scope-id",
9
- "name" => "my-scope",
10
- "description" => "A test scope",
11
- "protocol" => "openid-connect",
12
- "attributes" => {
13
- "display.on.consent.screen" => "true",
14
- "include.in.token.scope" => "true"
15
- },
16
- "protocolMappers" => [
17
- {
18
- "id" => "mapper-id",
19
- "name" => "my-claim",
20
- "protocol" => "openid-connect",
21
- "protocolMapper" => "oidc-hardcoded-claim-mapper",
22
- "config" => { "claim.name" => "my_claim", "claim.value" => "bar" }
23
- }
24
- ]
25
- }
26
- end
27
-
28
- subject { described_class.from_hash(hash) }
29
-
30
- it "returns an instance of the class" do
31
- expect(subject).to be_a described_class
32
- end
33
-
34
- it "sets id" do
35
- expect(subject.id).to eq "valid-scope-id"
36
- end
37
-
38
- it "sets name" do
39
- expect(subject.name).to eq "my-scope"
40
- end
41
-
42
- it "sets description" do
43
- expect(subject.description).to eq "A test scope"
44
- end
45
-
46
- it "sets protocol" do
47
- expect(subject.protocol).to eq "openid-connect"
48
- end
49
-
50
- it "sets attributes" do
51
- expect(subject.attributes).to eq(
52
- "display.on.consent.screen" => "true",
53
- "include.in.token.scope" => "true"
54
- )
55
- end
56
-
57
- it "deserializes protocolMappers as ProtocolMapperRepresentation objects" do
58
- expect(subject.protocol_mappers.size).to eq 1
59
- expect(subject.protocol_mappers.first).to be_a KeycloakAdmin::ProtocolMapperRepresentation
60
- end
61
-
62
- it "sets the correct mapper attributes" do
63
- expect(subject.protocol_mappers.first).to have_attributes(
64
- id: "mapper-id",
65
- name: "my-claim",
66
- protocol: "openid-connect",
67
- protocolMapper: "oidc-hardcoded-claim-mapper"
68
- )
69
- end
70
- end
71
-
72
- context "without protocolMappers" do
73
- subject { described_class.from_hash({ "id" => "valid-scope-id", "name" => "my-scope" }) }
74
-
75
- it "defaults protocolMappers to an empty array" do
76
- expect(subject.protocol_mappers).to eq []
77
- end
78
- end
79
-
80
- context "with minimal fields" do
81
- subject { described_class.from_hash({ "name" => "my-scope", "protocol" => "saml" }) }
82
-
83
- it "sets name" do
84
- expect(subject.name).to eq "my-scope"
85
- end
86
-
87
- it "sets protocol" do
88
- expect(subject.protocol).to eq "saml"
89
- end
90
-
91
- it "leaves id nil" do
92
- expect(subject.id).to be_nil
93
- end
94
-
95
- it "leaves description nil" do
96
- expect(subject.description).to be_nil
97
- end
98
-
99
- it "leaves attributes nil" do
100
- expect(subject.attributes).to be_nil
101
- end
102
- end
103
- end
104
-
105
- describe "#to_json" do
106
- subject do
107
- described_class.from_hash(
108
- "id" => "valid-scope-id",
109
- "name" => "my-scope",
110
- "description" => "A test scope",
111
- "protocol" => "openid-connect",
112
- "attributes" => { "include.in.token.scope" => "true" }
113
- )
114
- end
115
-
116
- it "serializes to JSON" do
117
- parsed = JSON.parse(subject.to_json)
118
- expect(parsed["id"]).to eq "valid-scope-id"
119
- expect(parsed["name"]).to eq "my-scope"
120
- expect(parsed["description"]).to eq "A test scope"
121
- expect(parsed["protocol"]).to eq "openid-connect"
122
- expect(parsed["attributes"]).to eq("include.in.token.scope" => "true")
123
- end
124
- end
125
- end
@@ -1,68 +0,0 @@
1
-
2
- RSpec.describe KeycloakAdmin::CredentialRepresentation do
3
- describe ".from_json" do
4
- it "parses a password" do
5
- json_payload = <<-'payload'
6
- {
7
- "id": "2ff4b4d0-fd72-4c6e-9684-02ab337687c2",
8
- "type": "password",
9
- "userLabel": "My password",
10
- "createdDate": 1767604673211,
11
- "credentialData": "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}"
12
- }
13
- payload
14
-
15
- credential = described_class.from_json(json_payload)
16
- expect(credential).to be
17
- expect(credential).to be_a described_class
18
- expect(credential.id).to eq "2ff4b4d0-fd72-4c6e-9684-02ab337687c2"
19
- expect(credential.type).to eq "password"
20
- expect(credential.createdDate).to eq 1767604673211
21
- expect(credential.credentialData).to eq "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}"
22
- expect(credential.userLabel).to eq "My password"
23
- expect(credential.device).to be_nil
24
- expect(credential.value).to be_nil
25
- expect(credential.hashedSaltedValue).to be_nil
26
- expect(credential.salt).to be_nil
27
- expect(credential.hashIterations).to eq 5
28
- expect(credential.counter).to be_nil
29
- expect(credential.algorithm).to eq "argon2"
30
- expect(credential.digits).to be_nil
31
- expect(credential.period).to be_nil
32
- expect(credential.config).to be_nil
33
- expect(credential.temporary).to be_nil
34
- end
35
-
36
- it "parses an otp" do
37
- json_payload = <<-'payload'
38
- {
39
- "id": "34389672-9356-4154-9ed6-6c212b869010",
40
- "type": "otp",
41
- "userLabel": "Smartphone",
42
- "createdDate": 1767605202060,
43
- "credentialData": "{\"subType\":\"totp\",\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\"}"
44
- }
45
- payload
46
-
47
- credential = described_class.from_json(json_payload)
48
- expect(credential).to be
49
- expect(credential).to be_a described_class
50
- expect(credential.id).to eq "34389672-9356-4154-9ed6-6c212b869010"
51
- expect(credential.type).to eq "otp"
52
- expect(credential.createdDate).to eq 1767605202060
53
- expect(credential.credentialData).to eq "{\"subType\":\"totp\",\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\"}"
54
- expect(credential.userLabel).to eq "Smartphone"
55
- expect(credential.device).to be_nil
56
- expect(credential.value).to be_nil
57
- expect(credential.hashedSaltedValue).to be_nil
58
- expect(credential.salt).to be_nil
59
- expect(credential.hashIterations).to be_nil
60
- expect(credential.counter).to eq 0
61
- expect(credential.algorithm).to eq "HmacSHA1"
62
- expect(credential.digits).to eq 6
63
- expect(credential.period).to eq 30
64
- expect(credential.config).to be_nil
65
- expect(credential.temporary).to be_nil
66
- end
67
- end
68
- end
@@ -1,22 +0,0 @@
1
-
2
- RSpec.describe KeycloakAdmin::GroupRepresentation do
3
- describe ".from_hash" do
4
- it "parses the sub groups into group representations" do
5
- group = described_class.from_hash({
6
- "name" => "group a",
7
- "attributes" => {
8
- "key" => ["value"]
9
- },
10
- "subGroupCount" => 1,
11
- "subGroups" => [{
12
- "name" => "subgroup b"
13
- }]
14
- })
15
-
16
- expect(group.attributes).to eq(key: ["value"])
17
- expect(group.sub_group_count).to eq 1
18
- expect(group.sub_groups.length).to eq 1
19
- expect(group.sub_groups.first).to be_a described_class
20
- end
21
- end
22
- end
@@ -1,24 +0,0 @@
1
- RSpec.describe KeycloakAdmin::IdentityProviderMapperRepresentation do
2
- describe "#to_json" do
3
- before(:each) do
4
- @mapper = KeycloakAdmin::IdentityProviderMapperRepresentation.from_hash(
5
- {
6
- "id" => "91895ce9-b225-4274-993e-c8e6b8e490f0",
7
- "name" => "IDP",
8
- "identityProviderAlias" => "test",
9
- "identityProviderMapper" => "hardcoded-attribute-idp-mapper",
10
- "config" => {
11
- "syncMode" => "INHERIT",
12
- "attribute.value" => "test",
13
- "attributes" => "[]",
14
- "attribute" => "keycloak.idp"
15
- }
16
- }
17
- )
18
- end
19
-
20
- it "can convert to json" do
21
- expect(@mapper.to_json).to eq "{\"id\":\"91895ce9-b225-4274-993e-c8e6b8e490f0\",\"name\":\"IDP\",\"identityProviderAlias\":\"test\",\"identityProviderMapper\":\"hardcoded-attribute-idp-mapper\",\"config\":{\"syncMode\":\"INHERIT\",\"attribute.value\":\"test\",\"attributes\":\"[]\",\"attribute\":\"keycloak.idp\"}}"
22
- end
23
- end
24
- end