keycloak-aplcache
Changes
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProviderResource.java 27(+27 -0)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java 29(+29 -0)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java 3(+3 -0)
services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java 147(+18 -129)
Details
diff --git a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
index cc4b3e6..b9f09c3 100644
--- a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
@@ -26,6 +26,7 @@ import java.util.Map;
public class IdentityProviderRepresentation {
protected String id;
+ protected String internalId;
protected String providerId;
protected String name;
protected boolean enabled = true;
@@ -34,6 +35,14 @@ public class IdentityProviderRepresentation {
protected String groupName;
protected Map<String, String> config = new HashMap<String, String>();
+ public String getInternalId() {
+ return this.internalId;
+ }
+
+ public void setInternalId(String internalId) {
+ this.internalId = internalId;
+ }
+
public String getId() {
return this.id;
}
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
index 13db021..7a31d03 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
@@ -160,7 +160,25 @@ module.config([ '$routeProvider', function($routeProvider) {
return {};
},
providerFactory : function(IdentityProviderFactoryLoader) {
- return IdentityProviderFactoryLoader();
+ return {};
+ }
+ },
+ controller : 'RealmIdentityProviderCtrl'
+ })
+ .when('/create/identity-provider/:realm/:provider_id', {
+ templateUrl : function(params){ return 'partials/realm-identity-provider-' + params.provider_id + '.html'; },
+ resolve : {
+ realm : function(RealmLoader) {
+ return RealmLoader();
+ },
+ serverInfo : function(ServerInfoLoader) {
+ return ServerInfoLoader();
+ },
+ instance : function(IdentityProviderLoader) {
+ return {};
+ },
+ providerFactory : function(IdentityProviderFactoryLoader) {
+ return new IdentityProviderFactoryLoader();
}
},
controller : 'RealmIdentityProviderCtrl'
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
index ec05bb0..98a6e6b 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
@@ -722,7 +722,7 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
$scope.callbackUrl = $location.absUrl().replace(/\/admin.*/, "/broker/") + realm.realm + "/" ;
$scope.addProvider = function(provider) {
- $location.url("/realms/" + realm.realm + "/identity-provider-settings/provider/" + provider.id + "/" + provider.id);
+ $location.url("/create/identity-provider/" + realm.realm + "/" + provider.id);
};
$scope.remove = function() {
@@ -746,7 +746,8 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
});
} else {
IdentityProvider.update({
- realm: $scope.realm.realm
+ realm: $scope.realm.realm,
+ id: $scope.identityProvider.internalId
}, $scope.identityProvider, function () {
$location.url("/realms/" + realm.realm + "/identity-provider-settings");
Notifications.success("The " + $scope.identityProvider.name + " provider has been update.");
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProviderResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProviderResource.java
new file mode 100755
index 0000000..48a9d5b
--- /dev/null
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProviderResource.java
@@ -0,0 +1,27 @@
+package org.keycloak.admin.client.resource;
+
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * @author pedroigor
+ */
+public interface IdentityProviderResource {
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ IdentityProviderRepresentation toRepresentation();
+
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ void update(IdentityProviderRepresentation identityProviderRepresentation);
+
+ @DELETE
+ void remove();
+}
\ No newline at end of file
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java
new file mode 100755
index 0000000..16ae0e9
--- /dev/null
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java
@@ -0,0 +1,29 @@
+package org.keycloak.admin.client.resource;
+
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.List;
+
+/**
+ * @author pedroigor
+ */
+public interface IdentityProvidersResource {
+
+ @Path("{id}")
+ IdentityProviderResource get(@PathParam("id") String id);
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ List<IdentityProviderRepresentation> findAll();
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ void create(IdentityProviderRepresentation identityProvider);
+}
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
index fa7309a..1ed0a80 100644
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
@@ -35,6 +35,9 @@ public interface RealmResource {
@Path("roles")
public RolesResource roles();
+ @Path("identity-provider")
+ IdentityProvidersResource identityProviders();
+
@DELETE
public void remove();
diff --git a/model/api/src/main/java/org/keycloak/models/AdminRoles.java b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
index a988951..8d46505 100755
--- a/model/api/src/main/java/org/keycloak/models/AdminRoles.java
+++ b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
@@ -19,13 +19,15 @@ public class AdminRoles {
public static String VIEW_APPLICATIONS = "view-applications";
public static String VIEW_CLIENTS = "view-clients";
public static String VIEW_EVENTS = "view-events";
+ public static String VIEW_IDENTITY_PROVIDERS = "view-identity-providers";
public static String MANAGE_REALM = "manage-realm";
public static String MANAGE_USERS = "manage-users";
public static String MANAGE_APPLICATIONS = "manage-applications";
+ public static String MANAGE_IDENTITY_PROVIDERS = "manage-identity-providers";
public static String MANAGE_CLIENTS = "manage-clients";
public static String MANAGE_EVENTS = "manage-events";
- public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, VIEW_EVENTS, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS, MANAGE_EVENTS};
+ public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, VIEW_EVENTS, VIEW_IDENTITY_PROVIDERS, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS, MANAGE_EVENTS, MANAGE_IDENTITY_PROVIDERS};
}
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 8fe9688..f89acaa 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
@@ -146,16 +146,7 @@ public class ModelToRepresentation {
}
for (IdentityProviderModel provider : realm.getIdentityProviders()) {
- IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation();
-
- providerRep.setProviderId(provider.getProviderId());
- providerRep.setId(provider.getId());
- providerRep.setName(provider.getName());
- providerRep.setEnabled(provider.isEnabled());
- providerRep.setUpdateProfileFirstLogin(provider.isUpdateProfileFirstLogin());
- providerRep.setConfig(provider.getConfig());
-
- rep.addIdentityProvider(providerRep);
+ rep.addIdentityProvider(toRepresentation(provider));
}
return rep;
@@ -306,4 +297,19 @@ public class ModelToRepresentation {
rep.setLastSync(model.getLastSync());
return rep;
}
+
+ public static IdentityProviderRepresentation toRepresentation(IdentityProviderModel identityProviderModel) {
+ IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation();
+
+ providerRep.setInternalId(identityProviderModel.getInternalId());
+ providerRep.setProviderId(identityProviderModel.getProviderId());
+ providerRep.setId(identityProviderModel.getId());
+ providerRep.setName(identityProviderModel.getName());
+ providerRep.setEnabled(identityProviderModel.isEnabled());
+ providerRep.setStoreToken(identityProviderModel.isStoreToken());
+ providerRep.setUpdateProfileFirstLogin(identityProviderModel.isUpdateProfileFirstLogin());
+ providerRep.setConfig(identityProviderModel.getConfig());
+
+ return providerRep;
+ }
}
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 0c7835c..8463168 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
@@ -744,19 +744,24 @@ public class RepresentationToModel {
private static void importIdentityProviders(RealmRepresentation rep, RealmModel newRealm) {
if (rep.getIdentityProviders() != null) {
- for (IdentityProviderRepresentation identityProviderRepresentation : rep.getIdentityProviders()) {
- IdentityProviderModel identityProviderModel = new IdentityProviderModel();
-
- identityProviderModel.setId(identityProviderRepresentation.getId());
- identityProviderModel.setProviderId(identityProviderRepresentation.getProviderId());
- identityProviderModel.setName(identityProviderRepresentation.getName());
- identityProviderModel.setEnabled(identityProviderRepresentation.isEnabled());
- identityProviderModel.setUpdateProfileFirstLogin(identityProviderRepresentation.isUpdateProfileFirstLogin());
- identityProviderModel.setStoreToken(identityProviderRepresentation.isStoreToken());
- identityProviderModel.setConfig(identityProviderRepresentation.getConfig());
-
- newRealm.addIdentityProvider(identityProviderModel);
+ for (IdentityProviderRepresentation representation : rep.getIdentityProviders()) {
+ newRealm.addIdentityProvider(toModel(representation));
}
}
}
+
+ public static IdentityProviderModel toModel(IdentityProviderRepresentation representation) {
+ IdentityProviderModel identityProviderModel = new IdentityProviderModel();
+
+ identityProviderModel.setInternalId(representation.getInternalId());
+ identityProviderModel.setId(representation.getId());
+ identityProviderModel.setProviderId(representation.getProviderId());
+ identityProviderModel.setName(representation.getName());
+ identityProviderModel.setEnabled(representation.isEnabled());
+ identityProviderModel.setUpdateProfileFirstLogin(representation.isUpdateProfileFirstLogin());
+ identityProviderModel.setStoreToken(representation.isStoreToken());
+ identityProviderModel.setConfig(representation.getConfig());
+
+ return identityProviderModel;
+ }
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
index 1917844..1e61b3e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
@@ -1,36 +1,21 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
-import org.jboss.resteasy.plugins.providers.multipart.InputPart;
-import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
-import org.keycloak.broker.provider.IdentityProvider;
-import org.keycloak.broker.provider.IdentityProviderFactory;
-import org.keycloak.models.ClientModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.social.SocialIdentityProvider;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.services.resources.flows.Flows;
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.MediaType;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
/**
* @author Pedro Igor
@@ -39,132 +24,36 @@ public class IdentityProviderResource {
private final RealmModel realm;
private final KeycloakSession session;
+ private final IdentityProviderModel identityProviderModel;
- public IdentityProviderResource(RealmModel realm, KeycloakSession session) {
+ public IdentityProviderResource(RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel) {
this.realm = realm;
this.session = session;
+ this.identityProviderModel = identityProviderModel;
}
@GET
@NoCache
@Produces("application/json")
- public List<IdentityProviderModel> getIdentityProviders() {
- return realm.getIdentityProviders();
- }
-
- @Path("/providers/{provider_id}")
- @GET
- @NoCache
- @Produces("application/json")
- public Response getIdentityProviders(@PathParam("provider_id") String providerId) {
- IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
-
- if (providerFactory != null) {
- return Response.ok(providerFactory).build();
- }
-
- return Response.status(BAD_REQUEST).build();
- }
-
- @POST
- @Consumes(MediaType.APPLICATION_JSON)
- public Response create(@Context UriInfo uriInfo, IdentityProviderModel providerModel) {
- realm.addIdentityProvider(providerModel);
-
- return Response.created(uriInfo.getAbsolutePathBuilder().path(providerModel.getProviderId()).build()).build();
- }
-
- @POST
- @Consumes(MediaType.MULTIPART_FORM_DATA)
- public Response createWithFile(@Context UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
- Map<String, List<InputPart>> formDataMap = input.getFormDataMap();
-
- String id = formDataMap.get("id").get(0).getBodyAsString();
- String name = formDataMap.get("name").get(0).getBodyAsString();
- String providerId = formDataMap.get("providerId").get(0).getBodyAsString();
- String enabled = formDataMap.get("enabled").get(0).getBodyAsString();
- String updateProfileFirstLogin = formDataMap.get("updateProfileFirstLogin").get(0).getBodyAsString();
- String storeToken = formDataMap.get("storeToken").get(0).getBodyAsString();
- InputPart file = formDataMap.get("file").get(0);
- InputStream inputStream = file.getBody(InputStream.class, null);
- IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
- Map config = providerFactory.parseConfig(inputStream);
- IdentityProviderModel providerModel = new IdentityProviderModel();
-
- providerModel.setId(id);
- providerModel.setName(name);
- providerModel.setProviderId(providerId);
- providerModel.setEnabled(Boolean.valueOf(enabled));
- providerModel.setUpdateProfileFirstLogin(Boolean.valueOf(updateProfileFirstLogin));
- providerModel.setStoreToken(Boolean.valueOf(storeToken));
- providerModel.setConfig(config);
-
- return create(uriInfo, providerModel);
- }
-
- @Path("{id}")
- @GET
- @NoCache
- @Produces("application/json")
- public Response getIdentityProvider(@PathParam("id") String providerId) {
- for (IdentityProviderModel identityProviderModel : this.realm.getIdentityProviders()) {
- if (identityProviderModel.getId().equals(providerId)) {
- return Response.ok(identityProviderModel).build();
- }
- }
-
- return Response.noContent().build();
+ public IdentityProviderRepresentation getIdentityProvider() {
+ return ModelToRepresentation.toRepresentation(this.identityProviderModel);
}
- @Path("{id}")
@DELETE
@NoCache
- public Response delete(@PathParam("id") String providerId) {
- for (ClientModel applicationModel : getClientModels()) {
- List<String> allowedIdentityProviders = applicationModel.getAllowedIdentityProviders();
-
- for (String appProvider : new ArrayList<String>(allowedIdentityProviders)) {
- if (appProvider.equals(providerId)) {
- allowedIdentityProviders.remove(appProvider);
- }
- }
-
- applicationModel.updateAllowedIdentityProviders(allowedIdentityProviders);
- }
-
- this.realm.removeIdentityProviderById(providerId);
-
+ public Response delete() {
+ this.realm.removeIdentityProviderById(this.identityProviderModel.getId());
return Response.noContent().build();
}
- private List<ClientModel> getClientModels() {
- List<ClientModel> clients = new ArrayList<ClientModel>();
-
- clients.addAll(this.realm.getOAuthClients());
- clients.addAll(this.realm.getApplications());
-
- return clients;
- }
-
@PUT
@Consumes("application/json")
- public Response update(IdentityProviderModel model) {
- this.realm.updateIdentityProvider(model);
- return Response.noContent().build();
- }
-
- private IdentityProviderFactory getProviderFactorytById(String providerId) {
- List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
-
- allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
- allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
-
- for (ProviderFactory providerFactory : allProviders) {
- if (providerFactory.getId().equals(providerId)) {
- return (IdentityProviderFactory) providerFactory;
- }
+ public Response update(IdentityProviderRepresentation model) {
+ try {
+ this.realm.updateIdentityProvider(RepresentationToModel.toModel(model));
+ return Response.noContent().build();
+ } catch (ModelDuplicateException e) {
+ return Flows.errors().exists("Identity Provider " + model.getId() + " already exists");
}
-
- return null;
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
new file mode 100755
index 0000000..42c3497
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
@@ -0,0 +1,169 @@
+package org.keycloak.services.resources.admin;
+
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.broker.provider.IdentityProvider;
+import org.keycloak.broker.provider.IdentityProviderFactory;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.services.resources.flows.Flows;
+import org.keycloak.social.SocialIdentityProvider;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+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.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+
+/**
+ * @author Pedro Igor
+ */
+public class IdentityProvidersResource {
+
+ private final RealmModel realm;
+ private final KeycloakSession session;
+ private RealmAuth auth;
+
+ public IdentityProvidersResource(RealmModel realm, KeycloakSession session, RealmAuth auth) {
+ this.realm = realm;
+ this.session = session;
+ this.auth = auth;
+ this.auth.init(RealmAuth.Resource.IDENTITY_PROVIDER);
+ }
+
+ @GET
+ @NoCache
+ @Produces("application/json")
+ public List<IdentityProviderRepresentation> getIdentityProviders() {
+ this.auth.requireView();
+
+ List<IdentityProviderRepresentation> representations = new ArrayList<IdentityProviderRepresentation>();
+
+ for (IdentityProviderModel identityProviderModel : realm.getIdentityProviders()) {
+ representations.add(ModelToRepresentation.toRepresentation(identityProviderModel));
+ }
+
+ return representations;
+ }
+
+ @Path("/providers/{provider_id}")
+ @GET
+ @NoCache
+ @Produces("application/json")
+ public Response getIdentityProviders(@PathParam("provider_id") String providerId) {
+ this.auth.requireView();
+ IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
+
+ if (providerFactory != null) {
+ return Response.ok(providerFactory).build();
+ }
+
+ return Response.status(BAD_REQUEST).build();
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response create(@Context UriInfo uriInfo, IdentityProviderRepresentation representation) {
+ this.auth.requireManage();
+
+ try {
+ this.realm.addIdentityProvider(RepresentationToModel.toModel(representation));
+ return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build();
+ } catch (ModelDuplicateException e) {
+ return Flows.errors().exists("Identity Provider " + representation.getId() + " already exists");
+ }
+ }
+
+ @POST
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ public Response createWithFile(@Context UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
+ this.auth.requireManage();
+ Map<String, List<InputPart>> formDataMap = input.getFormDataMap();
+
+ String id = formDataMap.get("id").get(0).getBodyAsString();
+ String name = formDataMap.get("name").get(0).getBodyAsString();
+ String providerId = formDataMap.get("providerId").get(0).getBodyAsString();
+ String enabled = formDataMap.get("enabled").get(0).getBodyAsString();
+ String updateProfileFirstLogin = formDataMap.get("updateProfileFirstLogin").get(0).getBodyAsString();
+ String storeToken = formDataMap.get("storeToken").get(0).getBodyAsString();
+ InputPart file = formDataMap.get("file").get(0);
+ InputStream inputStream = file.getBody(InputStream.class, null);
+ IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
+ Map config = providerFactory.parseConfig(inputStream);
+ IdentityProviderRepresentation representation = new IdentityProviderRepresentation();
+
+ representation.setId(id);
+ representation.setName(name);
+ representation.setProviderId(providerId);
+ representation.setEnabled(Boolean.valueOf(enabled));
+ representation.setUpdateProfileFirstLogin(Boolean.valueOf(updateProfileFirstLogin));
+ representation.setStoreToken(Boolean.valueOf(storeToken));
+ representation.setConfig(config);
+
+ return create(uriInfo, representation);
+ }
+
+ @Path("{id}")
+ public IdentityProviderResource getIdentityProvider(@PathParam("id") String providerId) {
+ this.auth.requireView();
+ IdentityProviderModel identityProviderModel = null;
+
+ for (IdentityProviderModel storedIdentityProvider : this.realm.getIdentityProviders()) {
+ if (storedIdentityProvider.getId().equals(providerId)
+ || storedIdentityProvider.getInternalId().equals(providerId)) {
+ identityProviderModel = storedIdentityProvider;
+ }
+ }
+
+ if (identityProviderModel == null) {
+ throw new NotFoundException("Could not find identity provider: " + providerId);
+ }
+
+ IdentityProviderResource identityProviderResource = new IdentityProviderResource(realm, session, identityProviderModel);
+ ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource);
+
+ return identityProviderResource;
+ }
+
+ private IdentityProviderFactory getProviderFactorytById(String providerId) {
+ List<ProviderFactory> allProviders = getProviderFactories();
+
+ for (ProviderFactory providerFactory : allProviders) {
+ if (providerFactory.getId().equals(providerId)) {
+ return (IdentityProviderFactory) providerFactory;
+ }
+ }
+
+ return null;
+ }
+
+ private List<ProviderFactory> getProviderFactories() {
+ List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
+
+ allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
+ allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
+
+ return allProviders;
+ }
+}
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 51a39f7..3e5c2b0 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
@@ -447,7 +447,7 @@ public class RealmAdminResource {
}
@Path("identity-provider")
- public IdentityProviderResource getIdentityProviderResource() {
- return new IdentityProviderResource(realm, session);
+ public IdentityProvidersResource getIdentityProviderResource() {
+ return new IdentityProvidersResource(realm, session, this.auth);
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
index 641315b..20238f1 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
@@ -13,7 +13,7 @@ public class RealmAuth {
private Resource resource;
public enum Resource {
- APPLICATION, CLIENT, USER, REALM, EVENTS
+ APPLICATION, CLIENT, USER, REALM, EVENTS, IDENTITY_PROVIDER
}
private AdminAuth auth;
@@ -67,6 +67,8 @@ public class RealmAuth {
return AdminRoles.VIEW_REALM;
case EVENTS:
return AdminRoles.VIEW_EVENTS;
+ case IDENTITY_PROVIDER:
+ return AdminRoles.VIEW_IDENTITY_PROVIDERS;
default:
throw new IllegalStateException();
}
@@ -84,6 +86,8 @@ public class RealmAuth {
return AdminRoles.MANAGE_REALM;
case EVENTS:
return AdminRoles.MANAGE_EVENTS;
+ case IDENTITY_PROVIDER:
+ return AdminRoles.MANAGE_IDENTITY_PROVIDERS;
default:
throw new IllegalStateException();
}
diff --git a/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java b/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
index 91b0fb0..5320eee 100644
--- a/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
@@ -204,6 +204,10 @@ public class AuthenticationBrokerResource {
if (identityProviderConfig.isStoreToken()) {
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(authResult.getUser(), providerId, realm);
+ if (identity == null) {
+ return corsResponse(Flows.errors().error("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerId + "].", Response.Status.FORBIDDEN), clientModel);
+ }
+
return corsResponse(identityProvider.retrieveToken(identity), clientModel);
}
@@ -229,17 +233,19 @@ public class AuthenticationBrokerResource {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = realmManager.getRealmByName(realmName);
+ IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(realm, providerId);
+
try {
- IdentityProvider provider = getIdentityProvider(realm, providerId);
+ IdentityProvider identityProvider = getIdentityProvider(realm, providerId);
- if (provider == null) {
- return Flows.forms(session, realm, null, uriInfo).setError("Social provider not found").createErrorPage();
+ if (identityProvider == null) {
+ return Flows.forms(session, realm, null, uriInfo).setError("Social identityProvider not found").createErrorPage();
}
- String relayState = provider.getRelayState(createAuthenticationRequest(providerId, null, realm, null));
+ String relayState = identityProvider.getRelayState(createAuthenticationRequest(providerId, null, realm, null));
if (relayState == null) {
- return redirectToErrorPage(realm, "No relay state from identity provider.");
+ return redirectToErrorPage(realm, "No relay state from identity identityProvider.");
}
ClientSessionCode clientCode = isValidAuthorizationCode(relayState, realm);
@@ -256,7 +262,7 @@ public class AuthenticationBrokerResource {
return response;
}
- AuthenticationResponse authenticationResponse = provider.handleResponse(createAuthenticationRequest(providerId, null, realm, clientSession));
+ AuthenticationResponse authenticationResponse = identityProvider.handleResponse(createAuthenticationRequest(providerId, null, realm, clientSession));
response = authenticationResponse.getResponse();
@@ -266,14 +272,16 @@ public class AuthenticationBrokerResource {
FederatedIdentity identity = authenticationResponse.getUser();
+ if (!identityProviderConfig.isStoreToken()) {
+ identity.setToken(null);
+ }
+
return performLocalAuthentication(realm, providerId, identity, clientCode);
} catch (Exception e) {
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
- IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(realm, providerId);
-
return Flows.forms(session, realm, null, uriInfo).setError("Authentication failed. Could not authenticate against Identity Provider [" + identityProviderConfig.getName() + "].").createErrorPage();
} finally {
if (session.getTransaction().isActive()) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java
index e0d29e9..5d04fa4 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AbstractClientTest.java
@@ -9,6 +9,7 @@ import org.keycloak.models.Constants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
@@ -100,6 +101,8 @@ public abstract class AbstractClientTest {
return ((ApplicationRepresentation) o1).getName();
} else if (o1 instanceof OAuthClientRepresentation) {
return ((OAuthClientRepresentation) o1).getName();
+ } else if (o1 instanceof IdentityProviderRepresentation) {
+ return ((IdentityProviderRepresentation) o1).getId();
}
throw new IllegalArgumentException();
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
new file mode 100644
index 0000000..2d91d9f
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
@@ -0,0 +1,123 @@
+package org.keycloak.testsuite.admin;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.admin.client.resource.IdentityProviderResource;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.testsuite.rule.WebRule;
+
+import javax.ws.rs.NotFoundException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class IdentityProviderTest extends AbstractClientTest {
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ @Test
+ public void testFindAll() {
+ realm.identityProviders().create(create("google", "google", "Google"));
+ realm.identityProviders().create(create("facebook", "facebook", "Facebook"));
+
+ assertNames(realm.identityProviders().findAll(), "google", "facebook");
+ }
+
+ @Test
+ public void testCreate() {
+ IdentityProviderRepresentation newIdentityProvider = create("new-identity-provider", "oidc", "New Identity Provider");
+
+ newIdentityProvider.getConfig().put("clientId", "clientId");
+ newIdentityProvider.getConfig().put("clientSecret", "clientSecret");
+
+ realm.identityProviders().create(newIdentityProvider);
+ IdentityProviderResource identityProviderResource = realm.identityProviders().get("new-identity-provider");
+
+ assertNotNull(identityProviderResource);
+
+ IdentityProviderRepresentation representation = identityProviderResource.toRepresentation();
+
+ assertNotNull(representation);
+
+ assertNotNull(representation.getInternalId());
+ assertEquals("New Identity Provider", representation.getName());
+ assertEquals("new-identity-provider", representation.getId());
+ assertEquals("oidc", representation.getProviderId());
+ assertEquals("clientId", representation.getConfig().get("clientId"));
+ assertEquals("clientSecret", representation.getConfig().get("clientSecret"));
+ assertTrue(representation.isEnabled());
+ assertFalse(representation.isStoreToken());
+ assertTrue(representation.isUpdateProfileFirstLogin());
+ }
+
+ @Test
+ public void testUpdate() {
+ IdentityProviderRepresentation newIdentityProvider = create("update-identity-provider", "oidc", "Update Identity Provider");
+
+ newIdentityProvider.getConfig().put("clientId", "clientId");
+ newIdentityProvider.getConfig().put("clientSecret", "clientSecret");
+
+ realm.identityProviders().create(newIdentityProvider);
+ IdentityProviderResource identityProviderResource = realm.identityProviders().get("update-identity-provider");
+
+ assertNotNull(identityProviderResource);
+
+ IdentityProviderRepresentation representation = identityProviderResource.toRepresentation();
+
+ assertNotNull(representation);
+
+ assertEquals("update-identity-provider", representation.getId());
+
+ representation.setId("changed-alias");
+ representation.setEnabled(false);
+ representation.setStoreToken(true);
+ representation.getConfig().put("clientId", "changedClientId");
+
+ identityProviderResource.update(representation);
+
+ identityProviderResource = realm.identityProviders().get(representation.getInternalId());
+
+ assertNotNull(identityProviderResource);
+
+ representation = identityProviderResource.toRepresentation();
+
+ assertFalse(representation.isEnabled());
+ assertTrue(representation.isStoreToken());
+ assertEquals("changedClientId", representation.getConfig().get("clientId"));
+ }
+
+ @Test(expected = NotFoundException.class)
+ public void testRemove() {
+ IdentityProviderRepresentation newIdentityProvider = create("remove-identity-provider", "saml", "Remove Identity Provider");
+
+ realm.identityProviders().create(newIdentityProvider);
+ IdentityProviderResource identityProviderResource = realm.identityProviders().get("update-identity-provider");
+
+ assertNotNull(identityProviderResource);
+
+ IdentityProviderRepresentation representation = identityProviderResource.toRepresentation();
+
+ assertNotNull(representation);
+
+ identityProviderResource.remove();
+
+ realm.identityProviders().get("update-identity-provider");
+ }
+
+ private IdentityProviderRepresentation create(String id, String providerId, String name) {
+ IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
+
+ identityProviderRepresentation.setId(id);
+ identityProviderRepresentation.setProviderId(providerId);
+ identityProviderRepresentation.setName(name);
+ identityProviderRepresentation.setEnabled(true);
+
+ return identityProviderRepresentation;
+ }
+}