keycloak-aplcache
Changes
forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html 2(+1 -1)
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java 2(+2 -0)
Details
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html
index c477f14..cf9f985 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html
@@ -22,7 +22,7 @@
</button>
</div>
<div class="pull-right">
- <a class="btn btn-primary" href="#/create/application/{{realm.realm}}">Add Application</a>
+ <a class="btn btn-primary" href="#/create/oauth-client/{{realm.realm}}">Add Client</a>
</div>
</th>
</tr>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
index ffafaa5..adcae87 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
@@ -7,10 +7,13 @@ import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
+import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -30,9 +33,6 @@ public class ApplicationEntity extends ClientEntity {
private String managementUrl;
private boolean bearerOnly;
- @ManyToOne()
- private RealmEntity realm;
-
@OneToMany(fetch = FetchType.EAGER, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "application")
Collection<ApplicationRoleEntity> roles = new ArrayList<ApplicationRoleEntity>();
@@ -80,14 +80,6 @@ public class ApplicationEntity extends ClientEntity {
this.defaultRoles = defaultRoles;
}
- public RealmEntity getRealm() {
- return realm;
- }
-
- public void setRealm(RealmEntity realm) {
- this.realm = realm;
- }
-
public boolean isBearerOnly() {
return bearerOnly;
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index b365ee0..0729553 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -4,6 +4,7 @@ import org.hibernate.annotations.GenericGenerator;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
+import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
@@ -11,8 +12,11 @@ import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
import java.util.HashSet;
import java.util.Set;
@@ -21,12 +25,14 @@ import java.util.Set;
* @version $Revision: 1 $
*/
@Entity
-@Inheritance(strategy = InheritanceType.JOINED)
-public class ClientEntity {
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"realm", "name"})})
+public abstract class ClientEntity {
@Id
@GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator")
@GeneratedValue(generator = "keycloak_generator")
private String id;
+ @Column(name = "name")
private String name;
private boolean enabled;
private String secret;
@@ -34,6 +40,9 @@ public class ClientEntity {
private int notBefore;
private boolean publicClient;
+ @ManyToOne
+ @JoinColumn(name = "realm")
+ protected RealmEntity realm;
@ElementCollection
@CollectionTable
@@ -42,6 +51,13 @@ public class ClientEntity {
@CollectionTable
protected Set<String> redirectUris = new HashSet<String>();
+ public RealmEntity getRealm() {
+ return realm;
+ }
+
+ public void setRealm(RealmEntity realm) {
+ this.realm = realm;
+ }
public String getId() {
return id;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
index ff69530..2a57024 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
@@ -1,20 +1,8 @@
package org.keycloak.models.jpa.entities;
-import javax.persistence.CollectionTable;
-import javax.persistence.ElementCollection;
import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
-import javax.persistence.OneToOne;
-
-import org.hibernate.annotations.GenericGenerator;
-
-import java.util.HashSet;
-import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -27,17 +15,4 @@ import java.util.Set;
})
@Entity
public class OAuthClientEntity extends ClientEntity {
-
- @ManyToOne()
- private RealmEntity realm;
-
- 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 7d4b5a9..ba662f4 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
@@ -83,7 +83,7 @@ public class RealmEntity {
@JoinTable(name="AuthProviders")
List<AuthenticationProviderEntity> authenticationProviders = new ArrayList<AuthenticationProviderEntity>();
- @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
+ @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
Collection<ApplicationEntity> applications = new ArrayList<ApplicationEntity>();
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java
index 6e7f3f3..a300b0f 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java
@@ -3,6 +3,7 @@ package org.keycloak.models.jpa;
import org.keycloak.models.KeycloakTransaction;
import javax.persistence.EntityManager;
+import javax.persistence.PersistenceException;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -23,7 +24,11 @@ public class JpaKeycloakTransaction implements KeycloakTransaction {
@Override
public void commit() {
- em.getTransaction().commit();
+ try {
+ em.getTransaction().commit();
+ } catch (PersistenceException e) {
+ throw PersistenceExceptionConverter.convert(e.getCause());
+ }
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
index 1ae4a3d..48d0e4f 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
@@ -21,5 +21,6 @@ public class OAuthClientAdapter extends ClientAdapter implements OAuthClientMode
@Override
public void setClientId(String id) {
entity.setName(id);
+
}
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
index 712f1e7..dfa5053 100644
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
@@ -6,6 +6,7 @@ import org.keycloak.models.ModelDuplicateException;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
+import javax.persistence.PersistenceException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -31,14 +32,17 @@ public class PersistenceExceptionConverter implements InvocationHandler {
try {
return method.invoke(em, args);
} catch (InvocationTargetException e) {
- Throwable c = e.getCause();
- if (c.getCause() != null && c.getCause() instanceof ConstraintViolationException) {
- throw new ModelDuplicateException(c);
- } if (c instanceof EntityExistsException) {
- throw new ModelDuplicateException(c);
- } else {
- throw new ModelException(c);
- }
+ throw convert(e.getCause());
+ }
+ }
+
+ public static ModelException convert(Throwable t) {
+ if (t.getCause() != null && t.getCause() instanceof ConstraintViolationException) {
+ throw new ModelDuplicateException(t);
+ } if (t instanceof EntityExistsException) {
+ throw new ModelDuplicateException(t);
+ } else {
+ throw new ModelException(t);
}
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
index be086d9..c98842e 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
@@ -7,12 +7,14 @@ import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoField;
+import org.keycloak.models.mongo.api.MongoIndex;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "applications")
+@MongoIndex(name = "name-within-realm", fields = { "realmId", "name" }, unique = true)
public class ApplicationEntity extends ClientEntity {
private boolean surrogateAuthRequired;
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
index 7c6ea58..0ca8045 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
@@ -1,6 +1,7 @@
package org.keycloak.models.mongo.keycloak.entities;
import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoIndex;
import java.util.List;
@@ -8,6 +9,7 @@ import java.util.List;
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "oauthClients")
+@MongoIndex(name = "name-within-realm", fields = { "realmId", "name" }, unique = true)
public class OAuthClientEntity extends ClientEntity {
}
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
index 625e959..a6c2315 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
@@ -218,9 +218,9 @@ public class AdapterTest extends AbstractModelTest {
realmModel.addScopeMapping(app, realmRole);
- Assert.assertTrue(identitySession.removeRealm(realmModel.getId()));
- Assert.assertFalse(identitySession.removeRealm(realmModel.getId()));
- Assert.assertNull(identitySession.getRealm(realmModel.getId()));
+ Assert.assertTrue(realmManager.removeRealm(realmModel));
+ Assert.assertFalse(realmManager.removeRealm(realmModel));
+ Assert.assertNull(realmManager.getRealm(realmModel.getId()));
}
@@ -522,17 +522,80 @@ public class AdapterTest extends AbstractModelTest {
commit(true);
// Ty to rename realm to duplicate name
- realmModel = realmManager.createRealm("JUGGLER2");
+ realmManager.createRealm("JUGGLER2");
+ commit();
+ try {
+ realmManager.getRealmByName("JUGGLER2").setName("JUGGLER");
+ commit();
+ Assert.fail("Expected exception");
+ } catch (ModelDuplicateException e) {
+ }
+
+ identitySession.close();
+ identitySession = factory.createSession();
+ identitySession.getTransaction().begin();
+ }
+
+ @Test
+ public void testAppNameCollisions() throws Exception {
+ realmManager.createRealm("JUGGLER1").addApplication("app1");
+ realmManager.createRealm("JUGGLER2").addApplication("app1");
+
commit();
- realmModel = realmManager.getRealmByName("JUGGLER2");
+ // Try to create app with duplicate name
try {
- realmModel.setName("JUGGLER");
+ realmManager.getRealmByName("JUGGLER1").addApplication("app1");
commit();
Assert.fail("Expected exception");
} catch (ModelDuplicateException e) {
}
commit(true);
+
+ // Ty to rename app to duplicate name
+ realmManager.getRealmByName("JUGGLER1").addApplication("app2");
+ commit();
+ try {
+ realmManager.getRealmByName("JUGGLER1").getApplicationByName("app2").setName("app1");
+ commit();
+ Assert.fail("Expected exception");
+ } catch (ModelDuplicateException e) {
+ }
+
+ identitySession.close();
+ identitySession = factory.createSession();
+ identitySession.getTransaction().begin();
+ }
+
+ @Test
+ public void testClientNameCollisions() throws Exception {
+ realmManager.createRealm("JUGGLER1").addOAuthClient("client1");
+ realmManager.createRealm("JUGGLER2").addOAuthClient("client1");
+
+ commit();
+
+ // Try to create app with duplicate name
+ try {
+ realmManager.getRealmByName("JUGGLER1").addOAuthClient("client1");
+ commit();
+ Assert.fail("Expected exception");
+ } catch (ModelDuplicateException e) {
+ }
+ commit(true);
+
+ // Ty to rename app to duplicate name
+ realmManager.getRealmByName("JUGGLER1").addOAuthClient("client2");
+ commit();
+ try {
+ realmManager.getRealmByName("JUGGLER1").getOAuthClient("client2").setClientId("client1");
+ commit();
+ Assert.fail("Expected exception");
+ } catch (ModelDuplicateException e) {
+ }
+
+ identitySession.close();
+ identitySession = factory.createSession();
+ identitySession.getTransaction().begin();
}
}
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 4f7b9e0..ff76a99 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -104,9 +104,9 @@ public class RealmManager {
public boolean removeRealm(RealmModel realm) {
boolean removed = identitySession.removeRealm(realm.getId());
-
- getKeycloakAdminstrationRealm().removeApplication(realm.getAdminApp().getId());
-
+ if (removed) {
+ getKeycloakAdminstrationRealm().removeApplication(realm.getAdminApp().getId());
+ }
return removed;
}
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 0fb20a9..8878c6b 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
@@ -5,6 +5,7 @@ import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.NotFoundException;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
@@ -17,6 +18,7 @@ import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.services.resources.KeycloakApplication;
+import org.keycloak.services.resources.flows.Flows;
import org.keycloak.util.JsonSerialization;
import javax.ws.rs.Consumes;
@@ -32,6 +34,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.util.HashMap;
@@ -74,11 +77,16 @@ public class ApplicationResource {
@PUT
@Consumes(MediaType.APPLICATION_JSON)
- public void update(final ApplicationRepresentation rep) {
+ public Response update(final ApplicationRepresentation rep) {
auth.requireManage();
ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
- applicationManager.updateApplication(rep, application);
+ try {
+ applicationManager.updateApplication(rep, application);
+ return Response.noContent().build();
+ } catch (ModelDuplicateException e) {
+ return Flows.errors().exists("Application " + rep.getName() + " already exists");
+ }
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index ec236cf..d3e9543 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -6,6 +6,7 @@ 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;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.services.managers.ApplicationManager;
@@ -72,12 +73,13 @@ public class ApplicationsResource {
public Response createApplication(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) {
auth.requireManage();
- if (realm.getApplicationNameMap().containsKey(rep.getName())) {
+ ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
+ try {
+ ApplicationModel applicationModel = resourceManager.createApplication(realm, rep);
+ return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getName()).build()).build();
+ } catch (ModelDuplicateException e) {
return Flows.errors().exists("Application " + rep.getName() + " already exists");
}
- ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
- ApplicationModel applicationModel = resourceManager.createApplication(realm, rep);
- return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getName()).build()).build();
}
@Path("{app-name}")
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 eb72e63..5b07018 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
@@ -4,6 +4,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.NotFoundException;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
@@ -12,6 +13,7 @@ import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.OAuthClientManager;
import org.keycloak.services.resources.KeycloakApplication;
+import org.keycloak.services.resources.flows.Flows;
import org.keycloak.util.JsonSerialization;
import javax.ws.rs.Consumes;
@@ -24,6 +26,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
@@ -64,11 +67,16 @@ public class OAuthClientResource {
@PUT
@Consumes(MediaType.APPLICATION_JSON)
- public void update(final OAuthClientRepresentation rep) {
+ public Response update(final OAuthClientRepresentation rep) {
auth.requireManage();
OAuthClientManager manager = new OAuthClientManager(realm);
- manager.update(rep, oauthClient);
+ try {
+ manager.update(rep, oauthClient);
+ return Response.noContent().build();
+ } catch (ModelDuplicateException e) {
+ return Flows.errors().exists("Client " + rep.getName() + " already exists");
+ }
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index 3fdcd16..f940c93 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -5,10 +5,12 @@ import org.jboss.resteasy.logging.Logger;
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;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.services.managers.OAuthClientManager;
+import org.keycloak.services.resources.flows.Flows;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -74,8 +76,12 @@ public class OAuthClientsResource {
auth.requireManage();
OAuthClientManager resourceManager = new OAuthClientManager(realm);
- OAuthClientModel oauth = resourceManager.create(rep);
- return Response.created(uriInfo.getAbsolutePathBuilder().path(oauth.getId()).build()).build();
+ try {
+ OAuthClientModel oauth = resourceManager.create(rep);
+ return Response.created(uriInfo.getAbsolutePathBuilder().path(oauth.getId()).build()).build();
+ } catch (ModelDuplicateException e) {
+ return Flows.errors().exists("Client " + rep.getName() + " already exists");
+ }
}
@Path("{id}")
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 2e56437..7ec8c16 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
@@ -9,6 +9,7 @@ import org.keycloak.audit.Event;
import org.keycloak.audit.EventQuery;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.adapters.action.SessionStats;
import org.keycloak.representations.idm.RealmAuditRepresentation;
@@ -18,10 +19,12 @@ import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.services.managers.TokenManager;
+import org.keycloak.services.resources.flows.Flows;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -94,11 +97,16 @@ public class RealmAdminResource {
@PUT
@Consumes("application/json")
- public void updateRealm(final RealmRepresentation rep) {
+ public Response updateRealm(final RealmRepresentation rep) {
auth.requireManage();
logger.debug("updating realm: " + realm.getName());
- new RealmManager(session).updateRealm(rep, realm);
+ try {
+ new RealmManager(session).updateRealm(rep, realm);
+ return Response.noContent().build();
+ } catch (ModelDuplicateException e) {
+ return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
+ }
}
@DELETE