package org.keycloak.testsuite.cli.registration; import org.junit.Assert; import org.junit.Test; import org.keycloak.client.registration.cli.config.FileConfigHandler; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.testsuite.cli.KcRegExec; import org.keycloak.testsuite.util.TempFileResource; import org.keycloak.util.JsonSerialization; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Arrays; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; import static org.keycloak.testsuite.cli.KcRegExec.execute; /** * @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a> */ public class KcRegUpdateTest extends AbstractRegCliTest { @Test public void testUpdateThoroughly() throws IOException { FileConfigHandler handler = initCustomConfigFile(); try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) { final String realm = "test"; loginAsUser(configFile.getFile(), serverUrl, realm, "user1", "userpass"); // create an object so we can update it KcRegExec exe = execute("create --config '" + configFile.getName() + "' -o -s clientId=my_client"); assertExitCodeAndStdErrSize(exe, 0, 0); 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("redirectUris is empty", client.getRedirectUris().isEmpty()); // Merge update exe = execute("update my_client --config '" + configFile.getName() + "' -o " + " -s enabled=false -s 'redirectUris=[\"http://localhost:8980/myapp/*\"]'"); assertExitCodeAndStdErrSize(exe, 0, 0); client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); Assert.assertEquals("enabled", false, client.isEnabled()); Assert.assertEquals("redirectUris", Arrays.asList("http://localhost:8980/myapp/*"), client.getRedirectUris()); // Another merge update - test deleting an attribute, deleting a list item and adding a list item exe = execute("update my_client --config '" + configFile.getName() + "' -o -d redirectUris -s webOrigins+=http://localhost:8980/myapp -s webOrigins+=http://localhost:8981/myapp -d webOrigins[0]"); assertExitCodeAndStdErrSize(exe, 0, 0); client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); Assert.assertTrue("redirectUris is empty", client.getRedirectUris().isEmpty()); Assert.assertEquals("webOrigins", Arrays.asList("http://localhost:8981/myapp"), client.getWebOrigins()); // Another merge update - test nested attributes and setting an attribute using json format // TODO KEYCLOAK-3705 Updating protocolMapper config via client registration endpoint has no effect /* exe = execute("update my_client --config '" + configFile.getName() + "' -o -s 'protocolMappers[0].config.\"id.token.claim\"=false' " + "-s 'protocolMappers[4].config={\"single\": \"true\", \"attribute.nameformat\": \"Basic\", \"attribute.name\": \"Role\"}'"); assertExitCodeAndStdErrSize(exe, 0, 0); client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); Assert.assertEquals("protocolMapper[0].config.\"id.token.claim\"", "false", client.getProtocolMappers().get(0).getConfig().get("id.token.claim")); Assert.assertEquals("protocolMappers[4].config.single", "true", client.getProtocolMappers().get(4).getConfig().get("single")); Assert.assertEquals("protocolMappers[4].config.\"attribute.nameformat\"", "Basic", client.getProtocolMappers().get(4).getConfig().get("attribute.nameformat")); Assert.assertEquals("protocolMappers[4].config.\"attribute.name\"", "Role", client.getProtocolMappers().get(4).getConfig().get("attribute.name")); */ // update using oidc format // check that using an invalid attribute key is not ignored exe = execute("update my_client --nonexisting --config '" + configFile.getName() + "'"); assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("error message", "Unsupported option: --nonexisting", exe.stderrLines().get(0)); Assert.assertEquals("try help", "Try '" + CMD + " help update' for more information", exe.stderrLines().get(1)); // try use incompatible endpoint exe = execute("update my_client --config '" + configFile.getName() + "' -o -s enabled=true -e oidc"); assertExitCodeAndStreamSizes(exe, 1, 0, 1); Assert.assertEquals("error message", "Failed to set attribute 'enabled' on document type 'oidc'", exe.stderrLines().get(0)); // test overwrite from file exe = KcRegExec.newBuilder() .argsLine("update my_client --config '" + configFile.getName() + "' -o -s clientId=my_client -s 'redirectUris=[\"http://localhost:8980/myapp/*\"]' -f -") .stdin(new ByteArrayInputStream("{ \"enabled\": false }".getBytes())) .execute(); assertExitCodeAndStdErrSize(exe, 0, 0); client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); // web origin is not sent to the server, thus it retains the current value Assert.assertEquals("webOrigins", Arrays.asList("http://localhost:8981/myapp"), client.getWebOrigins()); Assert.assertFalse("enabled is false", client.isEnabled()); Assert.assertEquals("redirectUris", Arrays.asList("http://localhost:8980/myapp/*"), client.getRedirectUris()); // test using merge with file exe = KcRegExec.newBuilder() .argsLine("update my_client --config '" + configFile.getName() + "' -o -s enabled=true -m -f -") .stdin(new ByteArrayInputStream("{ \"webOrigins\": [\"http://localhost:8980/myapp\"] }".getBytes())) .execute(); assertExitCodeAndStdErrSize(exe, 0, 0); client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); Assert.assertEquals("webOrigins", Arrays.asList("http://localhost:8980/myapp"), client.getWebOrigins()); Assert.assertTrue("enabled is true", client.isEnabled()); Assert.assertEquals("redirectUris", Arrays.asList("http://localhost:8980/myapp/*"), client.getRedirectUris()); // remove registration access token exe = execute("config registration-token --config '" + configFile.getName() + "' --server " + serverUrl + " --realm " + realm + " --client my_client -d"); assertExitCodeAndStdErrSize(exe, 0, 0); Assert.assertNull("my_client registration token", handler.loadConfig().ensureRealmConfigData(serverUrl, realm).getClients().get("my_client")); } } }