Revert "[KEYCLOAK-18425] - Allow mapping user profile attributes"
This reverts commit 3e07ca3c
This commit is contained in:
parent
f1ee2826c1
commit
7f34af4016
11 changed files with 8 additions and 321 deletions
|
@ -62,8 +62,6 @@ public class ProviderConfigProperty {
|
||||||
*/
|
*/
|
||||||
public static final String MAP_TYPE ="Map";
|
public static final String MAP_TYPE ="Map";
|
||||||
|
|
||||||
public static final String USER_PROFILE_ATTRIBUTE_LIST_TYPE="UserProfileAttributeList";
|
|
||||||
|
|
||||||
protected String name;
|
protected String name;
|
||||||
protected String label;
|
protected String label;
|
||||||
protected String helpText;
|
protected String helpText;
|
||||||
|
|
|
@ -48,7 +48,6 @@ public class ProtocolMapperUtils {
|
||||||
public static final String USER_MODEL_PROPERTY_HELP_TEXT = "usermodel.prop.tooltip";
|
public static final String USER_MODEL_PROPERTY_HELP_TEXT = "usermodel.prop.tooltip";
|
||||||
public static final String USER_MODEL_ATTRIBUTE_LABEL = "usermodel.attr.label";
|
public static final String USER_MODEL_ATTRIBUTE_LABEL = "usermodel.attr.label";
|
||||||
public static final String USER_MODEL_ATTRIBUTE_HELP_TEXT = "usermodel.attr.tooltip";
|
public static final String USER_MODEL_ATTRIBUTE_HELP_TEXT = "usermodel.attr.tooltip";
|
||||||
public static final String USER_PROFILE_ATTRIBUTE = "user.profile.attribute";
|
|
||||||
|
|
||||||
public static final String USER_MODEL_CLIENT_ROLE_MAPPING_CLIENT_ID = "usermodel.clientRoleMapping.clientId";
|
public static final String USER_MODEL_CLIENT_ROLE_MAPPING_CLIENT_ID = "usermodel.clientRoleMapping.clientId";
|
||||||
public static final String USER_MODEL_CLIENT_ROLE_MAPPING_CLIENT_ID_LABEL = "usermodel.clientRoleMapping.clientId.label";
|
public static final String USER_MODEL_CLIENT_ROLE_MAPPING_CLIENT_ID_LABEL = "usermodel.clientRoleMapping.clientId.label";
|
||||||
|
|
|
@ -233,29 +233,11 @@ public class OIDCAttributeMapperHelper {
|
||||||
String tokenClaimName, String claimType,
|
String tokenClaimName, String claimType,
|
||||||
boolean accessToken, boolean idToken,
|
boolean accessToken, boolean idToken,
|
||||||
String mapperId) {
|
String mapperId) {
|
||||||
return createClaimMapper(name, userAttribute, null, tokenClaimName, claimType, accessToken, idToken, true, mapperId);
|
return createClaimMapper(name, userAttribute,tokenClaimName, claimType, accessToken, idToken, true, mapperId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProtocolMapperModel createClaimMapper(String name,
|
public static ProtocolMapperModel createClaimMapper(String name,
|
||||||
String userAttribute,
|
String userAttribute,
|
||||||
String userProfileAttribute,
|
|
||||||
String tokenClaimName, String claimType,
|
|
||||||
boolean accessToken, boolean idToken,
|
|
||||||
String mapperId) {
|
|
||||||
return createClaimMapper(name, userAttribute, userProfileAttribute, tokenClaimName, claimType, accessToken, idToken, true, mapperId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProtocolMapperModel createClaimMapper(String name,
|
|
||||||
String userAttribute,
|
|
||||||
String tokenClaimName, String claimType,
|
|
||||||
boolean accessToken, boolean idToken, boolean userinfo,
|
|
||||||
String mapperId) {
|
|
||||||
return createClaimMapper(name, userAttribute, null, tokenClaimName, claimType, accessToken, idToken, userinfo, mapperId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProtocolMapperModel createClaimMapper(String name,
|
|
||||||
String userAttribute,
|
|
||||||
String userProfileAttribute,
|
|
||||||
String tokenClaimName, String claimType,
|
String tokenClaimName, String claimType,
|
||||||
boolean accessToken, boolean idToken, boolean userinfo,
|
boolean accessToken, boolean idToken, boolean userinfo,
|
||||||
String mapperId) {
|
String mapperId) {
|
||||||
|
@ -265,10 +247,6 @@ public class OIDCAttributeMapperHelper {
|
||||||
mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||||
Map<String, String> config = new HashMap<String, String>();
|
Map<String, String> config = new HashMap<String, String>();
|
||||||
config.put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
|
config.put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
|
||||||
if (userProfileAttribute != null) {
|
|
||||||
config.put(ProtocolMapperUtils.USER_PROFILE_ATTRIBUTE, userProfileAttribute);
|
|
||||||
}
|
|
||||||
|
|
||||||
config.put(TOKEN_CLAIM_NAME, tokenClaimName);
|
config.put(TOKEN_CLAIM_NAME, tokenClaimName);
|
||||||
config.put(JSON_TYPE, claimType);
|
config.put(JSON_TYPE, claimType);
|
||||||
if (accessToken) config.put(INCLUDE_IN_ACCESS_TOKEN, "true");
|
if (accessToken) config.put(INCLUDE_IN_ACCESS_TOKEN, "true");
|
||||||
|
|
|
@ -18,19 +18,16 @@
|
||||||
package org.keycloak.protocol.oidc.mappers;
|
package org.keycloak.protocol.oidc.mappers;
|
||||||
|
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.protocol.ProtocolMapperUtils;
|
import org.keycloak.protocol.ProtocolMapperUtils;
|
||||||
import org.keycloak.provider.ProviderConfigProperty;
|
import org.keycloak.provider.ProviderConfigProperty;
|
||||||
import org.keycloak.representations.IDToken;
|
import org.keycloak.representations.IDToken;
|
||||||
import org.keycloak.userprofile.DeclarativeUserProfileProvider;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mappings UserModel.attribute to an ID Token claim. Token claim name can be a full qualified nested object name,
|
* Mappings UserModel.attribute to an ID Token claim. Token claim name can be a full qualified nested object name,
|
||||||
|
@ -52,14 +49,6 @@ public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements O
|
||||||
property.setHelpText(ProtocolMapperUtils.USER_MODEL_ATTRIBUTE_HELP_TEXT);
|
property.setHelpText(ProtocolMapperUtils.USER_MODEL_ATTRIBUTE_HELP_TEXT);
|
||||||
property.setType(ProviderConfigProperty.STRING_TYPE);
|
property.setType(ProviderConfigProperty.STRING_TYPE);
|
||||||
configProperties.add(property);
|
configProperties.add(property);
|
||||||
|
|
||||||
property = new ProviderConfigProperty();
|
|
||||||
property.setName(ProtocolMapperUtils.USER_PROFILE_ATTRIBUTE);
|
|
||||||
property.setLabel(ProtocolMapperUtils.USER_MODEL_ATTRIBUTE_LABEL);
|
|
||||||
property.setHelpText(ProtocolMapperUtils.USER_MODEL_ATTRIBUTE_HELP_TEXT);
|
|
||||||
property.setType(ProviderConfigProperty.USER_PROFILE_ATTRIBUTE_LIST_TYPE);
|
|
||||||
configProperties.add(property);
|
|
||||||
|
|
||||||
OIDCAttributeMapperHelper.addAttributeConfig(configProperties, UserAttributeMapper.class);
|
OIDCAttributeMapperHelper.addAttributeConfig(configProperties, UserAttributeMapper.class);
|
||||||
|
|
||||||
property = new ProviderConfigProperty();
|
property = new ProviderConfigProperty();
|
||||||
|
@ -107,25 +96,13 @@ public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements O
|
||||||
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
|
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
|
||||||
|
|
||||||
UserModel user = userSession.getUser();
|
UserModel user = userSession.getUser();
|
||||||
String attributeName = getAttributeName(mappingModel, userSession.getRealm());
|
String attributeName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_ATTRIBUTE);
|
||||||
boolean aggregateAttrs = Boolean.valueOf(mappingModel.getConfig().get(ProtocolMapperUtils.AGGREGATE_ATTRS));
|
boolean aggregateAttrs = Boolean.valueOf(mappingModel.getConfig().get(ProtocolMapperUtils.AGGREGATE_ATTRS));
|
||||||
Collection<String> attributeValue = KeycloakModelUtils.resolveAttribute(user, attributeName, aggregateAttrs);
|
Collection<String> attributeValue = KeycloakModelUtils.resolveAttribute(user, attributeName, aggregateAttrs);
|
||||||
if (attributeValue == null) return;
|
if (attributeValue == null) return;
|
||||||
OIDCAttributeMapperHelper.mapClaim(token, mappingModel, attributeValue);
|
OIDCAttributeMapperHelper.mapClaim(token, mappingModel, attributeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getAttributeName(ProtocolMapperModel mappingModel, RealmModel realm) {
|
|
||||||
Map<String, String> config = mappingModel.getConfig();
|
|
||||||
String name = config.get(ProtocolMapperUtils.USER_ATTRIBUTE);
|
|
||||||
|
|
||||||
if (realm.getAttribute(DeclarativeUserProfileProvider.REALM_USER_PROFILE_ENABLED, false)) {
|
|
||||||
// defaults to the default config property for backward compatibility
|
|
||||||
return config.getOrDefault(ProtocolMapperUtils.USER_PROFILE_ATTRIBUTE, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProtocolMapperModel createClaimMapper(String name,
|
public static ProtocolMapperModel createClaimMapper(String name,
|
||||||
String userAttribute,
|
String userAttribute,
|
||||||
String tokenClaimName, String claimType,
|
String tokenClaimName, String claimType,
|
||||||
|
@ -139,18 +116,7 @@ public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements O
|
||||||
String tokenClaimName, String claimType,
|
String tokenClaimName, String claimType,
|
||||||
boolean accessToken, boolean idToken,
|
boolean accessToken, boolean idToken,
|
||||||
boolean multivalued, boolean aggregateAttrs) {
|
boolean multivalued, boolean aggregateAttrs) {
|
||||||
return createClaimMapper(name, userAttribute, null, tokenClaimName, claimType,
|
|
||||||
accessToken, idToken, multivalued, aggregateAttrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProtocolMapperModel createClaimMapper(String name,
|
|
||||||
String userAttribute,
|
|
||||||
String userProfileAttribute,
|
|
||||||
String tokenClaimName, String claimType,
|
|
||||||
boolean accessToken, boolean idToken,
|
|
||||||
boolean multivalued, boolean aggregateAttrs) {
|
|
||||||
ProtocolMapperModel mapper = OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute,
|
ProtocolMapperModel mapper = OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute,
|
||||||
userProfileAttribute,
|
|
||||||
tokenClaimName, claimType,
|
tokenClaimName, claimType,
|
||||||
accessToken, idToken,
|
accessToken, idToken,
|
||||||
PROVIDER_ID);
|
PROVIDER_ID);
|
||||||
|
|
|
@ -103,7 +103,6 @@ import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -289,11 +288,10 @@ public class UserResource {
|
||||||
|
|
||||||
if (rep.getAttributes() != null) {
|
if (rep.getAttributes() != null) {
|
||||||
Map<String, List<String>> allowedAttributes = profile.getAttributes().getReadable(false);
|
Map<String, List<String>> allowedAttributes = profile.getAttributes().getReadable(false);
|
||||||
Iterator<String> iterator = rep.getAttributes().keySet().iterator();
|
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
for (String attributeName : rep.getAttributes().keySet()) {
|
||||||
if (!allowedAttributes.containsKey(iterator.next())) {
|
if (!allowedAttributes.containsKey(attributeName)) {
|
||||||
iterator.remove();
|
rep.getAttributes().remove(attributeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1218,7 +1218,7 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OAuthClient.AccessTokenResponse browserLogin(String clientSecret, String username, String password) {
|
private OAuthClient.AccessTokenResponse browserLogin(String clientSecret, String username, String password) {
|
||||||
OAuthClient.AuthorizationEndpointResponse authzEndpointResponse = oauth.doLogin(username, password);
|
OAuthClient.AuthorizationEndpointResponse authzEndpointResponse = oauth.doLogin(username, password);
|
||||||
return oauth.doAccessTokenRequest(authzEndpointResponse.getCode(), clientSecret);
|
return oauth.doAccessTokenRequest(authzEndpointResponse.getCode(), clientSecret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,160 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.testsuite.oauth;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.anyOf;
|
|
||||||
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
|
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.isEmptyOrNullString;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
|
||||||
import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId;
|
|
||||||
import static org.keycloak.testsuite.admin.ApiUtil.findClientResourceByClientId;
|
|
||||||
import static org.keycloak.testsuite.admin.ApiUtil.findUserByUsernameId;
|
|
||||||
import static org.keycloak.testsuite.forms.VerifyProfileTest.PERMISSIONS_ALL;
|
|
||||||
import static org.keycloak.testsuite.util.ProtocolMapperUtil.createAddressMapper;
|
|
||||||
import static org.keycloak.testsuite.util.ProtocolMapperUtil.createClaimMapper;
|
|
||||||
import static org.keycloak.testsuite.util.ProtocolMapperUtil.createHardcodedClaim;
|
|
||||||
import static org.keycloak.testsuite.util.ProtocolMapperUtil.createHardcodedRole;
|
|
||||||
import static org.keycloak.testsuite.util.ProtocolMapperUtil.createRoleNameMapper;
|
|
||||||
import static org.keycloak.testsuite.util.ProtocolMapperUtil.createScriptMapper;
|
|
||||||
import static org.keycloak.userprofile.DeclarativeUserProfileProvider.REALM_USER_PROFILE_ENABLED;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hamcrest.CoreMatchers;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.keycloak.admin.client.resource.ClientResource;
|
|
||||||
import org.keycloak.admin.client.resource.ClientScopeResource;
|
|
||||||
import org.keycloak.admin.client.resource.ProtocolMappersResource;
|
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
|
||||||
import org.keycloak.admin.client.resource.UserResource;
|
|
||||||
import org.keycloak.common.Profile;
|
|
||||||
import org.keycloak.common.util.UriUtils;
|
|
||||||
import org.keycloak.jose.jws.JWSInput;
|
|
||||||
import org.keycloak.models.AccountRoles;
|
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
|
||||||
import org.keycloak.protocol.oidc.mappers.AddressMapper;
|
|
||||||
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
|
|
||||||
import org.keycloak.representations.AccessToken;
|
|
||||||
import org.keycloak.representations.AddressClaimSet;
|
|
||||||
import org.keycloak.representations.IDToken;
|
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
|
||||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
|
||||||
import org.keycloak.representations.idm.GroupRepresentation;
|
|
||||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
|
||||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
|
||||||
import org.keycloak.testsuite.Assert;
|
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
|
||||||
import org.keycloak.testsuite.admin.ApiUtil;
|
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
|
||||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
|
||||||
import org.keycloak.testsuite.forms.VerifyProfileTest;
|
|
||||||
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
|
||||||
import org.keycloak.testsuite.updaters.ProtocolMappersUpdater;
|
|
||||||
import org.keycloak.testsuite.util.ClientManager;
|
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.util.ProtocolMapperUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class OIDCProtocolMappersUserProfileTest extends OIDCProtocolMappersTest {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
|
||||||
super.addTestRealms(testRealms);
|
|
||||||
final RealmRepresentation testRealm = testRealms.get(0);
|
|
||||||
if (testRealm.getAttributes() == null) {
|
|
||||||
testRealm.setAttributes(new HashMap<>());
|
|
||||||
}
|
|
||||||
testRealm.getAttributes().put(REALM_USER_PROFILE_ENABLED, Boolean.TRUE.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void onBefore() {
|
|
||||||
VerifyProfileTest.setUserProfileConfiguration(adminClient.realm("test"), "{\"attributes\": ["
|
|
||||||
+ "{\"name\": \"firstName\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"lastName\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"group-value\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"street\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"departments\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"locality\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"region_some\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"postal_code\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"country\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"formatted\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"phone\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"json-attribute\"," + PERMISSIONS_ALL + "},"
|
|
||||||
+ "{\"name\": \"json-attribute-multi\"," + PERMISSIONS_ALL + "}"
|
|
||||||
+ "]}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMappingFromAttribute() {
|
|
||||||
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
|
||||||
|
|
||||||
app.getProtocolMappers().createMapper(createClaimMapper("user profile attribute precedence", "lastName", "firstName", "c_fn", "String", true, true, false)).close();
|
|
||||||
|
|
||||||
OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password");
|
|
||||||
|
|
||||||
IDToken idToken = oauth.verifyIDToken(response.getIdToken());
|
|
||||||
|
|
||||||
Object firstName = idToken.getOtherClaims().get("c_fn");
|
|
||||||
assertThat(firstName, instanceOf(String.class));
|
|
||||||
assertThat(firstName, is("Tom"));
|
|
||||||
|
|
||||||
oauth.openLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFallbackToDefaultConfigProperty() {
|
|
||||||
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
|
||||||
|
|
||||||
app.getProtocolMappers().createMapper(createClaimMapper("user profile default config property", "lastName", null, "c_fn_from_default", "String", true, true, false)).close();
|
|
||||||
|
|
||||||
OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password");
|
|
||||||
|
|
||||||
IDToken idToken = oauth.verifyIDToken(response.getIdToken());
|
|
||||||
|
|
||||||
Object firstName = idToken.getOtherClaims().get("c_fn_from_default");
|
|
||||||
assertThat(firstName, instanceOf(String.class));
|
|
||||||
assertThat(firstName, is("Brady"));
|
|
||||||
|
|
||||||
oauth.openLogout();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -91,15 +91,6 @@ public class ProtocolMapperUtil {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProtocolMapperRepresentation createClaimMapper(String name,
|
|
||||||
String userAttribute, String userProfileAttribute,
|
|
||||||
String tokenClaimName, String claimType,
|
|
||||||
boolean accessToken, boolean idToken, boolean multivalued) {
|
|
||||||
return ModelToRepresentation.toRepresentation(UserAttributeMapper.createClaimMapper(name, userAttribute, userProfileAttribute, tokenClaimName,
|
|
||||||
claimType, accessToken, idToken, multivalued, false));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProtocolMapperRepresentation createClaimMapper(String name,
|
public static ProtocolMapperRepresentation createClaimMapper(String name,
|
||||||
String userAttribute,
|
String userAttribute,
|
||||||
String tokenClaimName, String claimType,
|
String tokenClaimName, String claimType,
|
||||||
|
|
|
@ -3048,9 +3048,8 @@ module.controller('RoleSelectorModalCtrl', function($scope, realm, config, confi
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('ProviderConfigCtrl', function ($modal, $scope, $route, ComponentUtils, Client, UserProfile, Current) {
|
module.controller('ProviderConfigCtrl', function ($modal, $scope, $route, ComponentUtils, Client) {
|
||||||
clientSelectControl($scope, $route.current.params.realm, Client);
|
clientSelectControl($scope, $route.current.params.realm, Client);
|
||||||
userProfileAttributeSelectControl($scope, $route.current.params.realm, UserProfile);
|
|
||||||
$scope.fileNames = {};
|
$scope.fileNames = {};
|
||||||
$scope.newMapEntries = {};
|
$scope.newMapEntries = {};
|
||||||
var cachedMaps = {};
|
var cachedMaps = {};
|
||||||
|
@ -3074,38 +3073,6 @@ module.controller('ProviderConfigCtrl', function ($modal, $scope, $route, Compon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.initSelectedUserProfileAttributes = function(configName, config) {
|
|
||||||
$scope.selectedUserAttribute = {};
|
|
||||||
if(config[configName]) {
|
|
||||||
UserProfile.get({realm: $route.current.params.realm}, function(data) {
|
|
||||||
if (!data.attributes) {
|
|
||||||
$scope.userProfileDisabled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < data.attributes.length; i++) {
|
|
||||||
if (data.attributes[i].name == config[configName]) {
|
|
||||||
$scope.selectedUserAttribute = data.attributes[i];
|
|
||||||
$scope.selectedUserAttribute.text = data.attributes[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.isPropertyDisabled = function(configName) {
|
|
||||||
var userProfileEnabled = Current.realm.attributes['userProfileEnabled'] == 'true';
|
|
||||||
|
|
||||||
if (configName == 'user.profile.attribute' && !userProfileEnabled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configName == 'user.attribute' && userProfileEnabled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.openRoleSelector = function (configName, config) {
|
$scope.openRoleSelector = function (configName, config) {
|
||||||
$modal.open({
|
$modal.open({
|
||||||
templateUrl: resourceUrl + '/partials/modal/role-selector.html',
|
templateUrl: resourceUrl + '/partials/modal/role-selector.html',
|
||||||
|
@ -3138,18 +3105,6 @@ module.controller('ProviderConfigCtrl', function ($modal, $scope, $route, Compon
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.changeUserAttribute = function(configName, config, userAttribute, multivalued) {
|
|
||||||
if (!$scope.selectedUserAttribute) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$scope.selectedUserAttribute = userAttribute;
|
|
||||||
if (multivalued) {
|
|
||||||
config[configName][0] = userAttribute.name;
|
|
||||||
} else {
|
|
||||||
config[configName] = userAttribute.name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ComponentUtils.convertAllMultivaluedStringValuesToList($scope.properties, $scope.config);
|
ComponentUtils.convertAllMultivaluedStringValuesToList($scope.properties, $scope.config);
|
||||||
|
|
||||||
ComponentUtils.addLastEmptyValueToMultivaluedLists($scope.properties, $scope.config);
|
ComponentUtils.addLastEmptyValueToMultivaluedLists($scope.properties, $scope.config);
|
||||||
|
|
|
@ -962,39 +962,6 @@ function clientSelectControl($scope, realm, Client) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function userProfileAttributeSelectControl($scope, realm, UserProfile) {
|
|
||||||
$scope.userProfileAttributesUiSelect = {
|
|
||||||
minimumInputLength: 0,
|
|
||||||
delay: 500,
|
|
||||||
allowClear: true,
|
|
||||||
id: function(e) { return e.name; },
|
|
||||||
query: function (query) {
|
|
||||||
var data = {results: []};
|
|
||||||
UserProfile.get({realm: realm}, function(config) {
|
|
||||||
var attributes = [];
|
|
||||||
|
|
||||||
if ('' == query.term.trim()) {
|
|
||||||
attributes = config.attributes;
|
|
||||||
} else {
|
|
||||||
for (var i = 0; i < config.attributes.length; i++) {
|
|
||||||
if (config.attributes[i].name.indexOf(query.term.trim()) != -1) {
|
|
||||||
attributes.push(config.attributes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
query.callback({results: attributes});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
formatResult: function(object, container, query) {
|
|
||||||
object.text = object.name;
|
|
||||||
return object.name;
|
|
||||||
},
|
|
||||||
formatSelection: function(object, container, query) {
|
|
||||||
return object.name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function roleControl($scope, $route, realm, role, roles, Client,
|
function roleControl($scope, $route, realm, role, roles, Client,
|
||||||
ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
|
ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
|
||||||
$http, $location, Notifications, Dialog, ComponentUtils) {
|
$http, $location, Notifications, Dialog, ComponentUtils) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<div>
|
<div>
|
||||||
<div data-ng-repeat="option in properties" class="form-group" data-ng-controller="ProviderConfigCtrl"
|
<div data-ng-repeat="option in properties" class="form-group" data-ng-controller="ProviderConfigCtrl">
|
||||||
ng-if="!isPropertyDisabled(option.name)">
|
|
||||||
<label class="col-md-2 control-label">{{:: option.label | translate}}</label>
|
<label class="col-md-2 control-label">{{:: option.label | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6" data-ng-if="option.type == 'String'">
|
<div class="col-md-6" data-ng-if="option.type == 'String'">
|
||||||
|
@ -34,10 +33,6 @@
|
||||||
<input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-init="initSelectedClient(option.name, config)" data-ng-model="selectedClient" data-ng-change="changeClient(option.name, config, selectedClient, false);" data-placeholder="{{:: 'selectOne' | translate}}...">
|
<input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-init="initSelectedClient(option.name, config)" data-ng-model="selectedClient" data-ng-change="changeClient(option.name, config, selectedClient, false);" data-placeholder="{{:: 'selectOne' | translate}}...">
|
||||||
</input>
|
</input>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4" data-ng-if="option.type == 'UserProfileAttributeList'">
|
|
||||||
<input type="hidden" ui-select2="userProfileAttributesUiSelect" id="userProfileAttributes" data-ng-init="initSelectedUserProfileAttributes(option.name, config)" data-ng-model="selectedUserAttribute" data-ng-change="changeUserAttribute(option.name, config, selectedUserAttribute, false);" data-placeholder="{{:: 'selectOne' | translate}}...">
|
|
||||||
</input>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6" data-ng-if="option.type == 'Script'">
|
<div class="col-md-6" data-ng-if="option.type == 'Script'">
|
||||||
<div ng-model="config[option.name]" placeholder="Enter your script..." ui-ace="{ onLoad : initEditor, useWrapMode: true, showGutter: true, theme:'github', mode: 'javascript'}">
|
<div ng-model="config[option.name]" placeholder="Enter your script..." ui-ace="{ onLoad : initEditor, useWrapMode: true, showGutter: true, theme:'github', mode: 'javascript'}">
|
||||||
|
|
Loading…
Reference in a new issue