keycloak-aplcache
Changes
core/src/main/java/org/keycloak/representations/idm/ClientProtocolMappingRepresentation.java 26(+26 -0)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java 4(+2 -2)
services/src/main/java/org/keycloak/services/resources/admin/ClientProtocolMappersResource.java 134(+134 -0)
Details
diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 4349a75..9ca74f0 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -30,7 +30,7 @@ public class ApplicationRepresentation {
protected Integer nodeReRegistrationTimeout;
protected Map<String, Integer> registeredNodes;
protected List<String> allowedIdentityProviders;
- protected Set<String> protocolMappers;
+ protected List<ClientProtocolMappingRepresentation> protocolMappers;
public String getId() {
return id;
@@ -200,11 +200,11 @@ public class ApplicationRepresentation {
this.allowedIdentityProviders = allowedIdentityProviders;
}
- public Set<String> getProtocolMappers() {
+ public List<ClientProtocolMappingRepresentation> getProtocolMappers() {
return protocolMappers;
}
- public void setProtocolMappers(Set<String> protocolMappers) {
+ public void setProtocolMappers(List<ClientProtocolMappingRepresentation> protocolMappers) {
this.protocolMappers = protocolMappers;
}
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ClientProtocolMappingRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClientProtocolMappingRepresentation.java
new file mode 100755
index 0000000..e5252b1
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/ClientProtocolMappingRepresentation.java
@@ -0,0 +1,26 @@
+package org.keycloak.representations.idm;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ClientProtocolMappingRepresentation {
+ protected String protocol;
+ protected String name;
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
index dcb6ba8..aa095a7 100755
--- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
@@ -24,7 +24,7 @@ public class OAuthClientRepresentation {
protected Boolean fullScopeAllowed;
protected Boolean frontchannelLogout;
protected List<String> allowedIdentityProviders;
- protected Set<String> protocolClaimMappings;
+ protected List<ClientProtocolMappingRepresentation> protocolMappers;
public String getId() {
@@ -147,11 +147,11 @@ public class OAuthClientRepresentation {
this.allowedIdentityProviders = allowedIdentityProviders;
}
- public Set<String> getProtocolClaimMappings() {
- return protocolClaimMappings;
+ public List<ClientProtocolMappingRepresentation> getProtocolMappers() {
+ return protocolMappers;
}
- public void setProtocolClaimMappings(Set<String> protocolClaimMappings) {
- this.protocolClaimMappings = protocolClaimMappings;
+ public void setProtocolMappers(List<ClientProtocolMappingRepresentation> protocolMappers) {
+ this.protocolMappers = protocolMappers;
}
}
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 edcb44e..5354d04 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -105,7 +105,7 @@ public interface ClientModel {
boolean hasIdentityProvider(String providerId);
Set<ProtocolMapperModel> getProtocolMappers();
- void addProtocolMappers(Set<String> mapperNames);
- void removeProtocolMappers(Set<String> mapperNames);
- void setProtocolMappers(Set<String> mapperNames);
+ void addProtocolMappers(Set<String> mapperIds);
+ void removeProtocolMappers(Set<String> mapperIds);
+ void setProtocolMappers(Set<String> mapperIds);
}
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 510d72a..f70f825 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -249,7 +249,7 @@ public interface RealmModel extends RoleContainerModel {
void removeProtocolMapper(ProtocolMapperModel mapping);
void updateProtocolMapper(ProtocolMapperModel mapping);
public ProtocolMapperModel getProtocolMapperById(String id);
- public ProtocolMapperModel getProtocolMapperByName(String name);
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name);
}
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 949f974..522c965 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
@@ -19,6 +19,7 @@ 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.ClientProtocolMappingRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@@ -266,8 +267,12 @@ public class ModelToRepresentation {
}
if (!applicationModel.getProtocolMappers().isEmpty()) {
- Set<String> mappings = new HashSet<String>();
- for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) mappings.add(model.getName());
+ List<ClientProtocolMappingRepresentation> mappings = new LinkedList<ClientProtocolMappingRepresentation>();
+ for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) {
+ ClientProtocolMappingRepresentation map = new ClientProtocolMappingRepresentation();
+ map.setProtocol(model.getProtocol());
+ map.setName(model.getName());
+ }
rep.setProtocolMappers(mappings);
}
@@ -301,10 +306,15 @@ public class ModelToRepresentation {
}
if (!model.getProtocolMappers().isEmpty()) {
- Set<String> mappings = new HashSet<String>();
- for (ProtocolMapperModel mappingModel : model.getProtocolMappers()) mappings.add(mappingModel.getName());
- rep.setProtocolClaimMappings(mappings);
+ List<ClientProtocolMappingRepresentation> mappings = new LinkedList<ClientProtocolMappingRepresentation>();
+ for (ProtocolMapperModel mapping : model.getProtocolMappers()) {
+ ClientProtocolMappingRepresentation map = new ClientProtocolMappingRepresentation();
+ map.setProtocol(mapping.getProtocol());
+ map.setName(mapping.getName());
+ }
+ rep.setProtocolMappers(mappings);
}
+
return rep;
}
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index cc0b63d..9e152b8 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -23,6 +23,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.ClaimTypeRepresentation;
+import org.keycloak.representations.idm.ClientProtocolMappingRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@@ -461,9 +462,18 @@ public class RepresentationToModel {
}
if (resourceRep.getProtocolMappers() != null) {
- applicationModel.setProtocolMappers(resourceRep.getProtocolMappers());
+ Set<String> ids = new HashSet<String>();
+ for (ClientProtocolMappingRepresentation map : resourceRep.getProtocolMappers()) {
+ ProtocolMapperModel mapperModel = applicationModel.getRealm().getProtocolMapperByName(map.getProtocol(), map.getName());
+ if (mapperModel != null) {
+ ids.add(mapperModel.getId());
+ }
+
+ }
+ applicationModel.setProtocolMappers(ids);
}
+
return applicationModel;
}
@@ -637,8 +647,16 @@ public class RepresentationToModel {
model.updateAllowedIdentityProviders(rep.getAllowedIdentityProviders());
}
- if (rep.getProtocolClaimMappings() != null) {
- model.addProtocolMappers(rep.getProtocolClaimMappings());
+ if (rep.getProtocolMappers() != null) {
+ Set<String> ids = new HashSet<String>();
+ for (ClientProtocolMappingRepresentation map : rep.getProtocolMappers()) {
+ ProtocolMapperModel mapperModel = model.getRealm().getProtocolMapperByName(map.getProtocol(), map.getName());
+ if (mapperModel != null) {
+ ids.add(mapperModel.getId());
+ }
+
+ }
+ model.setProtocolMappers(ids);
}
}
@@ -777,7 +795,7 @@ public class RepresentationToModel {
// we make sure we don't recreate mappers that are automatically created by the protocol providers.
Set<ProtocolMapperModel> mappers = newRealm.getProtocolMappers();
for (ProtocolMapperRepresentation representation : rep.getProtocolMappers()) {
- ProtocolMapperModel existing = newRealm.getProtocolMapperByName(representation.getName());
+ ProtocolMapperModel existing = newRealm.getProtocolMapperByName(representation.getProtocol(), representation.getName());
if (existing == null) {
newRealm.addProtocolMapper(toModel(representation));
} else {
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 d036456..debd784 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
@@ -920,9 +920,9 @@ public class RealmAdapter implements RealmModel {
}
@Override
- public ProtocolMapperModel getProtocolMapperByName(String name) {
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
for (ProtocolMapperModel mapping : cached.getClaimMappings()) {
- if (mapping.getName().equals(name)) return mapping;
+ if (mapping.getProtocol().equals(protocol) && mapping.getName().equals(name)) return mapping;
}
return null;
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index f45c085..d4616fd 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -380,9 +380,10 @@ public abstract class ClientAdapter implements ClientModel {
return mappings;
}
- protected ProtocolMapperEntity findProtocolMapperByName(String name) {
- TypedQuery<ProtocolMapperEntity> query = em.createNamedQuery("getProtocolMapperByName", ProtocolMapperEntity.class);
+ protected ProtocolMapperEntity findProtocolMapperByName(String protocol, String name) {
+ TypedQuery<ProtocolMapperEntity> query = em.createNamedQuery("getProtocolMapperByNameProtocol", ProtocolMapperEntity.class);
query.setParameter("name", name);
+ query.setParameter("protocol", protocol);
query.setParameter("realm", entity.getRealm());
List<ProtocolMapperEntity> entities = query.getResultList();
if (entities.size() == 0) return null;
@@ -396,11 +397,11 @@ public abstract class ClientAdapter implements ClientModel {
Collection<ProtocolMapperEntity> entities = entity.getProtocolMappers();
Set<String> already = new HashSet<String>();
for (ProtocolMapperEntity rel : entities) {
- already.add(rel.getName());
+ already.add(rel.getId());
}
- for (String name : mappings) {
- if (!already.contains(name)) {
- ProtocolMapperEntity mapping = findProtocolMapperByName(name);
+ for (String id : mappings) {
+ if (!already.contains(id)) {
+ ProtocolMapperEntity mapping = em.find(ProtocolMapperEntity.class, id);
if (mapping != null) {
entities.add(mapping);
}
@@ -414,7 +415,7 @@ public abstract class ClientAdapter implements ClientModel {
Collection<ProtocolMapperEntity> entities = entity.getProtocolMappers();
List<ProtocolMapperEntity> remove = new LinkedList<ProtocolMapperEntity>();
for (ProtocolMapperEntity rel : entities) {
- if (mappings.contains(rel.getName())) remove.add(rel);
+ if (mappings.contains(rel.getId())) remove.add(rel);
}
for (ProtocolMapperEntity entity : remove) {
entities.remove(entity);
@@ -428,15 +429,15 @@ public abstract class ClientAdapter implements ClientModel {
Set<String> already = new HashSet<String>();
while (it.hasNext()) {
ProtocolMapperEntity mapper = it.next();
- if (mappings.contains(mapper.getName())) {
- already.add(mapper.getName());
+ if (mappings.contains(mapper.getId())) {
+ already.add(mapper.getId());
continue;
}
it.remove();
}
- for (String name : mappings) {
- if (!already.contains(name)) {
- ProtocolMapperEntity mapping = findProtocolMapperByName(name);
+ for (String id : mappings) {
+ if (!already.contains(id)) {
+ ProtocolMapperEntity mapping = em.find(ProtocolMapperEntity.class, id);
if (mapping != null) {
entities.add(mapping);
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
index 822049b..cfb7939 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
@@ -20,7 +20,7 @@ import java.util.Map;
*/
@Entity
@NamedQueries({
- @NamedQuery(name="getProtocolMapperByName", query="select mapper from ProtocolMapperEntity mapper where mapper.name = :name and mapper.realm = :realm")
+ @NamedQuery(name="getProtocolMapperByNameProtocol", query="select mapper from ProtocolMapperEntity mapper where mapper.protocol = :protocol and mapper.name = :name and mapper.realm = :realm")
})
@Table(name="PROTOCOL_MAPPER")
public class ProtocolMapperEntity {
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 6c4af39..00a3fbb 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
@@ -632,7 +632,7 @@ public class RealmAdapter implements RealmModel {
Set<String> adding = new HashSet<String>();
for (ProtocolMapperEntity mapper : realm.getProtocolMappers()) {
if (mapper.isAppliedByDefault()) {
- adding.add(mapper.getName());
+ adding.add(mapper.getId());
}
}
client.setProtocolMappers(adding);
@@ -1295,8 +1295,8 @@ public class RealmAdapter implements RealmModel {
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
- if (getProtocolMapperByName(model.getName()) != null) {
- throw new RuntimeException("Duplicate protocol mapper with name: " + model.getName());
+ if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
+ throw new RuntimeException("protocol mapper name must be unique per protocol");
}
String id = KeycloakModelUtils.generateId();
ProtocolMapperEntity entity = new ProtocolMapperEntity();
@@ -1325,9 +1325,9 @@ public class RealmAdapter implements RealmModel {
}
- protected ProtocolMapperEntity getProtocolMapperEntityByName(String name) {
+ protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
- if (entity.getName().equals(name)) {
+ if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
return entity;
}
}
@@ -1370,8 +1370,8 @@ public class RealmAdapter implements RealmModel {
}
@Override
- public ProtocolMapperModel getProtocolMapperByName(String name) {
- ProtocolMapperEntity entity = getProtocolMapperEntityByName(name);
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
+ ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
if (entity == null) return null;
return entityToModel(entity);
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index 7bc47a5..8d87dc0 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -303,22 +303,22 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
}
@Override
- public void addProtocolMappers(Set<String> mapperNames) {
- getMongoEntityAsClient().getProtocolMappers().addAll(mapperNames);
+ public void addProtocolMappers(Set<String> mapperIds) {
+ getMongoEntityAsClient().getProtocolMappers().addAll(mapperIds);
updateMongoEntity();
}
@Override
- public void removeProtocolMappers(Set<String> mapperNames) {
- getMongoEntityAsClient().getProtocolMappers().removeAll(mapperNames);
+ public void removeProtocolMappers(Set<String> mapperIds) {
+ getMongoEntityAsClient().getProtocolMappers().removeAll(mapperIds);
updateMongoEntity();
}
@Override
- public void setProtocolMappers(Set<String> mapperNames) {
+ public void setProtocolMappers(Set<String> mapperIds) {
getMongoEntityAsClient().getProtocolMappers().clear();
- getMongoEntityAsClient().getProtocolMappers().addAll(mapperNames);
+ getMongoEntityAsClient().getProtocolMappers().addAll(mapperIds);
updateMongoEntity();
}
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 065443f..d48ae7d 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
@@ -619,7 +619,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
public void addDefaultClientProtocolMappers(ClientModel client) {
Set<String> adding = new HashSet<String>();
for (ProtocolMapperEntity mapper : realm.getProtocolMappers()) {
- if (mapper.isAppliedByDefault()) adding.add(mapper.getName());
+ if (mapper.isAppliedByDefault()) adding.add(mapper.getId());
}
client.setProtocolMappers(adding);
@@ -820,6 +820,9 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
+ if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
+ throw new RuntimeException("protocol mapper name must be unique per protocol");
+ }
ProtocolMapperEntity entity = new ProtocolMapperEntity();
entity.setId(KeycloakModelUtils.generateId());
entity.setProtocol(model.getProtocol());
@@ -855,9 +858,9 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
return null;
}
- protected ProtocolMapperEntity getProtocolMapperyEntityByName(String name) {
+ protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
- if (entity.getName().equals(name)) {
+ if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
return entity;
}
}
@@ -891,8 +894,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
}
@Override
- public ProtocolMapperModel getProtocolMapperByName(String name) {
- ProtocolMapperEntity entity = getProtocolMapperyEntityById(name);
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
+ ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
if (entity == null) return null;
return entityToModel(entity);
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
index 08ee15f..4b60b6a 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
@@ -91,7 +91,7 @@ public class OIDCLoginProtocolFactory implements LoginProtocolFactory {
false);
ProtocolMapperModel fullName = new ProtocolMapperModel();
- if (realm.getProtocolMapperByName("full name") == null) {
+ if (realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "full name") == null) {
fullName.setName("full name");
fullName.setProtocolMapper(OIDCFullNameMapper.PROVIDER_ID);
fullName.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
@@ -102,7 +102,7 @@ public class OIDCLoginProtocolFactory implements LoginProtocolFactory {
}
ProtocolMapperModel address = new ProtocolMapperModel();
- if (realm.getProtocolMapperByName("address") == null) {
+ if (realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "address") == null) {
address.setName("address");
address.setProtocolMapper(OIDCAddressMapper.PROVIDER_ID);
address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
@@ -120,7 +120,7 @@ public class OIDCLoginProtocolFactory implements LoginProtocolFactory {
String tokenClaimName, String claimType,
boolean consentRequired, String consentText,
boolean appliedByDefault) {
- ProtocolMapperModel mapper = realm.getProtocolMapperByName(name);
+ ProtocolMapperModel mapper = realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, name);
if (mapper != null) return;
mapper = new ProtocolMapperModel();
mapper.setName(name);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index 5e5a242..583d886 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -4,6 +4,7 @@ import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
@@ -87,6 +88,14 @@ public class ApplicationResource {
return new ClaimResource(application, auth);
}
+ @Path("protocol-mappers")
+ public ClientProtocolMappersResource getProtocolMappers() {
+ ClientProtocolMappersResource mappers = new ClientProtocolMappersResource(realm, auth, application);
+ ResteasyProviderFactory.getInstance().injectProperties(mappers);
+ //resourceContext.initResource(mappers);
+ return mappers;
+ }
+
/**
* Update the application.
* @param rep
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientProtocolMappersResource.java
new file mode 100755
index 0000000..b4d9456
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientProtocolMappersResource.java
@@ -0,0 +1,134 @@
+package org.keycloak.services.resources.admin;
+
+import org.jboss.logging.Logger;
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Base resource for managing users
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ClientProtocolMappersResource {
+ protected static final Logger logger = Logger.getLogger(ClientProtocolMappersResource.class);
+ protected ClientModel client;
+ protected RealmModel realm;
+ protected RealmAuth auth;
+
+ @Context
+ protected UriInfo uriInfo;
+
+ @Context
+ protected KeycloakSession session;
+
+ public ClientProtocolMappersResource(RealmModel realm, RealmAuth auth, ClientModel client) {
+ this.auth = auth;
+ this.realm = realm;
+ this.client = client;
+
+ auth.init(RealmAuth.Resource.USER);
+ }
+
+ /**
+ * Map of mappers by name for a specific protocol attached to the client
+ *
+ * @param protocol
+ * @return
+ */
+ @GET
+ @NoCache
+ @Path("protocol/{protocol}")
+ @Produces("application/json")
+ public Map<String, ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
+ auth.requireView();
+ Map<String, ProtocolMapperRepresentation> mappers = new HashMap<String, ProtocolMapperRepresentation>();
+ for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
+ mappers.put(mapper.getName(), ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+ /**
+ * Add mappers to client.
+ *
+ * @param mapperIds List of mapper ids
+ */
+ @Path("models/add")
+ @PUT
+ @NoCache
+ @Consumes("application/json")
+ public void addMappers(Set<String> mapperIds) {
+ auth.requireManage();
+ client.addProtocolMappers(mapperIds);
+ }
+
+ /**
+ * replace sets of client mappers.
+ *
+ * @param mapperIds List of mapper ids
+ */
+ @Path("models/set")
+ @PUT
+ @NoCache
+ @Consumes("application/json")
+ public void setMappers(Set<String> mapperIds) {
+ auth.requireManage();
+ client.setProtocolMappers(mapperIds);
+ }
+
+ /**
+ * remove client mappers.
+ *
+ * @param mapperIds List of mapper ids
+ */
+ @Path("models/remove")
+ @PUT
+ @NoCache
+ @Consumes("application/json")
+ public void removeMappers(Set<String> mapperIds) {
+ auth.requireManage();
+ client.removeProtocolMappers(mapperIds);
+ }
+
+ @GET
+ @NoCache
+ @Path("models")
+ @Produces("application/json")
+ public List<ProtocolMapperRepresentation> getMappersPerProtocol() {
+ auth.requireView();
+ List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
+ for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
+ mappers.add(ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index 1bdf410..e5768e6 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -3,6 +3,7 @@ package org.keycloak.services.resources.admin;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.OAuthClientModel;
@@ -74,6 +75,19 @@ public class OAuthClientResource {
}
/**
+ * interface for updating attached ProtocolMappers
+ *
+ * @return
+ */
+ @Path("protocol-mappers")
+ public ClientProtocolMappersResource getProtocolMappers() {
+ ClientProtocolMappersResource mappers = new ClientProtocolMappersResource(realm, auth, oauthClient);
+ ResteasyProviderFactory.getInstance().injectProperties(mappers);
+ //resourceContext.initResource(mappers);
+ return mappers;
+ }
+
+ /**
*
* @param attributePrefix
* @return
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
new file mode 100755
index 0000000..2a7c82a
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
@@ -0,0 +1,150 @@
+package org.keycloak.services.resources.admin;
+
+import org.jboss.logging.Logger;
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.models.KerberosConstants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserFederationProvider;
+import org.keycloak.models.UserFederationProviderFactory;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
+import org.keycloak.representations.idm.UserFederationProviderRepresentation;
+import org.keycloak.services.managers.UsersSyncManager;
+import org.keycloak.timer.TimerProvider;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base resource for managing users
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ProtocolMappersResource {
+ protected static final Logger logger = Logger.getLogger(ProtocolMappersResource.class);
+
+ protected RealmModel realm;
+
+ protected RealmAuth auth;
+
+ @Context
+ protected UriInfo uriInfo;
+
+ @Context
+ protected KeycloakSession session;
+
+ public ProtocolMappersResource(RealmModel realm, RealmAuth auth) {
+ this.auth = auth;
+ this.realm = realm;
+
+ auth.init(RealmAuth.Resource.USER);
+ }
+
+ /**
+ * Map of mappers by name for a specific protocol
+ *
+ * @param protocol
+ * @return
+ */
+ @GET
+ @NoCache
+ @Path("protocol/{protocol}")
+ @Produces("application/json")
+ public Map<String, ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
+ auth.requireView();
+ Map<String, ProtocolMapperRepresentation> mappers = new HashMap<String, ProtocolMapperRepresentation>();
+ for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
+ mappers.put(mapper.getName(), ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+ /**
+ * createa mapper
+ *
+ * @param rep
+ */
+ @Path("models")
+ @POST
+ @NoCache
+ @Consumes("application/json")
+ public Response createMapper(ProtocolMapperRepresentation rep) {
+ auth.requireManage();
+ ProtocolMapperModel model = RepresentationToModel.toModel(rep);
+ realm.addProtocolMapper(model);
+ return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
+ }
+
+ @GET
+ @NoCache
+ @Path("models")
+ @Produces("application/json")
+ public List<ProtocolMapperRepresentation> getMappersPerProtocol() {
+ auth.requireView();
+ List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
+ for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
+ mappers.add(ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+ @GET
+ @NoCache
+ @Path("models/{id}")
+ @Produces("application/json")
+ public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) {
+ auth.requireView();
+ ProtocolMapperModel model = realm.getProtocolMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ return ModelToRepresentation.toRepresentation(model);
+ }
+
+ @PUT
+ @NoCache
+ @Path("models/{id}")
+ @Consumes("application/json")
+ public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) {
+ auth.requireManage();
+ ProtocolMapperModel model = realm.getProtocolMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ model = RepresentationToModel.toModel(rep);
+ realm.updateProtocolMapper(model);
+ }
+
+ @DELETE
+ @NoCache
+ @Path("models/{id}")
+ public void delete(@PathParam("id") String id) {
+ auth.requireManage();
+ ProtocolMapperModel model = realm.getProtocolMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ realm.removeProtocolMapper(model);
+ }
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 3e5c2b0..592fa6f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -274,6 +274,19 @@ public class RealmAdminResource {
}
/**
+ * Protocol mappers
+ *
+ */
+ @Path("protocol-mappers")
+ @POST
+ public ProtocolMappersResource protocolMappers() {
+ ProtocolMappersResource mappers = new ProtocolMappersResource(realm, auth);
+ ResteasyProviderFactory.getInstance().injectProperties(mappers);
+ //resourceContext.initResource(mappers);
+ return mappers;
+ }
+
+ /**
* Removes all user sessions. Any application that has an admin url will also be told to invalidate any sessions
* they have.
*
@@ -281,7 +294,6 @@ public class RealmAdminResource {
@Path("logout-all")
@POST
public GlobalRequestResult logoutAll() {
- auth.requireManage();
session.sessions().removeUserSessions(realm);
return new ResourceAdminManager().logoutAll(uriInfo.getRequestUri(), realm);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
index 2ac929d..ecde0fd 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
@@ -119,7 +119,6 @@ public class ServerInfoAdminResource {
}
}
-
private void setProtocols(ServerInfoRepresentation info) {
info.protocols = new LinkedList<String>();
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class)) {