Skip to content

feat: propagate custom user attributes over SCIM#165

Open
thib-d wants to merge 1 commit intomitodl:mainfrom
thib-d:feat/scim-custom-user-attributes
Open

feat: propagate custom user attributes over SCIM#165
thib-d wants to merge 1 commit intomitodl:mainfrom
thib-d:feat/scim-custom-user-attributes

Conversation

@thib-d
Copy link
Copy Markdown

@thib-d thib-d commented Mar 21, 2026

Summary

  • propagate non built-in Keycloak user attributes as SCIM additional properties
  • include the same custom attributes in user PATCH operations
  • document the receiver-side requirement for matching Keycloak User Profile attributes

Notes

  • built-in fields remain mapped through the standard SCIM user schema
  • custom attributes are sent as single-valued strings

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the SCIM user provisioning functionality by enabling the propagation of custom user attributes defined in Keycloak. Previously, only standard attributes were synchronized. With this change, any additional, single-valued string attributes configured in Keycloak will now be sent to the SCIM server during user creation and updates, including support for PATCH operations. This provides greater flexibility and extensibility for integrating Keycloak with SCIM-compliant identity providers that require custom user data.

Highlights

  • SCIM Custom Attribute Propagation: Non-built-in Keycloak user attributes are now propagated as SCIM additional properties during outbound user provisioning.
  • PATCH Operation Support: Custom attributes are included in user PATCH operations, allowing updates to these attributes on the SCIM server.
  • Documentation Update: The README.md has been updated to document the propagation of custom user attributes and the requirement for matching attributes on the receiving SCIM server.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the propagation of custom user attributes over SCIM, a valuable feature enhancement. The changes primarily affect UserAdapter.java to handle the extraction and transmission of these attributes, along with documentation updates in README.md. The implementation is mostly sound, but I have identified a couple of areas for improvement regarding code quality, encapsulation, and readability. My review includes suggestions to make the code more robust and maintainable.

}

public Map<String, String> getCustomAttributes() {
return customAttributes;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The getCustomAttributes method returns a direct reference to the internal customAttributes map. This allows external code to modify the adapter's internal state, which can lead to unexpected behavior. It's better to return an unmodifiable view of the map to maintain encapsulation and prevent accidental modifications.

Suggested change
return customAttributes;
return java.util.Collections.unmodifiableMap(customAttributes);

Comment on lines +309 to +315
String value = values.stream()
.filter(StringUtils::isNotBlank)
.findFirst()
.orElse(values.get(0));
if (StringUtils.isNotBlank(value)) {
attributes.put(attributeName, value);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic to extract the first non-blank attribute value can be simplified. The current implementation is a bit convoluted with .orElse() and a separate if check. Using .ifPresent() on the Optional returned by findFirst() would make the code more concise, readable, and idiomatic for stream processing.

Suggested change
String value = values.stream()
.filter(StringUtils::isNotBlank)
.findFirst()
.orElse(values.get(0));
if (StringUtils.isNotBlank(value)) {
attributes.put(attributeName, value);
}
values.stream()
.filter(StringUtils::isNotBlank)
.findFirst()
.ifPresent(value -> attributes.put(attributeName, value));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant