keycloak-uncached

Details

diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java b/broker/core/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java
index f90f803..6052f57 100755
--- a/broker/core/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java
@@ -17,6 +17,7 @@
  */
 package org.keycloak.broker.provider;
 
+import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.IdentityProviderModel;
 
 import java.util.HashMap;
@@ -43,6 +44,7 @@ public class BrokeredIdentityContext {
     private IdentityProviderModel idpConfig;
     private IdentityProvider idp;
     private Map<String, Object> contextData = new HashMap<>();
+    private ClientSessionModel clientSession;
 
     public BrokeredIdentityContext(String id) {
         if (id == null) {
@@ -166,6 +168,14 @@ public class BrokeredIdentityContext {
         this.lastName = lastName;
     }
 
+    public ClientSessionModel getClientSession() {
+        return clientSession;
+    }
+
+    public void setClientSession(ClientSessionModel clientSession) {
+        this.clientSession = clientSession;
+    }
+
     public void setName(String name) {
         if (name != null) {
             int i = name.lastIndexOf(' ');
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedAttributeMapper.java b/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedAttributeMapper.java
new file mode 100755
index 0000000..d182d6f
--- /dev/null
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedAttributeMapper.java
@@ -0,0 +1,89 @@
+package org.keycloak.broker.provider;
+
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.provider.ProviderConfigProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class HardcodedAttributeMapper extends AbstractIdentityProviderMapper {
+    public static final String ATTRIBUTE = "attribute";
+    public static final String ATTRIBUTE_VALUE = "attribute.value";
+    protected static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
+
+    static {
+        ProviderConfigProperty property;
+        property = new ProviderConfigProperty();
+        property.setName(ATTRIBUTE);
+        property.setLabel("User Attribute");
+        property.setHelpText("Name of user attribute you want to hardcode");
+        property.setType(ProviderConfigProperty.STRING_TYPE);
+        configProperties.add(property);
+        property = new ProviderConfigProperty();
+        property.setName(ATTRIBUTE_VALUE);
+        property.setLabel("User Attribute Value");
+        property.setHelpText("Value you want to hardcode");
+        property.setType(ProviderConfigProperty.STRING_TYPE);
+        configProperties.add(property);
+    }
+
+
+
+    @Override
+    public List<ProviderConfigProperty> getConfigProperties() {
+        return configProperties;
+    }
+
+    @Override
+    public String getDisplayCategory() {
+        return "Attribute Importer";
+    }
+
+    @Override
+    public String getDisplayType() {
+        return "Hardcoded Attribute";
+    }
+
+    public static final String[] COMPATIBLE_PROVIDERS = {ANY_PROVIDER};
+
+
+    public static final String PROVIDER_ID = "hardcoded-attribute-idp-mapper";
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public String[] getCompatibleProviders() {
+        return COMPATIBLE_PROVIDERS;
+    }
+
+    @Override
+    public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
+        String attribute = mapperModel.getConfig().get(ATTRIBUTE);
+        String attributeValue = mapperModel.getConfig().get(ATTRIBUTE_VALUE);
+        user.setSingleAttribute(attribute, attributeValue);
+    }
+
+    @Override
+    public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
+        String attribute = mapperModel.getConfig().get(ATTRIBUTE);
+        String attributeValue = mapperModel.getConfig().get(ATTRIBUTE_VALUE);
+        user.setSingleAttribute(attribute, attributeValue);
+    }
+
+    @Override
+    public String getHelpText() {
+        return "When user is imported from provider, hardcode a value to a specific user attribute.";
+    }
+}
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedUserSessionAttributeMapper.java b/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedUserSessionAttributeMapper.java
new file mode 100755
index 0000000..676e6b1
--- /dev/null
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedUserSessionAttributeMapper.java
@@ -0,0 +1,87 @@
+package org.keycloak.broker.provider;
+
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.provider.ProviderConfigProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class HardcodedUserSessionAttributeMapper extends AbstractIdentityProviderMapper {
+    public static final String ATTRIBUTE = "attribute";
+    public static final String ATTRIBUTE_VALUE = "attribute.value";
+    protected static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
+
+    static {
+        ProviderConfigProperty property;
+        property = new ProviderConfigProperty();
+        property.setName(ATTRIBUTE);
+        property.setLabel("User Session Attribute");
+        property.setHelpText("Name of user session attribute you want to hardcode");
+        property.setType(ProviderConfigProperty.STRING_TYPE);
+        configProperties.add(property);
+        property = new ProviderConfigProperty();
+        property.setName(ATTRIBUTE_VALUE);
+        property.setLabel("User Session Attribute Value");
+        property.setHelpText("Value you want to hardcode");
+        property.setType(ProviderConfigProperty.STRING_TYPE);
+        configProperties.add(property);
+    }
+
+
+
+    @Override
+    public List<ProviderConfigProperty> getConfigProperties() {
+        return configProperties;
+    }
+
+    @Override
+    public String getDisplayCategory() {
+        return "Attribute Importer";
+    }
+
+    @Override
+    public String getDisplayType() {
+        return "Hardcoded User Session Attribute";
+    }
+
+    public static final String[] COMPATIBLE_PROVIDERS = {ANY_PROVIDER};
+
+
+    public static final String PROVIDER_ID = "hardcoded-user-session-attribute-idp-mapper";
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public String[] getCompatibleProviders() {
+        return COMPATIBLE_PROVIDERS;
+    }
+
+    @Override
+    public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
+        String attribute = mapperModel.getConfig().get(ATTRIBUTE);
+        String attributeValue = mapperModel.getConfig().get(ATTRIBUTE_VALUE);
+        context.getClientSession().setUserSessionNote(attribute, attributeValue);
+    }
+
+    @Override
+    public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
+        String attribute = mapperModel.getConfig().get(ATTRIBUTE);
+        String attributeValue = mapperModel.getConfig().get(ATTRIBUTE_VALUE);
+        context.getClientSession().setUserSessionNote(attribute, attributeValue);
+    }
+
+    @Override
+    public String getHelpText() {
+        return "When user is imported from provider, hardcode a value to a specific user session attribute.";
+    }
+}
diff --git a/broker/core/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/broker/core/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
index a3bf053..ef57994 100755
--- a/broker/core/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
+++ b/broker/core/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
@@ -1 +1,3 @@
-org.keycloak.broker.provider.HardcodedRoleMapper
\ No newline at end of file
+org.keycloak.broker.provider.HardcodedRoleMapper
+org.keycloak.broker.provider.HardcodedAttributeMapper
+org.keycloak.broker.provider.HardcodedUserSessionAttributeMapper
\ No newline at end of file
diff --git a/docbook/reference/en/en-US/modules/identity-broker.xml b/docbook/reference/en/en-US/modules/identity-broker.xml
index 2288ed7..a262b85 100755
--- a/docbook/reference/en/en-US/modules/identity-broker.xml
+++ b/docbook/reference/en/en-US/modules/identity-broker.xml
@@ -1264,6 +1264,24 @@ keycloak.createLoginUrl({
             JSON structure in Keycloak log file. 
         </para>
     </section>
+    <section>
+        <title>User Session Data</title>
+        <para>
+           After a user logs in from the external IDP, there's some additional user session note data that Keycloak stores that you
+            can access.  This data can be propagated to the client requesting a login
+            via the token or SAML assertion being passed back to it by using an appropriate client mapper.
+            <variablelist>
+                <varlistentry>
+                    <term>BROKER_PROVIDER_ID</term>
+                    <listitem>
+                        <para>
+                            This is the IDP alias of the broker used to perform the login.
+                        </para>
+                    </listitem>
+                </varlistentry>
+             </variablelist>
+        </para>
+    </section>
 
     <section>
         <title>Examples</title>
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/UserSessionNoteStatementMapper.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/UserSessionNoteStatementMapper.java
new file mode 100755
index 0000000..ccf4c1f
--- /dev/null
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/UserSessionNoteStatementMapper.java
@@ -0,0 +1,69 @@
+package org.keycloak.protocol.saml.mappers;
+
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.ProtocolMapperUtils;
+import org.keycloak.provider.ProviderConfigProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Maps a user session note to a SAML attribute
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class UserSessionNoteStatementMapper extends AbstractSAMLProtocolMapper implements SAMLAttributeStatementMapper {
+    private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
+
+    static {
+        ProviderConfigProperty property;
+        property = new ProviderConfigProperty();
+        property.setName("note");
+        property.setLabel("User Session Note Attribute");
+        property.setHelpText("The user session note you want to grab the value from.");
+        configProperties.add(property);
+        AttributeStatementHelper.setConfigProperties(configProperties);
+
+    }
+
+    public static final String PROVIDER_ID = "saml-user-session-note-mapper";
+
+
+    public List<ProviderConfigProperty> getConfigProperties() {
+        return configProperties;
+    }
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public String getDisplayType() {
+        return "User Session Note";
+    }
+
+    @Override
+    public String getDisplayCategory() {
+        return AttributeStatementHelper.ATTRIBUTE_STATEMENT_CATEGORY;
+    }
+
+    @Override
+    public String getHelpText() {
+        return "Map a user session note to a SAML attribute.";
+    }
+
+    @Override
+    public void transformAttributeStatement(AttributeStatementType attributeStatement, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
+        String note = mappingModel.getConfig().get("note");
+        String value = userSession.getNote(note);
+        if (value == null) return;
+        AttributeStatementHelper.addAttribute(attributeStatement, mappingModel, value);
+
+    }
+}
diff --git a/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper b/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
index 58e10db..163fed5 100755
--- a/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
+++ b/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
@@ -4,5 +4,6 @@ org.keycloak.protocol.saml.mappers.HardcodedRole
 org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper
 org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper
 org.keycloak.protocol.saml.mappers.UserPropertyAttributeStatementMapper
+org.keycloak.protocol.saml.mappers.UserSessionNoteStatementMapper
 
 
diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
index beec664..f95d7d8 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -256,6 +256,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
         }
 
         ClientSessionModel clientSession = clientCode.getClientSession();
+        context.setClientSession(clientSession);
 
         session.getContext().setClient(clientSession.getClient());