Skip to content

Latest commit

 

History

History
283 lines (187 loc) · 17.3 KB

File metadata and controls

283 lines (187 loc) · 17.3 KB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[2.0.3] - 2026-08-03

  • [Performance] Added # frozen_string_literal: true across all Ruby files to significantly reduce string object allocations and lower memory consumption.

  • [Performance] Refactored Representation JSON serialization (as_json and to_json) to eliminate intermediate Array and Hash allocations, improving CPU performance and memory footprint.

  • [Fix] Representation#as_json now strips nil values when generating JSON payloads. This fixes HTTP 400 Bad Request errors caused by strict API requirements in Keycloak 19+ (such as refusing null for subGroupCount and other restricted fields).

  • [Chore] Expanded the integration test suite to cover 100% of the REST clients against live Keycloak instances.

  • [Chore] Fixed the integration test suite against Keycloak 25 and 26. The dummy realm now enables internationalization and unmanaged user attributes, both required since Keycloak 24 for locale and custom attributes to be persisted; authorization permissions are deleted before the policy they depend on, since Keycloak 25 cascades that deletion; and permissions are asserted by name rather than by total count, which Keycloak 25 inflates with a seeded Default Permission. Each integration spec now loads the integration helper itself, instead of relying on another spec file having loaded it first.

  • [Fix] Configuration#inspect no longer renders client_secret, password or the cached access token, showing [FILTERED] instead. The default #inspect printed every attribute, so these credentials travelled into console sessions, pp output, and whatever local-variable dump an exception reporter attaches to a crash. A credential that is not set still renders as nil, so an inspect stays useful when authentication misbehaves.

  • [Fix] The access token cache introduced in 2.0.1 is now thread-safe.

  • [Fix] Identifiers are now percent-encoded before being interpolated into a URL path.

  • [Feature] UserClient#update_password accepts an optional temporary: keyword.

  • [Performance] ClientClient#find_by_client_id now has Keycloak filter with ?clientId= instead of listing every client of the realm and comparing in Ruby

  • [Feature] UserClient#list and GroupClient#list accept optional first: and max: keywords. Keycloak answers GET /users with at most 100 entries when max is absent, so users.list silently returned a truncated realm with no way to ask for more; GET /groups applies no such cap, but both endpoints now page the same way. Calling either list with no argument sends no query parameter and is unchanged. GroupClient#list pairs a lone max with first=0, because Keycloak 19 only paginates that endpoint when both bounds are present and ignores max on its own; this is a no-op from Keycloak 23 on. Verified against live Keycloak 19.0, 23.0 and 26.7.0.

  • [Feature] config.faraday_adapter selects the Faraday adapter requests run through.

  • [Fix] UserClient#impersonate now takes part in the 401 replay introduced in 2.0.2. It called get_redirect_impersonation outside execute_http, so its Authorization header was built before the replay cleared the cached token: the second attempt resent the very bearer that had just been rejected and failed with the same 401. It was the last call in the gem where the replay was inert.

  • [Fix] CamelJson#camelize no longer raises NoMethodError on an empty word.

  • [Fix] Query parameters built from an Array are now rendered as the key repeated once per element, instead of the array's Ruby inspect form: a list value used to be sent as name=%5B%22a%22%2C%20%22b%22%5D. An empty array now contributes no parameter at all; a nil still renders as name=, unchanged.

  • [Breaking] ClientAuthzResourceClient#update now replaces the submitted uris and scopes instead of merging them with the ones already stored. It used to union both, so updating twice with the same uri accumulated duplicates and no uri or scope could ever be removed. A key absent from the submitted hash still leaves the stored value untouched; presence is now what decides, not truthiness, so uris: [] clears the uris and owner_managed_access: false is honoured rather than read as "not submitted". The method also no longer raises a bare RuntimeError when a scope has no :name, but a KeycloakAdmin-consistent ArgumentError, and no longer raises TypeError when the stored resource has no uris at all.

  • [Fix] ClientRepresentation.from_hash no longer produces wrongly typed defaults when the payload omits a field.

  • [Fix] RoleRepresentation and SessionRepresentation no longer define spurious from_hash and from_hash= instance accessors. A trailing comma after the last symbol of their attr_accessor list continued the argument list into the following def, which evaluates to a Symbol, so attr_accessor also received :from_hash. The class method self.from_hash was never shadowed, so parsing was unaffected.

  • [Fix] UserClient#update, #add_group and #remove_group built their request outside execute_http. They were the only methods on this client that raised a bare Faraday::Error instead of the documented KeycloakAdmin::ApiError hierarchy, and the only ones that did not replay a request rejected on a stale 401.

  • [Fix] UserClient#create! could return a different user than the one it had just created. It looked the new user up with search(email), and Keycloak's search parameter matches a substring of the username, email, first name or last name: creating pioupioux@email.com while vieuxpioupioux@email.com already existed returned the pre-existing account. The new user's id is now read from the Location header of the creation response, like GroupClient#create! already did. Two consequences: a creation not answered with 201 Created now raises KeycloakAdmin::UnexpectedResponseError instead of returning nil, and the returned representation is fetched by id.

  • [Fix] UserClient#create! wrote the locale into the very attributes hash it was given, mutating the caller's object.

  • [Fix] UserClient#execute_actions_email (and #forgot_password) ignored config.faraday_options. It was the only call in the gem running with no timeout, and any configured SSL or proxy setting was silently dropped. The internal KeycloakAdmin::Resource.put shorthand it relied on is removed; its signature could not carry connection options.

  • [Chore] Migrated test suites to use WebMock stub_request instead of stubbing KeycloakAdmin::Resource directly, ensuring tests validate the actual network payload.

[2.0.2] - 2026-08-01

  • [Breaking] HTTP failures now raise a KeycloakAdmin::ApiError subclass instead of a bare RuntimeError.
    • Messages are unchanged, so code matching on the text keeps working.
    • Code rescuing RuntimeError explicitly must be updated.
    • A create call answering something other than 201 Created now raises KeycloakAdmin::UnexpectedResponseError.
  • [Feature] A 401 answer now drops the cached access token and replays the request once with a freshly fetched one, so a token revoked before its advertised expiry no longer fails every call until it lapses.
  • [Fix] GroupClient#members called ActiveSupport's Object#try and raised NoMethodError outside a Rails application.
  • [Fix] UserClient#execute_actions_email (and #forgot_password) called ActiveSupport's Numeric#seconds and raised NoMethodError outside a Rails application whenever a lifespan was passed.
  • [Fix] ClientAuthzPolicyClient#find_by opened a second ? in its URL, which folded name, type, first and max into the value of permission; Keycloak silently returned an unfiltered list.
  • [Fix] Query parameters are now percent-encoded everywhere they are built. Search terms, and the redirect_uri of UserClient#execute_actions_email, containing a space, & or = used to break the URL or forge extra parameters.
  • [Fix] OrganizationClient#build raised NameError instead of the intended ArgumentError when domains was not an Array.

[2.0.1] - 2026-07-31

  • [Feature] Requests are now logged through config.logger (method, URL, and response status) via Faraday's :logger middleware.
  • [Feature] The access token is now cached and reused (tracking expires_in) instead of being fetched before nearly every call. Previously, caching lived on the Client instance, but a fresh Client subclass is created for almost every call (e.g. KeycloakAdmin.realm(x).users builds a new UserClient), so the cache was rarely hit in practice; it now lives on the shared Configuration.
  • Publish the gem to RubyGems from Github Actions when a v* tag is pushed, using RubyGems' Trusted Publishing

[2.0.0] - 2026-07-31

  • [Breaking] Replaced rest-client with Faraday as the underlying HTTP library. This should be transparent for callers of this gem's own API, but config.rest_client_options is renamed to config.faraday_options and its shape changes from rest-client's flat hash to Faraday's connection options (e.g. { timeout: 5 } becomes { request: { timeout: 5 } }, { verify_ssl: false } becomes { ssl: { verify: false } }). See the Configuration section of the README.
  • [Fix] GroupClient#remove_realm_level_role_name! used Ruby 3.1 hash value omission
  • [Fix] Strip trailing slashes from the configured server_url. Keycloak 26 rejects non-normalized request paths with 400 {"error":"missingNormalization"}, so a server_url such as http://localhost:8080/ produced an unusable //realms/... path. Earlier Keycloak versions tolerated it.
  • [Chore] required_ruby_version is now >= 3.1 instead of >= 2.3
  • [Chore] CI now tests against Ruby 3.1, 3.2, 3.3 and 3.4.

[1.2.0] - 2026-07-30

  • [Chore] Bump http-cookie dependency from 1.1.0 to 1.1.6.
  • [Chore] Upgrade Docker base image from ruby:3.2.2-slim-bullseye to ruby:3.3.12-slim-trixie.
  • [Chore] CI now boots Keycloak 26.7.0 (quay.io/keycloak/keycloak) instead of the abandoned tillawy/keycloak-github-actions:25.0.1

[1.1.7] - 2026-03-27

  • [Feature] Client scopes - supported operations: create!, get, delete, list, and search.
  • [Feature] Client scopes protocol mappers - supported operations: create!, get, delete, list, and search.

[1.1.6] - 2026-01-05

  • [Feature] Support for Organizations (Multi-tenancy):
    • Organization Management:
      • Supported operations: create!, update, get, delete, list, and count.
      • Supported searching and filtering via exact, query, and search parameters.
    • Member Management:
      • Added ability to list organization members with pagination and filtering (members).
      • Added members_count to retrieve the total number of members.
      • Added get_member, add_member (by user ID), and delete_member.
      • Added helper to find all organizations associated with a specific user: associated_with_member.
    • Invitations:
      • Added invite_user: Invites a new user via email/name.
      • Added invite_existing_user: Invites an existing Keycloak user to the organization by ID.
    • Identity Provider (IdP) Linking:
      • Added methods to manage IdPs linked to an organization: identity_providers, get_identity_provider, add_identity_provider, and delete_identity_provider.

[1.1.5] - 2026-01-05

  • [Feature] Added the ability to list credentials for a given user.
  • [Fix] Implemented safe parsing for nested JSON elements within CredentialRepresentation (handling both credentialData and secretData fields). Please refer to the official documentation.
  • [Breaking] Renamed CredentialRepresentation attribute created_date $\rightarrow$ createdDate to align with the Keycloak Admin API.

[1.1.4] - 2025-11-08

  • Add remove_realm_level_role_name! action on a GroupClient (thanks to @mkrawc)
  • Dependencies: Update Gemfile.lock to bump byebug → 12.0.0, rspec → 3.13.2, and related dependencies
  • Bug: The 'remove' operation of the 'RoleMapperClient' does not take the global rest options into account

[1.1.3] - 2024-07-12

  • Client Authorization management support (thanks to @tillawy)
  • GitHub-actions setup to execute rspec (thanks to @tillawy)

[1.1.2] - 2024-05-22

  • Add group endpoints (get, children, delete), support for group attributes (thanks to @mkrawc)
  • GroupClient#save method now can update an existing group (thanks to @mkrawc)
  • RoleClient#save method now can update an existing role (thanks to @mkrawc)

[1.1.1] - 2024-01-21

  • Add/List realm-role/s to a group, Allow role-names with spaces, List groups assigned to role (thanks to @LiquidMagical)

[1.1.0] - 2023-10-03

  • Search for groups with parameters (thanks to @@tlloydthwaites)
  • Get client by ID, Find client by Client ID, Update Client (thanks to @gee-forr)

[1.0.24] - 2023-06-07

  • Revert the modifications on the feature 'Update a User' introduced in 1.0.22. This implementation had breaking changes such as not being able to update several attributes (first_name, email, etc).

[1.0.23] - 2023-06-01

  • Be more permissive about the version of rest-client (~> 2.0) (thanks to @type-face)

[1.0.22] - 2023-05-29

  • Fetch user's all active sessions (thanks to @prsanjay)
  • Check whether a user is locked or not (thanks to @prsanjay)
  • Logout users from all the active sessions (thanks to @prsanjay)

[1.0.21] - 2023-02-03

  • List users who are a member of a group (thanks to @tlloydthwaites)

[1.0.20] - 2022-12-26

  • Create subgroups (thanks to @neckhair)
  • Add subgroups to GroupRepresentation (thanks to @neckhair)
  • Expose BaseRoleContainingResource.resource_id (thanks to @neckhair)

[1.0.19] - 2022-12-03

  • Remove specific realm roles from user (thanks to @tlloydthwaites)
  • Get role by name (thanks to @tlloydthwaites)

[1.0.18] - 2022-11-24

  • List user realm-level role mappings (thanks to @Kazhuu)

[1.0.17] - 2022-11-02

  • Delete Client

[1.0.16] - 2022-10-15

  • Remove rest-client warning when adding a group (thanks to @tlloydthwaites)

[1.0.15] - 2022-05-23

  • Delete all "realm" roles mapped to a user

[1.0.14] - 2022-03-30

  • Update Gemfile.lock to avoid wrong CVE detections. The version of Rails should always be specified by the parent project. This change has no functional impact.

[1.0.13] - 2022-03-13

  • Add client role on users
  • List client roles

[1.0.7] - 2022-03-13

  • Allow to use multiple KeycloakAdmin::Client in the same environment

[1.0.6] - 2022-03-13

  • When serializing an array to JSON, force the serialization to use to_json for each element. In several contexts (e.g. Rails), to_json is not used.

[1.0.5] - 2022-03-11

  • Create Client
  • Create Identity Provider (Breaking change: IdentityProviderRepresentation.configuration has been renamed to IdentityProviderRepresentation.config)
  • Add Identity Provider Mapping
  • Find service account for a Client

[1.0.1] - 2021-10-14

  • List all Identity Providers
  • Add Group on Users (thanks to @tomuench)
  • Remove Group from Users (thanks to @tomuench)

[1.0.0] - 2021-08-03

  • Add totp on Users
  • Add required_actions on Users

[0.7.9] - 2020-10-22

  • Extend search function to use complex queries (thanks to @hobbypunk90)

[0.7.8] - 2020-10-15

  • Bug: rest_client_options default value does not match the documentation (was nil by default, should be {})
  • Update documentation about client setup (based on Keycloak 11)

[0.7.7] - 2020-07-10

  • Fix: Replace request method shorthand with .execute for proper RestClient option support (thanks to @RomanHargrave)
  • When sending action emails, add lifespan as an optional parameter (thanks to @hobbypunk90)

[0.7.6] - 2020-06-22

Thanks to @hobbypunk90

  • Support for action emails and send forgot passsword mail

[0.7.5] - 2020-03-28

Thanks to @RomanHargrave

  • Support for working with federated identity provider (broker) links

[0.7.4] - 2019-10-17

  • Support for Rails 6

[0.7.3] - 2019-07-11

Thanks to @cederigo:

  • For a given user, get her list of groups

[0.7.2] - 2019-06-17

Thanks to @vlad-ro:

  • Get list of client role mappings for a group
  • Save client role mappings for a user/group
  • Save realm-level role mappings for a user/group

[0.7.1] - 2019-06-11

Thanks to @vlad-ro:

  • List users
  • List clients
  • List groups, create/save a group
  • List roles, save a role
  • List realms, save/update/delete a realm
  • Get list of client role mappings for a user
  • Support passing rest client options for user save and search
  • Support using gem without ActiveSupport

[0.7.0] - 2019-06-06

Thanks to @vlad-ro:

  • Support passing rest client options
  • More documentation
  • More tests
  • Better handling of timeouts

[0.6.5] - 2019-05-14

  • Get user

[0.6.2] - 2019-05-14

  • Update users

[0.6] - 2019-03-06

  • Save a locale when creating a new user

[0.5] - 2018-01-26

  • Client to access Custom REST API configurable-token

[0.3] - 2018-01-19

  • Support of impersonation