MAP_TYPE property doesn't activate the "Save" button when updating own Jpa impl
Arnaud-FELTZ opened this issue · comments
Before reporting an issue
- I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
admin/ui
Describe the bug
I am currently developing a custom UserStorageProviderFactory
for Keycloak 24.0.4, which includes an admin configuration page.
This page is designed to collect several pieces of information from the administrator:
Property | Type | Required |
---|---|---|
API URI | STRING_TYPE | Yes |
Trust Certificates | BOOLEAN_TYPE | Yes |
Headers | MAP_TYPE | No |
The issue arises when attempting to modify the custom headers on the admin page. Despite making changes to the headers, the "Save" button remains disabled (greyed out), preventing the submission of the modified configuration.
This behavior persists even after ensuring that both keys and values are provided for each entry in the map of headers. The expected behavior is for the "Save" button to become active (enabled) whenever any configuration changes are made, allowing the administrator to save the updated settings.
My implementation:
package com.contoso.keycloak.authenticator.jpa;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.keycloak.component.ComponentModel;
import org.keycloak.component.ComponentValidationException;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.storage.UserStorageProviderFactory;
import org.keycloak.validate.validators.UriValidator;
public class JpaStorageProviderFactory implements UserStorageProviderFactory<JpaStorageProvider> {
public static final String PROVIDER_ID = "CONTOSO-JPA";
private static final List<ProviderConfigProperty> configProperties = new ArrayList<>();
static {
// API URL
ProviderConfigProperty apiUrl = new ProviderConfigProperty();
apiUrl.setName("apiUrl");
apiUrl.setLabel("API URL");
apiUrl.setType(ProviderConfigProperty.STRING_TYPE);
apiUrl.setHelpText("The URL of the external API used to authenticate suppliers.");
apiUrl.setRequired(true);
configProperties.add(apiUrl);
// Trust Certificate
ProviderConfigProperty trustCertificate = new ProviderConfigProperty();
trustCertificate.setName("trustCertificate");
trustCertificate.setLabel("Trust Certificate");
trustCertificate.setType(ProviderConfigProperty.BOOLEAN_TYPE);
trustCertificate.setHelpText("Whether to trust HTTPS certificate.");
trustCertificate.setDefaultValue(true);
configProperties.add(trustCertificate);
// Headers
ProviderConfigProperty headers = new ProviderConfigProperty();
headers.setName("headers");
headers.setLabel("Headers");
headers.setType(ProviderConfigProperty.MAP_TYPE);
headers.setHelpText("Custom headers to add to the request when calling the API.");
configProperties.add(headers);
}
@Override
public JpaStorageProvider create(KeycloakSession session, ComponentModel model) {
return new JpaStorageProvider(session, model);
}
@Override
public String getId() {
return PROVIDER_ID;
}
@Override
public String getHelpText() {
return "Contoso - JPA";
}
@Override
public void close() {
}
@Override
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
}
@Override
public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel config)
throws ComponentValidationException {
// Validate the apiUrl configuration
String apiUrl = config.getConfig().getFirst("apiUrl");
if (apiUrl == null || apiUrl.isEmpty()) {
throw new ComponentValidationException("API URL is required.");
}
// Use Keycloak's built-in URL validator
UriValidator uriValidator = new UriValidator();
try {
URI apiUri = URI.create(apiUrl);
if (!uriValidator.validateUri(apiUri, Set.copyOf(UriValidator.DEFAULT_ALLOWED_SCHEMES), false, true)) {
throw new ComponentValidationException("Invalid API URL.");
}
} catch (Exception e) {
throw new ComponentValidationException("Invalid API URL.");
}
}
}
Capture below, once created, I return on the JPA to modify it. Adding the headers b/c (red squared) doesn't activate the Save
button.
Version
24.0.4
Regression
- The issue is a regression
Expected behavior
When adding/updating/deleting a value in a MAP_TYPE property, the Save
button should be enabled.
Actual behavior
When adding/updating/deleting a value in a MAP_TYPE entry, the Save
button remains disabled.
How to Reproduce?
- Create a custom JPA using provided code for Factory
- Compile and add resulting provider to keycloak
- Build and start keycloak
- Create your custom JPA and validate
- Now return on your custom JPA and try to modify the "Headers",
Save
remains disabled while you added/updated/removed entries
Anything else?
No response