keycloak-aplcache

Merge pull request #973 from patriot1burke/master claim

2/14/2015 12:39:34 AM

Changes

Details

diff --git a/connections/jpa/src/main/resources/META-INF/persistence.xml b/connections/jpa/src/main/resources/META-INF/persistence.xml
index bb40325..5f428ee 100755
--- a/connections/jpa/src/main/resources/META-INF/persistence.xml
+++ b/connections/jpa/src/main/resources/META-INF/persistence.xml
@@ -18,6 +18,8 @@
         <class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
         <class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
         <class>org.keycloak.models.jpa.entities.IdentityProviderEntity</class>
+        <class>org.keycloak.models.jpa.entities.ClaimTypeEntity</class>
+        <class>org.keycloak.models.jpa.entities.ProtocolClaimMappingEntity</class>
 
         <!-- JpaUserSessionProvider -->
         <class>org.keycloak.models.sessions.jpa.entities.ClientSessionEntity</class>
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
index 1b553af..f48615b 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
@@ -1,11 +1,31 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
     <changeSet author="psilva@redhat.com" id="1.2.0.Beta1">
+        <createTable tableName="PROTOCOL_CLAIM_MAPPING">
+            <column name="ID" type="VARCHAR(36)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="PROTOCOL_CLAIM" type="VARCHAR(255)"/>
+            <column name="PROTOCOL" type="VARCHAR(255)"/>
+            <column name="SOURCE" type="VARCHAR(255)"/>
+            <column name="SOURCE_ATTRIBUTE" type="VARCHAR(255)"/>
+            <column name="APPLIED_BY_DEFAULT" type="BOOLEAN(1)"/>
+            <column name="REALM_ID" type="VARCHAR(36)"/>
+        </createTable>
+        <createTable tableName="CLAIM_TYPE">
+            <column name="ID" type="VARCHAR(36)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="NAME" type="VARCHAR(255)"/>
+            <column name="BUILT_IN" type="BOOLEAN(1)"/>
+            <column name="VALUE_TYPE" type="VARCHAR(255)"/>
+            <column name="REALM_ID" type="VARCHAR(36)"/>
+        </createTable>
         <createTable tableName="FEDERATED_IDENTITY">
             <column name="IDENTITY_PROVIDER" type="VARCHAR(255)">
                 <constraints nullable="false"/>
             </column>
-            <column name="REALM_ID" type="VARCHAR(255)"/>
+            <column name="REALM_ID" type="VARCHAR(36)"/>
             <column name="FEDERATED_USER_ID" type="VARCHAR(255)"/>
             <column name="FEDERATED_USERNAME" type="VARCHAR(255)"/>
             <column name="TOKEN" type="TEXT"/>
@@ -46,10 +66,14 @@
         <addColumn tableName="CLIENT">
             <column name="FRONTCHANNEL_LOGOUT" type="BOOLEAN" defaultValueBoolean="false"/>
         </addColumn>
+        <addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_CT" tableName="CLAIM_TYPE"/>
+        <addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_PCM" tableName="PROTOCOL_CLAIM_MAPPING"/>
         <addPrimaryKey columnNames="INTERNAL_ID" constraintName="CONSTRAINT_2B" tableName="IDENTITY_PROVIDER"/>
         <addPrimaryKey columnNames="IDENTITY_PROVIDER, USER_ID" constraintName="CONSTRAINT_40" tableName="FEDERATED_IDENTITY"/>
         <addPrimaryKey columnNames="IDENTITY_PROVIDER_ID, NAME" constraintName="CONSTRAINT_D" tableName="IDENTITY_PROVIDER_CONFIG"/>
         <addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="IDENTITY_PROVIDER" constraintName="FK2B4EBC52AE5C3B34" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="REALM"/>
+        <addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="CLAIM_TYPE" constraintName="FK_CT_REALM" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="REALM"/>
+        <addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="PROTOCOL_CLAIM_MAPPING" constraintName="FK_PCM_REALM" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="REALM"/>
         <addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="FEDERATED_IDENTITY" constraintName="FK404288B92EF007A6" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
         <addForeignKeyConstraint baseColumnNames="IDENTITY_PROVIDER_ID" baseTableName="IDENTITY_PROVIDER_CONFIG" constraintName="FKDC4897CF864C4E43" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="INTERNAL_ID" referencedTableName="IDENTITY_PROVIDER"/>
         <addForeignKeyConstraint baseColumnNames="INTERNAL_ID" baseTableName="CLIENT_ALLOWED_IDENTITY_PROVIDER" constraintName="FK_7CELWNIBJI49AVXSRTUF6XJ12" referencedColumnNames="INTERNAL_ID" referencedTableName="IDENTITY_PROVIDER"/>
diff --git a/core/src/main/java/org/keycloak/representations/idm/ClaimTypeRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClaimTypeRepresentation.java
new file mode 100755
index 0000000..747c366
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/ClaimTypeRepresentation.java
@@ -0,0 +1,45 @@
+package org.keycloak.representations.idm;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ClaimTypeRepresentation {
+
+    private String id;
+    private String name;
+    private Boolean builtIn;
+    private String type;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Boolean isBuiltIn() {
+        return builtIn;
+    }
+
+    public void setBuiltIn(Boolean builtIn) {
+        this.builtIn = builtIn;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index e5a1173..b33312d 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -63,7 +63,8 @@ public class RealmRepresentation {
     protected Long eventsExpiration;
     protected List<String> eventsListeners;
     private List<IdentityProviderRepresentation> identityProviders;
-    private boolean identityFederationEnabled;
+    private List<ClaimTypeRepresentation> claimTypes;
+    private Boolean identityFederationEnabled;
 
     public String getId() {
         return id;
@@ -480,4 +481,13 @@ public class RealmRepresentation {
     public boolean isIdentityFederationEnabled() {
         return !getIdentityProviders().isEmpty();
     }
+
+    public List<ClaimTypeRepresentation> getClaimTypes() {
+        if (claimTypes == null) claimTypes = new ArrayList<ClaimTypeRepresentation>();
+        return claimTypes;
+    }
+
+    public void setClaimTypes(List<ClaimTypeRepresentation> claimTypes) {
+        this.claimTypes = claimTypes;
+    }
 }
diff --git a/model/api/src/main/java/org/keycloak/models/ClaimTypeModel.java b/model/api/src/main/java/org/keycloak/models/ClaimTypeModel.java
new file mode 100755
index 0000000..c4bee9c
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/ClaimTypeModel.java
@@ -0,0 +1,63 @@
+package org.keycloak.models;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ClaimTypeModel {
+
+    public static enum ValueType {
+        BOOLEAN,
+        INT,
+        STRING
+    }
+
+    private final String id;
+    private final String name;
+    private final boolean builtIn;
+    private final ValueType type;
+
+    public ClaimTypeModel(ClaimTypeModel copy) {
+        this(copy.getId(), copy.getName(), copy.isBuiltIn(), copy.getType());
+    }
+
+    public ClaimTypeModel(String id, String name, boolean builtIn, ValueType type) {
+        this.id = id;
+        this.name = name;
+        this.builtIn = builtIn;
+        this.type = type;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean isBuiltIn() {
+        return builtIn;
+    }
+
+    public ValueType getType() {
+        return type;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ClaimTypeModel that = (ClaimTypeModel) o;
+
+        if (!id.equals(that.id)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index 0acd9c5..5fa685f 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -103,4 +103,11 @@ public interface ClientModel {
     List<String> getAllowedIdentityProviders();
 
     boolean hasIdentityProvider(String providerId);
+
+    /*
+    Set<ProtocolClaimMapping> getClaimMappings();
+    ProtocolClaimMapping getClaimMapping(String protocolClaim);
+    ProtocolClaimMapping addClaimMapping(String assertion, String protocol, ClaimTypeModel claimType);
+    void removeClaimMapping(ProtocolClaimMapping mapping);
+    */
 }
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ClaimTypeEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ClaimTypeEntity.java
new file mode 100755
index 0000000..93572cd
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/entities/ClaimTypeEntity.java
@@ -0,0 +1,53 @@
+package org.keycloak.models.entities;
+
+import org.keycloak.models.ClaimTypeModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ClaimTypeEntity {
+    protected String id;
+
+    private String name;
+
+    protected boolean builtIn;
+
+    protected ClaimTypeModel.ValueType type;
+
+    private String realmId;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isBuiltIn() {
+        return builtIn;
+    }
+
+    public void setBuiltIn(boolean builtIn) {
+        this.builtIn = builtIn;
+    }
+
+    public ClaimTypeModel.ValueType getType() {
+        return type;
+    }
+
+    public void setType(ClaimTypeModel.ValueType type) {
+        this.type = type;
+    }
+
+}
+
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ProtocolClaimMappingEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ProtocolClaimMappingEntity.java
new file mode 100755
index 0000000..83095a1
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/entities/ProtocolClaimMappingEntity.java
@@ -0,0 +1,64 @@
+package org.keycloak.models.entities;
+
+import org.keycloak.models.ProtocolClaimMappingModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ProtocolClaimMappingEntity {
+    protected String id;
+    protected String protocolClaim;
+    protected String protocol;
+    protected ProtocolClaimMappingModel.Source source;
+    protected String sourceAttribute;
+    protected boolean appliedByDefault;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getProtocolClaim() {
+        return protocolClaim;
+    }
+
+    public void setProtocolClaim(String protocolClaim) {
+        this.protocolClaim = protocolClaim;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public ProtocolClaimMappingModel.Source getSource() {
+        return source;
+    }
+
+    public void setSource(ProtocolClaimMappingModel.Source source) {
+        this.source = source;
+    }
+
+    public String getSourceAttribute() {
+        return sourceAttribute;
+    }
+
+    public void setSourceAttribute(String sourceAttribute) {
+        this.sourceAttribute = sourceAttribute;
+    }
+
+    public boolean isAppliedByDefault() {
+        return appliedByDefault;
+    }
+
+    public void setAppliedByDefault(boolean appliedByDefault) {
+        this.appliedByDefault = appliedByDefault;
+    }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
index 6da7387..e4324e3 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
@@ -52,6 +52,8 @@ public class RealmEntity extends AbstractIdentifiableEntity {
     private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
     private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
     private List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
+    private List<ClaimTypeEntity> claimTypes = new ArrayList<ClaimTypeEntity>();
+    private List<ProtocolClaimMappingEntity> claimMappings = new ArrayList<ProtocolClaimMappingEntity>();
 
     private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
     private Map<String, String> smtpConfig = new HashMap<String, String>();
@@ -390,4 +392,22 @@ public class RealmEntity extends AbstractIdentifiableEntity {
     public void setCertificatePem(String certificatePem) {
         this.certificatePem = certificatePem;
     }
+
+    public List<ClaimTypeEntity> getClaimTypes() {
+        return claimTypes;
+    }
+
+    public void setClaimTypes(List<ClaimTypeEntity> claimTypes) {
+        this.claimTypes = claimTypes;
+    }
+
+    public List<ProtocolClaimMappingEntity> getClaimMappings() {
+        return claimMappings;
+    }
+
+    public void setClaimMappings(List<ProtocolClaimMappingEntity> claimMappings) {
+        this.claimMappings = claimMappings;
+    }
 }
+
+
diff --git a/model/api/src/main/java/org/keycloak/models/ProtocolClaimMappingModel.java b/model/api/src/main/java/org/keycloak/models/ProtocolClaimMappingModel.java
new file mode 100755
index 0000000..766cd9e
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/ProtocolClaimMappingModel.java
@@ -0,0 +1,87 @@
+package org.keycloak.models;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ProtocolClaimMappingModel {
+    public static enum Source {
+        USER_MODEL,
+        USER_ATTRIBUTE,
+        USER_SESSION_NOTE,
+        CLIENT_SESSION_NOTE
+    }
+
+    protected String id;
+    protected String protocolClaim;
+    protected String protocol;
+    protected Source source;
+    protected String sourceAttribute;
+    protected boolean appliedByDefault;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getProtocolClaim() {
+        return protocolClaim;
+    }
+
+    public void setProtocolClaim(String protocolClaim) {
+        this.protocolClaim = protocolClaim;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public String getSourceAttribute() {
+        return sourceAttribute;
+    }
+
+    public void setSourceAttribute(String sourceAttribute) {
+        this.sourceAttribute = sourceAttribute;
+    }
+
+    public boolean isAppliedByDefault() {
+        return appliedByDefault;
+    }
+
+    public void setAppliedByDefault(boolean appliedByDefault) {
+        this.appliedByDefault = appliedByDefault;
+    }
+
+    public Source getSource() {
+        return source;
+    }
+
+    public void setSource(Source source) {
+        this.source = source;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ProtocolClaimMappingModel that = (ProtocolClaimMappingModel) o;
+
+        if (!id.equals(that.id)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 4ce7d61..d41fc3d 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -223,4 +223,19 @@ public interface RealmModel extends RoleContainerModel {
     ClientModel findClientById(String id);
 
     boolean isIdentityFederationEnabled();
+
+    Set<ClaimTypeModel> getClaimTypes();
+    ClaimTypeModel addClaimType(String name, ClaimTypeModel.ValueType type, boolean builtIn);
+    void removeClaimType(ClaimTypeModel claimType);
+    ClaimTypeModel getClaimType(String name);
+    void updateClaimType(ClaimTypeModel claimType);
+
+    Set<ProtocolClaimMappingModel> getProtocolClaimMappings();
+    ProtocolClaimMappingModel addProtocolClaimMapping(String protocolClaim, String protocol, String sourceAttribute,
+                                                      ProtocolClaimMappingModel.Source source, boolean appliedByDefault);
+    void removeProtocolClaimMapping(ProtocolClaimMappingModel mapping);
+    void updateProtocolClaimMapping(ProtocolClaimMappingModel mapping);
+    public ProtocolClaimMappingModel getProtocolClaimMappingById(String id);
+
+
 }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 05ccba9..72b62d2 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -2,6 +2,7 @@ package org.keycloak.models.utils;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClaimMask;
+import org.keycloak.models.ClaimTypeModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.FederatedIdentityModel;
@@ -16,6 +17,7 @@ import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.ClaimRepresentation;
+import org.keycloak.representations.idm.ClaimTypeRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.FederatedIdentityRepresentation;
 import org.keycloak.representations.idm.IdentityProviderRepresentation;
@@ -149,6 +151,10 @@ public class ModelToRepresentation {
             rep.addIdentityProvider(toRepresentation(provider));
         }
 
+        for (ClaimTypeModel claimType : realm.getClaimTypes()) {
+            rep.getClaimTypes().add(toRepresentation(claimType));
+        }
+
         return rep;
     }
 
@@ -313,4 +319,13 @@ public class ModelToRepresentation {
 
         return providerRep;
     }
+
+    public static ClaimTypeRepresentation toRepresentation(ClaimTypeModel claimType) {
+        ClaimTypeRepresentation rep = new ClaimTypeRepresentation();
+        rep.setId(claimType.getId());
+        rep.setName(claimType.getName());
+        rep.setBuiltIn(claimType.isBuiltIn());
+        rep.setType(claimType.getType().name().toLowerCase());
+        return rep;
+    }
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
index bfc5a95..c4a7796 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
@@ -2,9 +2,11 @@ package org.keycloak.models.cache.entities;
 
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClaimTypeModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.ProtocolClaimMappingModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RequiredCredentialModel;
@@ -68,6 +70,8 @@ public class CachedRealm {
     private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>();
     private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>();
     private List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
+    private Set<ClaimTypeModel> claimTypes = new HashSet<ClaimTypeModel>();
+    private Set<ProtocolClaimMappingModel> claimMappings = new HashSet<ProtocolClaimMappingModel>();
 
     private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
     private Map<String, String> smtpConfig = new HashMap<String, String>();
@@ -131,6 +135,10 @@ public class CachedRealm {
             this.identityProviders.add(new IdentityProviderModel(identityProviderModel));
         }
 
+        for (ClaimTypeModel claimType : model.getClaimTypes()) {
+            this.claimTypes.add(new ClaimTypeModel(claimType));
+        }
+
         smtpConfig.putAll(model.getSmtpConfig());
         browserSecurityHeaders.putAll(model.getBrowserSecurityHeaders());
 
@@ -340,4 +348,12 @@ public class CachedRealm {
     public List<IdentityProviderModel> getIdentityProviders() {
         return identityProviders;
     }
+
+    public Set<ClaimTypeModel> getClaimTypes() {
+        return claimTypes;
+    }
+
+    public Set<ProtocolClaimMappingModel> getClaimMappings() {
+        return claimMappings;
+    }
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
index dc4ede4..573ba68 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
@@ -3,10 +3,12 @@ package org.keycloak.models.cache;
 import org.keycloak.Config;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClaimTypeModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.ProtocolClaimMappingModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
@@ -609,6 +611,7 @@ public class RealmAdapter implements RealmModel {
         updated.setSmtpConfig(smtpConfig);
     }
 
+
     @Override
     public List<IdentityProviderModel> getIdentityProviders() {
         if (updated != null) return updated.getIdentityProviders();
@@ -847,6 +850,74 @@ public class RealmAdapter implements RealmModel {
         return cached.isIdentityFederationEnabled();
     }
 
+    @Override
+    public Set<ClaimTypeModel> getClaimTypes() {
+        if (updated != null) return updated.getClaimTypes();
+        return cached.getClaimTypes();
+    }
+
+    @Override
+    public ClaimTypeModel addClaimType(String name, ClaimTypeModel.ValueType type, boolean builtIn) {
+        getDelegateForUpdate();
+        return updated.addClaimType(name, type, builtIn);
+    }
+
+    @Override
+    public void removeClaimType(ClaimTypeModel claimType) {
+        getDelegateForUpdate();
+        updated.removeClaimType(claimType);
+
+    }
+
+    @Override
+    public ClaimTypeModel getClaimType(String name) {
+        for (ClaimTypeModel claimType : getClaimTypes())  {
+            if (claimType.getName().equals(name)) return claimType;
+        }
+        return null;
+    }
+
+    @Override
+    public void updateClaimType(ClaimTypeModel claimType) {
+        getDelegateForUpdate();
+        updated.updateClaimType(claimType);
+
+    }
+
+
+    @Override
+    public Set<ProtocolClaimMappingModel> getProtocolClaimMappings() {
+        if (updated != null) return updated.getProtocolClaimMappings();
+        return cached.getClaimMappings();
+     }
+
+    @Override
+    public ProtocolClaimMappingModel addProtocolClaimMapping(String protocolClaim, String protocol, String sourceAttribute, ProtocolClaimMappingModel.Source source, boolean appliedByDefault) {
+        getDelegateForUpdate();
+        return updated.addProtocolClaimMapping(protocolClaim, protocol, sourceAttribute, source, appliedByDefault);
+    }
+
+    @Override
+    public void removeProtocolClaimMapping(ProtocolClaimMappingModel mapping) {
+        getDelegateForUpdate();
+        updated.removeProtocolClaimMapping(mapping);
+
+    }
+
+    @Override
+    public void updateProtocolClaimMapping(ProtocolClaimMappingModel mapping) {
+        getDelegateForUpdate();
+        updated.updateProtocolClaimMapping(mapping);
+
+    }
+
+    @Override
+    public ProtocolClaimMappingModel getProtocolClaimMappingById(String id) {
+        for (ProtocolClaimMappingModel mapping : cached.getClaimMappings()) {
+            if (mapping.getId().equals(id)) return mapping;
+        }
+        return null;
+    }
 
     @Override
     public boolean equals(Object o) {
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClaimTypeEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClaimTypeEntity.java
new file mode 100755
index 0000000..c77245f
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClaimTypeEntity.java
@@ -0,0 +1,82 @@
+package org.keycloak.models.jpa.entities;
+
+import org.keycloak.models.ClaimTypeModel;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@Entity
+@NamedQueries({
+        @NamedQuery(name="deleteClaimTypesByRealm", query="delete from ClaimTypeEntity attr where attr.realm = :realm")
+})
+@Table(name="CLAIM_TYPE")
+public class ClaimTypeEntity {
+
+    @Id
+    @Column(name="ID", length = 36)
+    protected String id;
+
+    @Column(name = "NAME")
+    private String name;
+
+    @Column(name = "BUILT_IN")
+    protected boolean builtIn;
+
+    @Column(name = "VALUE_TYPE")
+    protected String type;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "REALM_ID")
+    protected RealmEntity realm;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isBuiltIn() {
+        return builtIn;
+    }
+
+    public void setBuiltIn(boolean builtIn) {
+        this.builtIn = builtIn;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public RealmEntity getRealm() {
+        return realm;
+    }
+
+    public void setRealm(RealmEntity realm) {
+        this.realm = realm;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolClaimMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolClaimMappingEntity.java
new file mode 100755
index 0000000..7a429dc
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolClaimMappingEntity.java
@@ -0,0 +1,98 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@Entity
+@NamedQueries({
+        @NamedQuery(name="deleteProtocolClaimMappingsByRealm", query="delete from ProtocolClaimMappingEntity attr where attr.realm = :realm")
+})
+@Table(name="PROTOCOL_CLAIM_MAPPING")
+public class ProtocolClaimMappingEntity {
+
+    @Id
+    @Column(name="ID", length = 36)
+    protected String id;
+
+    @Column(name = "PROTOCOL_CLAIM")
+    protected String protocolClaim;
+    @Column(name = "PROTOCOL")
+    protected String protocol;
+    @Column(name = "SOURCE")
+    protected String source;
+    @Column(name = "SOURCE_ATTRIBUTE")
+    protected String sourceAttribute;
+    @Column(name = "APPLIED_BY_DEFAULT")
+    protected boolean appliedByDefault;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "REALM_ID")
+    protected RealmEntity realm;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getProtocolClaim() {
+        return protocolClaim;
+    }
+
+    public void setProtocolClaim(String protocolClaim) {
+        this.protocolClaim = protocolClaim;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public String getSource() {
+        return source;
+    }
+
+    public void setSource(String source) {
+        this.source = source;
+    }
+
+    public String getSourceAttribute() {
+        return sourceAttribute;
+    }
+
+    public void setSourceAttribute(String sourceAttribute) {
+        this.sourceAttribute = sourceAttribute;
+    }
+
+    public boolean isAppliedByDefault() {
+        return appliedByDefault;
+    }
+
+    public void setAppliedByDefault(boolean appliedByDefault) {
+        this.appliedByDefault = appliedByDefault;
+    }
+
+    public RealmEntity getRealm() {
+        return realm;
+    }
+
+    public void setRealm(RealmEntity realm) {
+        this.realm = realm;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
index 0f2cea8..5590e7f 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
@@ -93,6 +93,12 @@ public class RealmEntity {
     Collection<RealmAttributeEntity> attributes = new ArrayList<RealmAttributeEntity>();
 
     @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
+    Collection<ClaimTypeEntity> claimTypes = new ArrayList<ClaimTypeEntity>();
+
+    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
+    Collection<ProtocolClaimMappingEntity> protocolClaimMappings = new ArrayList<ProtocolClaimMappingEntity>();
+
+    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
     Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
 
     @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
@@ -432,5 +438,21 @@ public class RealmEntity {
         entity.setRealm(this);
         getIdentityProviders().add(entity);
     }
+
+    public Collection<ClaimTypeEntity> getClaimTypes() {
+        return claimTypes;
+    }
+
+    public void setClaimTypes(Collection<ClaimTypeEntity> claimTypes) {
+        this.claimTypes = claimTypes;
+    }
+
+    public Collection<ProtocolClaimMappingEntity> getProtocolClaimMappings() {
+        return protocolClaimMappings;
+    }
+
+    public void setProtocolClaimMappings(Collection<ProtocolClaimMappingEntity> protocolClaimMappings) {
+        this.protocolClaimMappings = protocolClaimMappings;
+    }
 }
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 0133829..bbc885e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -2,18 +2,22 @@ package org.keycloak.models.jpa;
 
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClaimTypeModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.ProtocolClaimMappingModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserFederationProviderModel;
 import org.keycloak.models.jpa.entities.ApplicationEntity;
+import org.keycloak.models.jpa.entities.ClaimTypeEntity;
 import org.keycloak.models.jpa.entities.IdentityProviderEntity;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
+import org.keycloak.models.jpa.entities.ProtocolClaimMappingEntity;
 import org.keycloak.models.jpa.entities.RealmAttributeEntity;
 import org.keycloak.models.jpa.entities.RealmEntity;
 import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
@@ -1191,4 +1195,146 @@ public class RealmAdapter implements RealmModel {
     public boolean isIdentityFederationEnabled() {
         return !this.realm.getIdentityProviders().isEmpty();
     }
+
+    @Override
+    public Set<ClaimTypeModel> getClaimTypes() {
+        Set<ClaimTypeModel> claimTypes = new HashSet<ClaimTypeModel>();
+        for (ClaimTypeEntity claimTypeEntity : realm.getClaimTypes()) {
+            claimTypes.add(new ClaimTypeModel(claimTypeEntity.getId(), claimTypeEntity.getName(), claimTypeEntity.isBuiltIn(), ClaimTypeModel.ValueType.valueOf(claimTypeEntity.getType())));
+        }
+        return claimTypes;
+    }
+
+    @Override
+    public ClaimTypeModel addClaimType(String name, ClaimTypeModel.ValueType type, boolean builtIn) {
+        ClaimTypeEntity claimEntity = new ClaimTypeEntity();
+        claimEntity.setId(KeycloakModelUtils.generateId());
+        claimEntity.setType(type.name());
+        claimEntity.setBuiltIn(builtIn);
+        claimEntity.setRealm(realm);
+        em.persist(claimEntity);
+        realm.getClaimTypes().add(claimEntity);
+        return new ClaimTypeModel(claimEntity.getId(), name, builtIn, type);
+    }
+
+    protected ClaimTypeEntity getClaimTypeEntity(ClaimTypeModel claim) {
+        for (ClaimTypeEntity claimTypeEntity : realm.getClaimTypes()) {
+            if (claimTypeEntity.getId().equals(claim.getId())) {
+               return claimTypeEntity;
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public void removeClaimType(ClaimTypeModel claimType) {
+        ClaimTypeEntity toDelete = getClaimTypeEntity(claimType);
+        if (toDelete != null) {
+            realm.getClaimTypes().remove(toDelete);
+            em.remove(toDelete);
+        }
+    }
+
+    @Override
+    public ClaimTypeModel getClaimType(String name) {
+        for (ClaimTypeModel model : getClaimTypes()) {
+            if (model.getName().equals(name)) {
+                return model;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void updateClaimType(ClaimTypeModel claimType) {
+        ClaimTypeEntity updated = getClaimTypeEntity(claimType);
+        updated.setName(claimType.getName());
+        updated.setBuiltIn(claimType.isBuiltIn());
+        updated.setType(claimType.getType().name());
+        em.flush();
+    }
+
+    @Override
+    public Set<ProtocolClaimMappingModel> getProtocolClaimMappings() {
+        Set<ProtocolClaimMappingModel> mappings = new HashSet<ProtocolClaimMappingModel>();
+        for (ProtocolClaimMappingEntity entity : realm.getProtocolClaimMappings()) {
+            ProtocolClaimMappingModel mapping = new ProtocolClaimMappingModel();
+            mapping.setId(entity.getId());
+            mapping.setProtocol(entity.getProtocol());
+            mapping.setProtocolClaim(entity.getProtocolClaim());
+            mapping.setAppliedByDefault(entity.isAppliedByDefault());
+            mapping.setSource(ProtocolClaimMappingModel.Source.valueOf(entity.getSource()));
+            mapping.setSourceAttribute(entity.getSourceAttribute());
+            mappings.add(mapping);
+        }
+        return mappings;
+    }
+
+    @Override
+    public ProtocolClaimMappingModel addProtocolClaimMapping(String protocolClaim, String protocol, String sourceAttribute, ProtocolClaimMappingModel.Source source, boolean appliedByDefault) {
+        ProtocolClaimMappingEntity entity = new ProtocolClaimMappingEntity();
+        entity.setId(KeycloakModelUtils.generateId());
+        entity.setSourceAttribute(sourceAttribute);
+        entity.setProtocol(protocol);
+        entity.setProtocolClaim(protocolClaim);
+        entity.setSource(source.name());
+        entity.setAppliedByDefault(appliedByDefault);
+        entity.setRealm(realm);
+        em.persist(entity);
+        ProtocolClaimMappingModel mapping = new ProtocolClaimMappingModel();
+        mapping.setId(entity.getId());
+        mapping.setProtocol(entity.getProtocol());
+        mapping.setProtocolClaim(entity.getProtocolClaim());
+        mapping.setAppliedByDefault(entity.isAppliedByDefault());
+        mapping.setSource(ProtocolClaimMappingModel.Source.valueOf(entity.getSource()));
+        mapping.setSourceAttribute(entity.getSourceAttribute());
+        return mapping;
+    }
+
+    protected ProtocolClaimMappingEntity getProtocolClaimMapping(String id) {
+        for (ProtocolClaimMappingEntity entity : realm.getProtocolClaimMappings()) {
+            if (entity.getId().equals(id)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public void removeProtocolClaimMapping(ProtocolClaimMappingModel mapping) {
+        ProtocolClaimMappingEntity toDelete = getProtocolClaimMapping(mapping.getId());
+        if (toDelete != null) {
+            realm.getProtocolClaimMappings().remove(toDelete);
+            em.remove(toDelete);
+        }
+
+    }
+
+    @Override
+    public void updateProtocolClaimMapping(ProtocolClaimMappingModel mapping) {
+        ProtocolClaimMappingEntity entity = getProtocolClaimMapping(mapping.getId());
+        entity.setProtocol(mapping.getProtocol());
+        entity.setProtocolClaim(mapping.getProtocolClaim());
+        entity.setAppliedByDefault(mapping.isAppliedByDefault());
+        entity.setSource(mapping.getSource().name());
+        entity.setSourceAttribute(mapping.getSourceAttribute());
+        em.flush();
+
+    }
+
+    @Override
+    public ProtocolClaimMappingModel getProtocolClaimMappingById(String id) {
+        ProtocolClaimMappingEntity entity = getProtocolClaimMapping(id);
+        if (entity == null) return null;
+        ProtocolClaimMappingModel mapping = new ProtocolClaimMappingModel();
+        mapping.setId(entity.getId());
+        mapping.setProtocol(entity.getProtocol());
+        mapping.setProtocolClaim(entity.getProtocolClaim());
+        mapping.setAppliedByDefault(entity.isAppliedByDefault());
+        mapping.setSource(ProtocolClaimMappingModel.Source.valueOf(entity.getSource()));
+        mapping.setSourceAttribute(entity.getSourceAttribute());
+        return mapping;
+    }
 }
\ No newline at end of file
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index a574e1c..f24cc02 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -5,17 +5,21 @@ import com.mongodb.QueryBuilder;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClaimTypeModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.ProtocolClaimMappingModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.entities.ClaimTypeEntity;
 import org.keycloak.models.entities.IdentityProviderEntity;
+import org.keycloak.models.entities.ProtocolClaimMappingEntity;
 import org.keycloak.models.entities.RequiredCredentialEntity;
 import org.keycloak.models.entities.UserFederationProviderEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
@@ -783,6 +787,146 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
+    public Set<ProtocolClaimMappingModel> getProtocolClaimMappings() {
+        Set<ProtocolClaimMappingModel> result = new HashSet<ProtocolClaimMappingModel>();
+        for (ProtocolClaimMappingEntity entity : realm.getClaimMappings()) {
+            ProtocolClaimMappingModel mapping = new ProtocolClaimMappingModel();
+            mapping.setId(entity.getId());
+            mapping.setProtocolClaim(entity.getProtocolClaim());
+            mapping.setProtocol(entity.getProtocol());
+            mapping.setSource(entity.getSource());
+            mapping.setSourceAttribute(entity.getSourceAttribute());
+            mapping.setAppliedByDefault(entity.isAppliedByDefault());
+        }
+        return result;
+    }
+
+    @Override
+    public ProtocolClaimMappingModel addProtocolClaimMapping(String protocolClaim, String protocol, String sourceAttribute, ProtocolClaimMappingModel.Source source, boolean appliedByDefault) {
+        ProtocolClaimMappingEntity entity = new ProtocolClaimMappingEntity();
+        entity.setId(KeycloakModelUtils.generateId());
+        entity.setSourceAttribute(sourceAttribute);
+        entity.setProtocol(protocol);
+        entity.setProtocolClaim(protocolClaim);
+        entity.setSource(source);
+        entity.setAppliedByDefault(appliedByDefault);
+        realm.getClaimMappings().add(entity);
+        updateRealm();
+        ProtocolClaimMappingModel mapping = new ProtocolClaimMappingModel();
+        mapping.setId(entity.getId());
+        mapping.setProtocol(entity.getProtocol());
+        mapping.setProtocolClaim(entity.getProtocolClaim());
+        mapping.setAppliedByDefault(entity.isAppliedByDefault());
+        mapping.setSource(entity.getSource());
+        mapping.setSourceAttribute(entity.getSourceAttribute());
+        return mapping;
+    }
+
+    @Override
+    public void removeProtocolClaimMapping(ProtocolClaimMappingModel mapping) {
+        for (ProtocolClaimMappingEntity entity : realm.getClaimMappings()) {
+            if (entity.getId().equals(mapping.getId())) {
+                realm.getClaimMappings().remove(entity);
+                updateRealm();
+                break;
+            }
+        }
+
+    }
+
+    protected ProtocolClaimMappingEntity getProtocolClaimMapping(String id) {
+        for (ProtocolClaimMappingEntity entity : realm.getClaimMappings()) {
+            if (entity.getId().equals(id)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+
+
+    @Override
+    public void updateProtocolClaimMapping(ProtocolClaimMappingModel mapping) {
+        ProtocolClaimMappingEntity entity = getProtocolClaimMapping(mapping.getId());
+        entity.setProtocol(mapping.getProtocol());
+        entity.setProtocolClaim(mapping.getProtocolClaim());
+        entity.setAppliedByDefault(mapping.isAppliedByDefault());
+        entity.setSource(mapping.getSource());
+        entity.setSourceAttribute(mapping.getSourceAttribute());
+        updateRealm();
+
+    }
+
+    @Override
+    public ProtocolClaimMappingModel getProtocolClaimMappingById(String id) {
+        ProtocolClaimMappingEntity entity = getProtocolClaimMapping(id);
+        if (entity == null) return null;
+        ProtocolClaimMappingModel mapping = new ProtocolClaimMappingModel();
+        mapping.setId(entity.getId());
+        mapping.setProtocol(entity.getProtocol());
+        mapping.setProtocolClaim(entity.getProtocolClaim());
+        mapping.setAppliedByDefault(entity.isAppliedByDefault());
+        mapping.setSource(entity.getSource());
+        mapping.setSourceAttribute(entity.getSourceAttribute());
+        return mapping;
+    }
+
+    @Override
+    public Set<ClaimTypeModel> getClaimTypes() {
+        Set<ClaimTypeModel> result = new HashSet<ClaimTypeModel>();
+        for (ClaimTypeEntity entity : realm.getClaimTypes()) {
+            result.add(new ClaimTypeModel(entity.getId(), entity.getName(), entity.isBuiltIn(), entity.getType()));
+        }
+       return result;
+    }
+
+    @Override
+    public ClaimTypeModel addClaimType(String name, ClaimTypeModel.ValueType type, boolean builtIn) {
+        ClaimTypeModel claim = new ClaimTypeModel(KeycloakModelUtils.generateId(), name, builtIn, type);
+        ClaimTypeEntity entity = new ClaimTypeEntity();
+        entity.setId(claim.getId());
+        entity.setType(type);
+        entity.setBuiltIn(builtIn);
+        entity.setName(name);
+        realm.getClaimTypes().add(entity);
+        updateRealm();
+        return claim;
+    }
+
+    @Override
+    public void removeClaimType(ClaimTypeModel claimType) {
+        for (ClaimTypeEntity entity : realm.getClaimTypes()) {
+            if (entity.getId().equals(claimType.getId())) {
+                realm.getClaimTypes().remove(entity);
+                updateRealm();
+                break;
+            }
+        }
+    }
+
+    @Override
+    public ClaimTypeModel getClaimType(String name) {
+        for (ClaimTypeModel claimType : getClaimTypes()) {
+            if (claimType.getName().equals(name)) return claimType;
+        }
+        return null;
+    }
+
+    @Override
+    public void updateClaimType(ClaimTypeModel claimType) {
+        for (ClaimTypeEntity entity : realm.getClaimTypes()) {
+            if (entity.getId().equals(claimType.getId())) {
+                entity.setName(claimType.getName());
+                entity.setBuiltIn(claimType.isBuiltIn());
+                entity.setType(claimType.getType());
+                updateRealm();
+                break;
+            }
+        }
+    }
+
+
+    @Override
     public List<IdentityProviderModel> getIdentityProviders() {
         List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();