/*
* 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.protocol.oidc.mappers;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.AddressClaimSet;
import org.keycloak.representations.IDToken;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class AddressMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper {
private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
public static final String STREET = "street";
static {
OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, AddressMapper.class);
configProperties.add(createConfigProperty(STREET));
configProperties.add(createConfigProperty(AddressClaimSet.LOCALITY));
configProperties.add(createConfigProperty(AddressClaimSet.REGION));
configProperties.add(createConfigProperty(AddressClaimSet.POSTAL_CODE));
configProperties.add(createConfigProperty(AddressClaimSet.COUNTRY));
configProperties.add(createConfigProperty(AddressClaimSet.FORMATTED));
}
protected static ProviderConfigProperty createConfigProperty(String claimName) {
ProviderConfigProperty property = new ProviderConfigProperty();
property.setName(getModelPropertyName(claimName));
property.setLabel("addressClaim." + claimName + ".label");
property.setHelpText("addressClaim." + claimName + ".tooltip");
property.setType(ProviderConfigProperty.STRING_TYPE);
property.setDefaultValue(claimName);
return property;
}
public static String getModelPropertyName(String claimName) {
return "user.attribute." + claimName;
}
public static final String PROVIDER_ID = "oidc-address-mapper";
public static ProtocolMapperModel createAddressMapper() {
return createAddressMapper(true, true);
}
public static ProtocolMapperModel createAddressMapper(boolean idToken, boolean accessToken) {
Map<String, String> config;
ProtocolMapperModel address = new ProtocolMapperModel();
address.setName("address");
address.setProtocolMapper(PROVIDER_ID);
address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
address.setConsentRequired(true);
address.setConsentText("${address}");
config = new HashMap<String, String>();
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, Boolean.toString(idToken));
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, Boolean.toString(accessToken));
config.put(getModelPropertyName(STREET), STREET);
config.put(getModelPropertyName(AddressClaimSet.LOCALITY), AddressClaimSet.LOCALITY);
config.put(getModelPropertyName(AddressClaimSet.REGION), AddressClaimSet.REGION);
config.put(getModelPropertyName(AddressClaimSet.POSTAL_CODE), AddressClaimSet.POSTAL_CODE);
config.put(getModelPropertyName(AddressClaimSet.COUNTRY), AddressClaimSet.COUNTRY);
config.put(getModelPropertyName(AddressClaimSet.FORMATTED), AddressClaimSet.FORMATTED);
address.setConfig(config);
return address;
}
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
}
@Override
public String getId() {
return PROVIDER_ID;
}
@Override
public String getDisplayType() {
return "User Address";
}
@Override
public String getDisplayCategory() {
return TOKEN_MAPPER_CATEGORY;
}
@Override
public String getHelpText() {
return "Maps user address attributes (street, locality, region, postal_code, and country) to the OpenID Connect 'address' claim.";
}
@Override
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
UserModel user = userSession.getUser();
AddressClaimSet addressSet = new AddressClaimSet();
addressSet.setStreetAddress(getUserModelAttributeValue(user, mappingModel, STREET));
addressSet.setLocality(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.LOCALITY));
addressSet.setRegion(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.REGION));
addressSet.setPostalCode(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.POSTAL_CODE));
addressSet.setCountry(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.COUNTRY));
addressSet.setFormattedAddress(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.FORMATTED));
token.getOtherClaims().put("address", addressSet);
}
private String getUserModelAttributeValue(UserModel user, ProtocolMapperModel mappingModel, String claim) {
String modelPropertyName = getModelPropertyName(claim);
String userAttrName = mappingModel.getConfig().get(modelPropertyName);
if (userAttrName == null) {
userAttrName = claim;
}
return user.getFirstAttribute(userAttrName);
}
}