Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 62 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ All options have a default value. However, all of them can be changed in your in
* Execute actions emails
* Send forgot passsword mail
* Client Authorization, create, update, get, delete Resource, Scope, Policy, Permission, Policy Enforcer
* Get list of protocol mappers for a client scope, create/update/get/delete a protocol mapper
* Get list of client scopes, create/save/get/delete/search a client scope
* Get list of protocol mappers for a client scope, create/save/get/delete a protocol mapper
* Get list of organizations, create/update/get/delete an organization
* Get list of members of an organization, add/remove members
* Invite new or existing users to an organization
Expand Down Expand Up @@ -758,6 +759,64 @@ KeycloakAdmin.realm("realm_a").authz_permissions(client.id, 'scope').delete(scop
KeycloakAdmin.realm("realm_a").authz_permissions(client.id, 'resource').delete(resource_permission.id)
```

### Manage Client Scopes

### List all client scopes in a realm

Returns an array of `KeycloakAdmin::ClientScopeRepresentation`.

```ruby
KeycloakAdmin.realm("a_realm").client_scopes.list
```

### Get a client scope by its id

Returns an instance of `KeycloakAdmin::ClientScopeRepresentation`.

```ruby
client_scope_id = "7686af34-204c-4515-8122-78d19febbf6e"
KeycloakAdmin.realm("a_realm").client_scopes.get(client_scope_id)
```

### Search for client scopes by name

Returns an array of `KeycloakAdmin::ClientScopeRepresentation` whose names contain the given substring.

```ruby
KeycloakAdmin.realm("a_realm").client_scopes.search("my-scope")
```

### Create a client scope

Takes `scope_representation` of type `KeycloakAdmin::ClientScopeRepresentation`. Returns `true` on success.

```ruby
scope = KeycloakAdmin::ClientScopeRepresentation.new
scope.name = "my-scope"
scope.description = "My custom scope"
scope.protocol = "openid-connect"
scope.attributes = { "display.on.consent.screen" => "true", "include.in.token.scope" => "true" }
KeycloakAdmin.realm("a_realm").client_scopes.create!(scope)
```

### Save (update) a client scope

Takes `scope_representation` of type `KeycloakAdmin::ClientScopeRepresentation` (must include its `id`). Returns `true` on success.

```ruby
client_scope_id = "7686af34-204c-4515-8122-78d19febbf6e"
scope = KeycloakAdmin.realm("a_realm").client_scopes.get(client_scope_id)
scope.description = "Updated description"
KeycloakAdmin.realm("a_realm").client_scopes.save(scope)
```

### Delete a client scope

```ruby
client_scope_id = "7686af34-204c-4515-8122-78d19febbf6e"
KeycloakAdmin.realm("a_realm").client_scopes.delete(client_scope_id)
```

### Manage Protocol Mappers for a Client Scope

Protocol mappers allow you to transform tokens and assertions. The following operations are available on the protocol mappers of a given client scope.
Expand Down Expand Up @@ -795,15 +854,15 @@ mapper.config = { "user.attribute" => "locale", "claim.name" => "locale",
KeycloakAdmin.realm("a_realm").client_scope_protocol_mappers(client_scope_id).create!(mapper)
```

### Update a protocol mapper for a client scope
### Save (update) a protocol mapper for a client scope

Takes `mapper_representation` of type `KeycloakAdmin::ProtocolMapperRepresentation` (must include its `id`). Returns `true` on success.

```ruby
client_scope_id = "7686af34-204c-4515-8122-78d19febbf6e"
mapper = KeycloakAdmin.realm("a_realm").client_scope_protocol_mappers(client_scope_id).get(mapper_id)
mapper.config["claim.name"] = "updated_claim"
KeycloakAdmin.realm("a_realm").client_scope_protocol_mappers(client_scope_id).update(mapper)
KeycloakAdmin.realm("a_realm").client_scope_protocol_mappers(client_scope_id).save(mapper)
```

### Delete a protocol mapper from a client scope
Expand Down
2 changes: 2 additions & 0 deletions lib/keycloak-admin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
require_relative "keycloak-admin/client/configurable_token_client"
require_relative "keycloak-admin/client/attack_detection_client"
require_relative "keycloak-admin/client/client_authz_scope_client"
require_relative "keycloak-admin/client/client_scope_client"
require_relative "keycloak-admin/client/client_scope_protocol_mapper_client"
require_relative "keycloak-admin/client/client_authz_resource_client"
require_relative "keycloak-admin/client/client_authz_policy_client"
Expand All @@ -40,6 +41,7 @@
require_relative "keycloak-admin/representation/identity_provider_representation"
require_relative "keycloak-admin/representation/attack_detection_representation"
require_relative "keycloak-admin/representation/session_representation"
require_relative "keycloak-admin/representation/client_scope_representation"
require_relative "keycloak-admin/representation/client_authz_scope_representation"
require_relative "keycloak-admin/representation/client_authz_resource_representation"
require_relative "keycloak-admin/representation/client_authz_policy_representation"
Expand Down
65 changes: 65 additions & 0 deletions lib/keycloak-admin/client/client_scope_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module KeycloakAdmin
class ClientScopeClient < Client
def initialize(configuration, realm_client)
super(configuration)

raise ArgumentError.new("realm must be defined") unless realm_client.name_defined?

@realm_client = realm_client
end

def list
response = execute_http do
RestClient::Resource.new(client_scopes_url, @configuration.rest_client_options).get(headers)
end

JSON.parse(response).map { |h| ClientScopeRepresentation.from_hash(h) }
end

def get(client_scope_id)
response = execute_http do
RestClient::Resource.new(client_scopes_url(client_scope_id), @configuration.rest_client_options).get(headers)
end

ClientScopeRepresentation.from_hash(JSON.parse(response))
end

def create!(client_scope_representation)
execute_http do
RestClient::Resource.new(client_scopes_url, @configuration.rest_client_options).post(
create_payload(client_scope_representation), headers
)
end

true
end

def save(client_scope_representation)
execute_http do
RestClient::Resource.new(client_scopes_url(client_scope_representation.id), @configuration.rest_client_options).put(
create_payload(client_scope_representation), headers
)
end

true
end

def search(name)
list.select { |scope| scope&.name&.include?(name) }
end

def delete(client_scope_id)
execute_http do
RestClient::Resource.new(client_scopes_url(client_scope_id), @configuration.rest_client_options).delete(headers)
end

true
end

def client_scopes_url(client_scope_id = nil)
base = "#{@realm_client.realm_admin_url}/client-scopes"

client_scope_id ? "#{base}/#{client_scope_id}" : base
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def create!(mapper_representation)
true
end

def update(mapper_representation)
def save(mapper_representation)
execute_http do
RestClient::Resource.new(protocol_mappers_url(mapper_representation.id), @configuration.rest_client_options).put(
create_payload(mapper_representation), headers
Expand Down
4 changes: 4 additions & 0 deletions lib/keycloak-admin/client/realm_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def user(user_id)
UserResource.new(@configuration, self, user_id)
end

def client_scopes
ClientScopeClient.new(@configuration, self)
end

def client_scope_protocol_mappers(client_scope_id)
ClientScopeProtocolMapperClient.new(@configuration, self, client_scope_id)
end
Expand Down
21 changes: 21 additions & 0 deletions lib/keycloak-admin/representation/client_scope_representation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module KeycloakAdmin
class ClientScopeRepresentation < Representation
attr_accessor :id,
:name,
:description,
:protocol,
:attributes,
:protocol_mappers

def self.from_hash(hash)
rep = new
rep.id = hash["id"]
rep.name = hash["name"]
rep.description = hash["description"]
rep.protocol = hash["protocol"]
rep.attributes = hash["attributes"]
rep.protocol_mappers = (hash["protocolMappers"] || []).map { |m| ProtocolMapperRepresentation.from_hash(m) }
rep
end
end
end
Loading
Loading