KEYCLOAK-11410 Do not throw exception in PlaintextVaultProvider if unconfigured

This commit is contained in:
mhajas 2019-09-13 15:58:38 +02:00 committed by Hynek Mlnařík
parent b71198af9f
commit 37b7b595a5
10 changed files with 189 additions and 70 deletions

View file

@ -22,14 +22,13 @@ public class PlainTextVaultProviderFactory implements VaultProviderFactory {
public static final String PROVIDER_ID = "plaintext"; public static final String PROVIDER_ID = "plaintext";
private String vaultDirectory; private String vaultDirectory;
private boolean disabled;
private Path vaultPath; private Path vaultPath;
@Override @Override
public VaultProvider create(KeycloakSession session) { public VaultProvider create(KeycloakSession session) {
if (disabled || vaultDirectory == null) { if (vaultDirectory == null) {
//init method not called? logger.debug("Can not create a vault since it's disabled or not initialized correctly");
throw new IllegalStateException("Can not create a vault since it's disabled or not initialized correctly"); return null;
} }
return new PlainTextVaultProvider(vaultPath, session.getContext().getRealm().getName()); return new PlainTextVaultProvider(vaultPath, session.getContext().getRealm().getName());
} }
@ -37,19 +36,6 @@ public class PlainTextVaultProviderFactory implements VaultProviderFactory {
@Override @Override
public void init(Config.Scope config) { public void init(Config.Scope config) {
vaultDirectory = config.get("dir"); vaultDirectory = config.get("dir");
Boolean disabledFromConfig = config.getBoolean("disabled");
if (disabledFromConfig == null) {
disabled = false;
} else {
disabled = disabledFromConfig.booleanValue();
}
if (disabled) {
logger.debug("PlainTextVaultProviderFactory disabled");
return;
}
if (vaultDirectory == null) { if (vaultDirectory == null) {
logger.debug("PlainTextVaultProviderFactory not configured"); logger.debug("PlainTextVaultProviderFactory not configured");
return; return;

View file

@ -29,6 +29,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/** /**
* Tests for {@link PlainTextVaultProviderFactory}. * Tests for {@link PlainTextVaultProviderFactory}.
@ -43,7 +44,7 @@ public class PlainTextVaultProviderFactoryTest {
@Test @Test
public void shouldInitializeVaultCorrectly() { public void shouldInitializeVaultCorrectly() {
//given //given
VaultConfig config = new VaultConfig(Scenario.EXISTING.getAbsolutePathAsString(), Boolean.FALSE); VaultConfig config = new VaultConfig(Scenario.EXISTING.getAbsolutePathAsString());
PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory(); PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory();
KeycloakSession session = new DefaultKeycloakSession(new DefaultKeycloakSessionFactory()); KeycloakSession session = new DefaultKeycloakSession(new DefaultKeycloakSessionFactory());
@ -57,42 +58,10 @@ public class PlainTextVaultProviderFactoryTest {
assertNotNull(provider); assertNotNull(provider);
} }
@Test
public void shouldInitializeCorrectlyWithNullDisabledFlag() {
//given
VaultConfig config = new VaultConfig(Scenario.EXISTING.getAbsolutePathAsString(), null);
PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory();
KeycloakSession session = new DefaultKeycloakSession(new DefaultKeycloakSessionFactory());
session.getContext().setRealm(new VaultRealmModel());
//when
factory.init(config);
VaultProvider provider = factory.create(session);
//then
assertNotNull(provider);
}
@Test
public void shouldThrowAnExceptionWhenTryingToCreateProviderOnDisabledFactory() {
//given
VaultConfig config = new VaultConfig(Scenario.EXISTING.getAbsolutePathAsString(), Boolean.TRUE);
PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory();
expectedException.expect(IllegalStateException.class);
//when
factory.init(config);
factory.create(null);
//then - verified by the ExpectedException rule
}
@Test @Test
public void shouldThrowAnExceptionWhenUsingNonExistingDirectory() { public void shouldThrowAnExceptionWhenUsingNonExistingDirectory() {
//given //given
VaultConfig config = new VaultConfig(Scenario.NON_EXISTING.getAbsolutePathAsString(), Boolean.FALSE); VaultConfig config = new VaultConfig(Scenario.NON_EXISTING.getAbsolutePathAsString());
PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory(); PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory();
expectedException.expect(VaultNotFoundException.class); expectedException.expect(VaultNotFoundException.class);
@ -104,18 +73,17 @@ public class PlainTextVaultProviderFactoryTest {
} }
@Test @Test
public void shouldThrowAnExceptionWhenWithNullDirectory() { public void shouldReturnNullWhenWithNullDirectory() {
//given //given
VaultConfig config = new VaultConfig(null, Boolean.FALSE); VaultConfig config = new VaultConfig(null);
PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory(); PlainTextVaultProviderFactory factory = new PlainTextVaultProviderFactory();
expectedException.expect(IllegalStateException.class);
//when //when
factory.init(config); factory.init(config);
factory.create(null); VaultProvider provider = factory.create(null);
//then - verified by the ExpectedException rule //then
assertNull(provider);
} }
/** /**
@ -1271,11 +1239,9 @@ public class PlainTextVaultProviderFactoryTest {
private static class VaultConfig implements Config.Scope { private static class VaultConfig implements Config.Scope {
private String vaultDirectory; private String vaultDirectory;
private Boolean disabled;
public VaultConfig(String vaultDirectory, Boolean disabled) { public VaultConfig(String vaultDirectory) {
this.vaultDirectory = vaultDirectory; this.vaultDirectory = vaultDirectory;
this.disabled = disabled;
} }
@Override @Override
@ -1315,7 +1281,7 @@ public class PlainTextVaultProviderFactoryTest {
@Override @Override
public Boolean getBoolean(String key) { public Boolean getBoolean(String key) {
return disabled; throw new UnsupportedOperationException("not implemented");
} }
@Override @Override

View file

@ -12,10 +12,6 @@ echo ** Adding login-protocol spi **
/subsystem=keycloak-server/spi=login-protocol/:add /subsystem=keycloak-server/spi=login-protocol/:add
/subsystem=keycloak-server/spi=login-protocol/provider=saml/:add(enabled=true,properties={knownProtocols => "[\"http=${auth.server.http.port}\",\"https=${auth.server.https.port}\"]"}) /subsystem=keycloak-server/spi=login-protocol/provider=saml/:add(enabled=true,properties={knownProtocols => "[\"http=${auth.server.http.port}\",\"https=${auth.server.https.port}\"]"})
echo ** Adding vault spi **
/subsystem=keycloak-server/spi=vault/:add
/subsystem=keycloak-server/spi=vault/provider=plaintext/:add(enabled=true,properties={dir => "${jboss.home.dir}/standalone/configuration/vault"})
echo ** Adding theme modules ** echo ** Adding theme modules **
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=modules,value=[org.keycloak.testsuite.integration-arquillian-testsuite-providers]) /subsystem=keycloak-server/theme=defaults/:write-attribute(name=modules,value=[org.keycloak.testsuite.integration-arquillian-testsuite-providers])

View file

@ -0,0 +1,55 @@
package org.keycloak.testsuite.util;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.SuiteContext;
import org.wildfly.extras.creaper.core.online.CliException;
import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
import org.wildfly.extras.creaper.core.online.operations.admin.Administration;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author mhajas
*/
public class VaultUtils {
public static void enableVault(SuiteContext suiteContext, ContainerController controller) throws IOException, CliException, TimeoutException, InterruptedException {
if (suiteContext.getAuthServerInfo().isUndertow()) {
controller.stop(suiteContext.getAuthServerInfo().getQualifier());
System.setProperty("keycloak.vault.plaintext.provider.enabled", "true");
controller.start(suiteContext.getAuthServerInfo().getQualifier());
} else {
OnlineManagementClient client = AuthServerTestEnricher.getManagementClient();
Administration administration = new Administration(client);
client.execute("/subsystem=keycloak-server/spi=vault/:add");
client.execute("/subsystem=keycloak-server/spi=vault/provider=plaintext/:add(enabled=true,properties={dir => \"${jboss.home.dir}/standalone/configuration/vault\"})");
administration.reload();
client.close();
}
}
public static void disableVault(SuiteContext suiteContext, ContainerController controller) throws IOException, CliException, TimeoutException, InterruptedException {
if (suiteContext.getAuthServerInfo().isUndertow()) {
controller.stop(suiteContext.getAuthServerInfo().getQualifier());
System.setProperty("keycloak.vault.plaintext.provider.enabled", "false");
controller.start(suiteContext.getAuthServerInfo().getQualifier());
} else {
OnlineManagementClient client = AuthServerTestEnricher.getManagementClient();
Administration administration = new Administration(client);
client.execute("/subsystem=keycloak-server/spi=vault/:remove");
administration.reload();
client.close();
}
}
}

View file

@ -1,11 +1,36 @@
package org.keycloak.testsuite.admin; package org.keycloak.testsuite.admin;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.After;
import org.junit.Before;
import org.keycloak.testsuite.util.VaultUtils;
/** /**
* @author Martin Kanis <mkanis@redhat.com> * @author Martin Kanis <mkanis@redhat.com>
*/ */
public class SMTPConnectionVaultTest extends SMTPConnectionTest { public class SMTPConnectionVaultTest extends SMTPConnectionTest {
public final String SMTP_PASSWORD = setSmtpPassword(); @ArquillianResource
protected ContainerController controller;
@Before
public void beforeSMTPConnectionVaultTest() throws Exception {
VaultUtils.enableVault(suiteContext, controller);
reconnectAdminClient();
super.before();
}
@Override
public void before() {
}
@After
public void afterLDAPVaultTest() throws Exception {
VaultUtils.disableVault(suiteContext, controller);
reconnectAdminClient();
}
@Override @Override
public String setSmtpPassword() { public String setSmtpPassword() {

View file

@ -17,11 +17,16 @@
package org.keycloak.testsuite.admin; package org.keycloak.testsuite.admin;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.services.managers.LDAPConnectionTestManager; import org.keycloak.services.managers.LDAPConnectionTestManager;
import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.util.LDAPRule; import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.VaultUtils;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
@ -33,6 +38,26 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest {
@ClassRule @ClassRule
public static LDAPRule ldapRule = new LDAPRule(); public static LDAPRule ldapRule = new LDAPRule();
@ArquillianResource
protected ContainerController controller;
@Before
public void beforeUserFederationLdapConnectionTest() throws Exception {
VaultUtils.enableVault(suiteContext, controller);
reconnectAdminClient();
super.setRealm();
}
@Override
public void setRealm() {}
@After
public void afterLDAPVaultTest() throws Exception {
VaultUtils.disableVault(suiteContext, controller);
reconnectAdminClient();
}
@Test @Test
public void testLdapConnections1() { public void testLdapConnections1() {
// Unknown action // Unknown action

View file

@ -1,10 +1,35 @@
package org.keycloak.testsuite.broker; package org.keycloak.testsuite.broker;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.After;
import org.junit.Before;
import org.keycloak.testsuite.util.VaultUtils;
/** /**
* @author Martin Kanis <mkanis@redhat.com> * @author Martin Kanis <mkanis@redhat.com>
*/ */
public class KcOidcBrokerVaultTest extends KcOidcBrokerTest { public class KcOidcBrokerVaultTest extends KcOidcBrokerTest {
@ArquillianResource
protected ContainerController controller;
@Before
public void beforeKcOidcBrokerVaultTest() throws Exception {
VaultUtils.enableVault(suiteContext, controller);
reconnectAdminClient();
super.beforeBrokerTest();
}
@Override
public void beforeBrokerTest() {}
@After
public void afterLDAPVaultTest() throws Exception {
VaultUtils.disableVault(suiteContext, controller);
reconnectAdminClient();
}
@Override @Override
protected BrokerConfiguration getBrokerConfiguration() { protected BrokerConfiguration getBrokerConfiguration() {
return KcOidcBrokerVaultConfiguration.INSTANCE; return KcOidcBrokerVaultConfiguration.INSTANCE;

View file

@ -1,9 +1,13 @@
package org.keycloak.testsuite.federation.ldap; package org.keycloak.testsuite.federation.ldap;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.keycloak.models.LDAPConstants;
import org.keycloak.testsuite.util.LDAPRule; import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestConfiguration; import org.keycloak.testsuite.util.LDAPTestConfiguration;
import org.keycloak.testsuite.util.VaultUtils;
import java.util.Map; import java.util.Map;
@ -16,6 +20,25 @@ public class LDAPVaultCredentialsTest extends LDAPSyncTest {
private static final String VAULT_EXPRESSION = "${vault.ldap_bindCredential}"; private static final String VAULT_EXPRESSION = "${vault.ldap_bindCredential}";
@ArquillianResource
protected ContainerController controller;
@Override
@Before
public void beforeAbstractKeycloakTest() throws Exception {
VaultUtils.enableVault(suiteContext, controller);
reconnectAdminClient();
super.beforeAbstractKeycloakTest();
}
@After
public void afterLDAPVaultTest() throws Exception {
VaultUtils.disableVault(suiteContext, controller);
reconnectAdminClient();
}
@ClassRule @ClassRule
public static LDAPRule ldapRule = new LDAPRule() { public static LDAPRule ldapRule = new LDAPRule() {
@Override @Override

View file

@ -17,19 +17,23 @@
package org.keycloak.testsuite.vault; package org.keycloak.testsuite.vault;
import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.runonserver.RunOnServer; import org.keycloak.testsuite.runonserver.RunOnServer;
import org.keycloak.testsuite.runonserver.RunOnServerDeployment; import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
import org.keycloak.testsuite.util.VaultUtils;
import org.keycloak.testsuite.utils.io.IOUtil; import org.keycloak.testsuite.utils.io.IOUtil;
import org.keycloak.vault.VaultStringSecret; import org.keycloak.vault.VaultStringSecret;
import org.keycloak.vault.VaultTranscriber; import org.keycloak.vault.VaultTranscriber;
@ -52,6 +56,21 @@ public class KeycloakVaultTest extends AbstractKeycloakTest {
testRealms.add(IOUtil.loadRealm("/testrealm.json")); testRealms.add(IOUtil.loadRealm("/testrealm.json"));
} }
@ArquillianResource
protected ContainerController controller;
@Before
public void beforeKeycloakVaultTest() throws Exception {
VaultUtils.enableVault(suiteContext, controller);
reconnectAdminClient();
}
@After
public void afterLDAPVaultTest() throws Exception {
VaultUtils.disableVault(suiteContext, controller);
reconnectAdminClient();
}
@Test @Test
public void testKeycloakVault() throws Exception { public void testKeycloakVault() throws Exception {
// run the test in two different realms to test the provider's ability to retrieve secrets with the same key in different realms. // run the test in two different realms to test the provider's ability to retrieve secrets with the same key in different realms.

View file

@ -187,10 +187,9 @@
}, },
"vault": { "vault": {
"provider": "${keycloak.vault.provider:plaintext}",
"plaintext": { "plaintext": {
"dir": "target/dependency/vault", "dir": "target/dependency/vault",
"disabled": false "enabled": "${keycloak.vault.plaintext.provider.enabled:false}"
} }
} }
} }