keycloak-aplcache

KEYCLOAK-9167 Using kcadm to update an identity-provider

2/26/2019 9:52:22 AM

Details

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 6a01713..7d133c2 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
@@ -172,6 +172,10 @@ public class IdentityProviderResource {
         String newProviderId = providerRep.getAlias();
         String oldProviderId = getProviderIdByInternalId(realm, internalId);
 
+        if (oldProviderId == null) {
+            lookUpProviderIdByAlias(realm, providerRep);
+        }
+
         IdentityProviderModel updated = RepresentationToModel.toModel(realm, providerRep);
 
         if (updated.getConfig() != null && ComponentRepresentation.SECRET_VALUE.equals(updated.getConfig().get("clientSecret"))) {
@@ -201,6 +205,18 @@ public class IdentityProviderResource {
         return null;
     }
 
+    // sets internalId to IdentityProvider based on alias
+    private static void lookUpProviderIdByAlias(RealmModel realm, IdentityProviderRepresentation providerRep) {
+        List<IdentityProviderModel> providerModels = realm.getIdentityProviders();
+        for (IdentityProviderModel providerModel : providerModels) {
+            if (providerModel.getAlias().equals(providerRep.getAlias())) {
+                providerRep.setInternalId(providerModel.getInternalId());
+                return;
+            }
+        }
+        throw new javax.ws.rs.NotFoundException();
+    }
+
     private static void updateUsersAfterProviderAliasChange(List<UserModel> users, String oldProviderId, String newProviderId, RealmModel realm, KeycloakSession session) {
         for (UserModel user : users) {
             FederatedIdentityModel federatedIdentity = session.users().getFederatedIdentity(user, oldProviderId, realm);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmUpdateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmUpdateTest.java
index 6e75f59..d88e694 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmUpdateTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmUpdateTest.java
@@ -9,11 +9,21 @@ import org.keycloak.testsuite.util.TempFileResource;
 import org.keycloak.util.JsonSerialization;
 
 import java.io.ByteArrayInputStream;
+import java.io.Closeable;
+import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.broker.saml.SAMLIdentityProviderConfig;
+import org.keycloak.broker.saml.SAMLIdentityProviderFactory;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
 
 import static org.keycloak.testsuite.cli.KcAdmExec.CMD;
 import static org.keycloak.testsuite.cli.KcAdmExec.execute;
+import org.keycloak.testsuite.updaters.IdentityProviderCreator;
+import org.keycloak.testsuite.util.IdentityProviderBuilder;
 
 /**
  * @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
@@ -21,6 +31,41 @@ import static org.keycloak.testsuite.cli.KcAdmExec.execute;
 public class KcAdmUpdateTest extends AbstractAdmCliTest {
 
     @Test
+    public void testUpdateIDPWithoutInternalId() throws IOException {
+        
+        final String realm = "test";
+        final RealmResource realmResource = adminClient.realm(realm);
+        
+        IdentityProviderRepresentation identityProvider = IdentityProviderBuilder.create()
+                .providerId(SAMLIdentityProviderFactory.PROVIDER_ID)
+                .alias("idpAlias")
+                .displayName("SAML")
+                .setAttribute(SAMLIdentityProviderConfig.SINGLE_SIGN_ON_SERVICE_URL, "http://saml.idp/saml")
+                .setAttribute(SAMLIdentityProviderConfig.SINGLE_LOGOUT_SERVICE_URL, "http://saml.idp/saml")
+                .setAttribute(SAMLIdentityProviderConfig.NAME_ID_POLICY_FORMAT, "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")
+                .setAttribute(SAMLIdentityProviderConfig.POST_BINDING_RESPONSE, "false")
+                .setAttribute(SAMLIdentityProviderConfig.POST_BINDING_AUTHN_REQUEST, "false")
+                .setAttribute(SAMLIdentityProviderConfig.BACKCHANNEL_SUPPORTED, "false")
+                .build();
+        
+        try (Closeable ipc = new IdentityProviderCreator(realmResource, identityProvider)) {
+            FileConfigHandler handler = initCustomConfigFile();
+            try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) {
+                loginAsUser(configFile.getFile(), serverUrl, realm, "user1", "userpass");
+
+                KcAdmExec exe = execute("get identity-provider/instances/idpAlias -r " + realm + " --config " + configFile.getFile());
+                assertExitCodeAndStdErrSize(exe, 0, 0);
+
+                final File idpJson = new File("target/test-classes/cli/idp-keycloak-9167.json");
+                exe = execute("update identity-provider/instances/idpAlias -r " + realm + " -f " + idpJson.getAbsolutePath() + " --config " + configFile.getFile());
+                assertExitCodeAndStdErrSize(exe, 0, 0);
+            }
+
+            Assert.assertThat(realmResource.identityProviders().get("idpAlias").toRepresentation().getDisplayName(), is(equalTo("SAML_UPDATED")));
+        }
+    }
+
+    @Test
     public void testUpdateThoroughly() throws IOException {
 
         FileConfigHandler handler = initCustomConfigFile();
@@ -39,9 +84,9 @@ public class KcAdmUpdateTest extends AbstractAdmCliTest {
 
             ClientRepresentation client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
 
-            Assert.assertEquals("enabled", true, client.isEnabled());
-            Assert.assertEquals("publicClient", false, client.isPublicClient());
-            Assert.assertEquals("bearerOnly", false, client.isBearerOnly());
+            Assert.assertTrue("enabled", client.isEnabled());
+            Assert.assertFalse("publicClient", client.isPublicClient());
+            Assert.assertFalse("bearerOnly", client.isBearerOnly());
             Assert.assertTrue("redirectUris is empty", client.getRedirectUris().isEmpty());
 
 
@@ -52,7 +97,7 @@ public class KcAdmUpdateTest extends AbstractAdmCliTest {
             assertExitCodeAndStdErrSize(exe, 0, 0);
 
             client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
-            Assert.assertEquals("enabled", false, client.isEnabled());
+            Assert.assertFalse("enabled", client.isEnabled());
             Assert.assertEquals("redirectUris", Arrays.asList("http://localhost:8980/myapp/*"), client.getRedirectUris());
 
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/cli/idp-keycloak-9167.json b/testsuite/integration-arquillian/tests/base/src/test/resources/cli/idp-keycloak-9167.json
new file mode 100644
index 0000000..58fd177
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/cli/idp-keycloak-9167.json
@@ -0,0 +1,21 @@
+{
+  "alias" : "idpAlias",
+  "displayName" : "SAML_UPDATED",
+  "providerId" : "saml",
+  "enabled" : true,
+  "updateProfileFirstLoginMode" : "on",
+  "trustEmail" : false,
+  "storeToken" : false,
+  "addReadTokenRoleOnCreate" : false,
+  "authenticateByDefault" : false,
+  "linkOnly" : false,
+  "firstBrokerLoginFlowAlias" : "first broker login",
+  "config" : {
+    "nameIDPolicyFormat" : "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
+    "postBindingResponse" : "false",
+    "singleLogoutServiceUrl" : "http://saml.idp/saml",
+    "postBindingAuthnRequest" : "false",
+    "singleSignOnServiceUrl" : "http://saml.idp/saml",
+    "backchannelSupported" : "false"
+  }
+}