KEYCLOAK-3719 Add 'options' to ProviderConfigProperty and use it for 'List' type instead of defaultValue

This commit is contained in:
mposolda 2016-10-17 17:41:02 +02:00
parent 4ce5f9e087
commit 00879b39b7
20 changed files with 63 additions and 36 deletions

View file

@ -17,6 +17,8 @@
package org.keycloak.representations.idm;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -27,6 +29,7 @@ public class ConfigPropertyRepresentation {
protected String helpText;
protected String type;
protected Object defaultValue;
protected List<String> options;
protected boolean secret;
public String getName() {
@ -69,6 +72,14 @@ public class ConfigPropertyRepresentation {
this.helpText = helpText;
}
public List<String> getOptions() {
return options;
}
public void setOptions(List<String> options) {
this.options = options;
}
public boolean isSecret() {
return secret;
}

View file

@ -17,6 +17,8 @@
package org.keycloak.federation.ldap.mappers;
import java.util.List;
import org.keycloak.Config;
import org.keycloak.federation.ldap.LDAPFederationProvider;
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
@ -75,13 +77,13 @@ public abstract class AbstractLDAPFederationMapperFactory implements UserFederat
public void close() {
}
public static ProviderConfigProperty createConfigProperty(String name, String label, String helpText, String type, Object defaultValue) {
public static ProviderConfigProperty createConfigProperty(String name, String label, String helpText, String type, List<String> options) {
ProviderConfigProperty configProperty = new ProviderConfigProperty();
configProperty.setName(name);
configProperty.setLabel(label);
configProperty.setHelpText(helpText);
configProperty.setType(type);
configProperty.setDefaultValue(defaultValue);
configProperty.setOptions(options);
return configProperty;
}

View file

@ -782,6 +782,7 @@ public class ModelToRepresentation {
propRep.setLabel(prop.getLabel());
propRep.setType(prop.getType());
propRep.setDefaultValue(prop.getDefaultValue());
propRep.setOptions(prop.getOptions());
propRep.setHelpText(prop.getHelpText());
propRep.setSecret(prop.isSecret());
return propRep;

View file

@ -17,6 +17,8 @@
package org.keycloak.provider;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -46,6 +48,7 @@ public class ProviderConfigProperty {
protected String helpText;
protected String type = STRING_TYPE;
protected Object defaultValue;
protected List<String> options;
protected boolean secret;
public ProviderConfigProperty() {
@ -96,6 +99,14 @@ public class ProviderConfigProperty {
this.defaultValue = defaultValue;
}
public List<String> getOptions() {
return options;
}
public void setOptions(List<String> options) {
this.options = options;
}
public String getHelpText() {
return helpText;
}

View file

@ -17,6 +17,7 @@
package org.keycloak.provider;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@ -43,14 +44,17 @@ public class ProviderConfigurationBuilder {
return this;
}
public ProviderConfigurationBuilder property(String name, String label, String helpText, String type, Object defaultValue, boolean secret) {
public ProviderConfigurationBuilder property(String name, String label, String helpText, String type, Object defaultValue, List<String> options, boolean secret) {
ProviderConfigProperty property = new ProviderConfigProperty(name, label, helpText, type, defaultValue);
property.setOptions(options);
property.setSecret(secret);
properties.add(property);
return this;
}
public ProviderConfigurationBuilder property(String name, String label, String helpText, String type, Object defaultValue) {
properties.add(new ProviderConfigProperty(name, label, helpText, type, defaultValue));
public ProviderConfigurationBuilder property(String name, String label, String helpText, String type, Object defaultValue, List<String> options) {
ProviderConfigProperty property = new ProviderConfigProperty(name, label, helpText, type, defaultValue);
property.setOptions(options);
properties.add(property);
return this;
}
@ -65,6 +69,7 @@ public class ProviderConfigurationBuilder {
private String helpText;
private String type;
private Object defaultValue;
private List<String> options;
private boolean secret;
public ProviderConfigPropertyBuilder name(String name) {
@ -92,6 +97,11 @@ public class ProviderConfigurationBuilder {
return this;
}
public ProviderConfigPropertyBuilder options(String... options) {
this.options = Arrays.asList(options);
return this;
}
public ProviderConfigPropertyBuilder secret(boolean secret) {
this.secret = secret;
return this;
@ -104,6 +114,7 @@ public class ProviderConfigurationBuilder {
property.setHelpText(helpText);
property.setType(type);
property.setDefaultValue(defaultValue);
property.setOptions(options);
property.setSecret(secret);
ProviderConfigurationBuilder.this.properties.add(property);
return ProviderConfigurationBuilder.this;

View file

@ -108,7 +108,8 @@ public class IdpReviewProfileAuthenticatorFactory implements AuthenticatorFactor
property.setLabel("{{:: 'update-profile-on-first-login' | translate}}");
property.setType(ProviderConfigProperty.LIST_TYPE);
List<String> updateProfileValues = Arrays.asList(IdentityProviderRepresentation.UPFLM_ON, IdentityProviderRepresentation.UPFLM_MISSING, IdentityProviderRepresentation.UPFLM_OFF);
property.setDefaultValue(updateProfileValues);
property.setOptions(updateProfileValues);
property.setDefaultValue(IdentityProviderRepresentation.UPFLM_MISSING);
property.setHelpText("Define conditions under which a user has to review and update his profile after first-time login. Value 'On' means that"
+ " page for reviewing profile will be displayed and user can review and update his profile. Value 'off' means that page won't be displayed."
+ " Value 'missing' means that page is displayed just when some required attribute is missing (wasn't downloaded from identity provider). Value 'missing' is the default one."

View file

@ -156,7 +156,7 @@ public class ConditionalOtpFormAuthenticatorFactory implements AuthenticatorFact
defaultOutcome.setType(LIST_TYPE);
defaultOutcome.setName(DEFAULT_OTP_OUTCOME);
defaultOutcome.setLabel("Fallback OTP handling");
defaultOutcome.setDefaultValue(asList(SKIP, FORCE));
defaultOutcome.setOptions(asList(SKIP, FORCE));
defaultOutcome.setHelpText("What to do in case of every check abstains. Defaults to force OTP authentication.");
return asList(forceOtpUserAttribute, skipOtpRole, forceOtpRole, skipOtpForHttpHeader, forceOtpForHttpHeader, defaultOutcome);

View file

@ -66,7 +66,7 @@ public class HardcodedClaim extends AbstractOIDCProtocolMapper implements OIDCAc
types.add("int");
types.add("boolean");
property.setType(ProviderConfigProperty.LIST_TYPE);
property.setDefaultValue(types);
property.setOptions(types);
property.setHelpText("JSON type that should be used for the value of the claim. long, int, boolean, and String are valid values.");
configProperties.add(property);
property = new ProviderConfigProperty();

View file

@ -182,7 +182,7 @@ public class OIDCAttributeMapperHelper {
types.add("int");
types.add("boolean");
property.setType(ProviderConfigProperty.LIST_TYPE);
property.setDefaultValue(types);
property.setOptions(types);
property.setHelpText(JSON_TYPE_TOOLTIP);
configProperties.add(property);
property = new ProviderConfigProperty();

View file

@ -85,7 +85,7 @@ public class AttributeStatementHelper {
types.add(AttributeStatementHelper.URI_REFERENCE);
types.add(AttributeStatementHelper.UNSPECIFIED);
property.setType(ProviderConfigProperty.LIST_TYPE);
property.setDefaultValue(types);
property.setOptions(types);
configProperties.add(property);
}

View file

@ -65,7 +65,7 @@ public class GroupMembershipMapper extends AbstractSAMLProtocolMapper implements
types.add(AttributeStatementHelper.URI_REFERENCE);
types.add(AttributeStatementHelper.UNSPECIFIED);
property.setType(ProviderConfigProperty.LIST_TYPE);
property.setDefaultValue(types);
property.setOptions(types);
configProperties.add(property);
property = new ProviderConfigProperty();
property.setName(SINGLE_GROUP_ATTRIBUTE);

View file

@ -69,7 +69,7 @@ public class RoleListMapper extends AbstractSAMLProtocolMapper implements SAMLRo
types.add(AttributeStatementHelper.URI_REFERENCE);
types.add(AttributeStatementHelper.UNSPECIFIED);
property.setType(ProviderConfigProperty.LIST_TYPE);
property.setDefaultValue(types);
property.setOptions(types);
configProperties.add(property);
property = new ProviderConfigProperty();
property.setName(SINGLE_ROLE_ATTRIBUTE);

View file

@ -60,7 +60,7 @@ public class ClientTemplatesClientRegistrationPolicyFactory extends AbstractClie
property.setType(ProviderConfigProperty.MULTIVALUED_LIST_TYPE);
if (session != null) {
property.setDefaultValue(getClientTemplates(session));
property.setOptions(getClientTemplates(session));
}
configProperties = Collections.singletonList(property);

View file

@ -58,7 +58,7 @@ public class ProtocolMappersClientRegistrationPolicyFactory extends AbstractClie
property.setLabel("allowed-protocol-mappers.label");
property.setHelpText("allowed-protocol-mappers.tooltip");
property.setType(ProviderConfigProperty.MULTIVALUED_LIST_TYPE);
property.setDefaultValue(getProtocolMapperFactoryIds());
property.setOptions(getProtocolMapperFactoryIds());
configProperties.add(property);
property = new ProviderConfigProperty();

View file

@ -36,12 +36,12 @@ import static org.keycloak.provider.ProviderConfigProperty.STRING_TYPE;
public class TestImplProviderFactory implements TestProviderFactory {
private List<ProviderConfigProperty> config = ProviderConfigurationBuilder.create()
.property("secret", "Secret", "A secret value", STRING_TYPE, null, true)
.property("number", "Number", "A number value", STRING_TYPE, null, false)
.property("required", "Required", "A required value", STRING_TYPE, null, false)
.property("val1", "Value 1", "Some more values", STRING_TYPE, null, false)
.property("val2", "Value 2", "Some more values", STRING_TYPE, null, false)
.property("val3", "Value 3", "Some more values", STRING_TYPE, null, false)
.property("secret", "Secret", "A secret value", STRING_TYPE, null, null, true)
.property("number", "Number", "A number value", STRING_TYPE, null, null, false)
.property("required", "Required", "A required value", STRING_TYPE, null, null, false)
.property("val1", "Value 1", "Some more values", STRING_TYPE, null, null, false)
.property("val2", "Value 2", "Some more values", STRING_TYPE, null, null, false)
.property("val3", "Value 3", "Some more values", STRING_TYPE, null, null, false)
.build();
@Override

View file

@ -20,25 +20,13 @@ package org.keycloak.testsuite.admin;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.ComponentsResource;
import org.keycloak.common.util.CertificateUtils;
import org.keycloak.common.util.KeyUtils;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.common.util.PemUtils;
import org.keycloak.keys.Attributes;
import org.keycloak.keys.KeyProvider;
import org.keycloak.keys.RsaKeyProviderFactory;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.ErrorRepresentation;
import org.keycloak.representations.idm.KeysMetadataRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.components.TestImplProviderFactory;
import org.keycloak.testsuite.components.TestProvider;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.Collections;
import java.util.List;
import java.util.Map;

View file

@ -329,7 +329,7 @@ public class ClientRegistrationPoliciesTest extends AbstractClientRegistrationTe
ConfigPropertyRepresentation allowedProtocolMappers = list.get(0);
Assert.assertEquals(allowedProtocolMappers.getName(), expectedConfigPropName);
return (List<String>) allowedProtocolMappers.getDefaultValue();
return allowedProtocolMappers.getOptions();
}

View file

@ -1830,6 +1830,8 @@ module.controller('ClientProtocolMapperCreateCtrl', function($scope, realm, serv
}, function(error) {
if (error.status == 400 && error.data.error_description) {
Notifications.error(error.data.error_description);
} else if (error.status == 409 && error.data.errorMessage) {
Notifications.error(error.data.errorMessage);
} else {
Notifications.error('Unexpected error when updating protocol mapper');
}

View file

@ -12,13 +12,13 @@
<input ng-model="config[ option.name ][0]" value="'true'" id="option.name" name="option.name" onoffswitchstring on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
</div>
<div class="col-md-6" data-ng-show="option.type == 'List'">
<select ng-model="config[ option.name ][0]" ng-options="data for data in option.defaultValue">
<select ng-model="config[ option.name ][0]" ng-options="data for data in option.options">
<option value="" selected> {{:: 'selectOne' | translate}} </option>
</select>
</div>
<div class="col-md-6" data-ng-show="option.type == 'MultivaluedList'">
<select ui-select2 data-ng-model="config[ option.name ]" data-placeholder="{{:: 'selectMultiple' | translate}}..." multiple>
<option ng-repeat="val in option.defaultValue" value="{{val}}" ng-selected="true">{{val}}</option>
<option ng-repeat="val in option.options" value="{{val}}" ng-selected="true">{{val}}</option>
</select>
</div>
<div class="col-md-6" data-ng-show="option.type == 'Role'">

View file

@ -12,7 +12,7 @@
<input ng-model="config[ option.name ]" value="'true'" name="option.name" id="option.name" onoffswitchstring on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
</div>
<div class="col-md-6" data-ng-show="option.type == 'List'">
<select ng-model="config[ option.name ]" ng-options="data for data in option.defaultValue">
<select ng-model="config[ option.name ]" ng-options="data for data in option.options">
<option value="" selected> {{:: 'selectOne' | translate}} </option>
</select>
</div>