Merge pull request elastic/elasticsearch#2772 from rjernst/remove_secret_service

Internal: Remove SecretService

Original commit: elastic/x-pack-elasticsearch@65981535dc
This commit is contained in:
Ryan Ernst 2016-07-11 09:06:33 -07:00 committed by GitHub
commit 5ea799cf51
25 changed files with 95 additions and 237 deletions

View File

@ -41,7 +41,6 @@ import org.elasticsearch.xpack.action.XPackInfoAction;
import org.elasticsearch.xpack.action.XPackUsageAction;
import org.elasticsearch.xpack.common.ScriptServiceProxy;
import org.elasticsearch.xpack.common.http.HttpClientModule;
import org.elasticsearch.xpack.common.secret.SecretModule;
import org.elasticsearch.xpack.common.text.TextTemplateModule;
import org.elasticsearch.xpack.extensions.XPackExtension;
import org.elasticsearch.xpack.extensions.XPackExtensionsService;
@ -145,7 +144,6 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin {
if (transportClientMode == false) {
modules.add(new HttpClientModule());
modules.add(new SecretModule(settings));
modules.add(new TextTemplateModule());
}
return modules;

View File

@ -5,20 +5,20 @@
*/
package org.elasticsearch.xpack.common.http.auth.basic;
import org.elasticsearch.xpack.common.http.auth.ApplicableHttpAuth;
import org.elasticsearch.xpack.common.secret.SecretService;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.elasticsearch.xpack.common.http.auth.ApplicableHttpAuth;
import org.elasticsearch.xpack.security.crypto.CryptoService;
/**
*/
public class ApplicableBasicAuth extends ApplicableHttpAuth<BasicAuth> {
private final String basicAuth;
public ApplicableBasicAuth(BasicAuth auth, SecretService service) {
public ApplicableBasicAuth(BasicAuth auth, CryptoService service) {
super(auth);
basicAuth = headerValue(auth.username, auth.password.text(service));
}

View File

@ -5,10 +5,11 @@
*/
package org.elasticsearch.xpack.common.http.auth.basic;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.xpack.common.http.auth.HttpAuthFactory;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import java.io.IOException;
@ -17,11 +18,11 @@ import java.io.IOException;
*/
public class BasicAuthFactory extends HttpAuthFactory<BasicAuth, ApplicableBasicAuth> {
private final SecretService secretService;
private final CryptoService cryptoService;
@Inject
public BasicAuthFactory(SecretService secretService) {
this.secretService = secretService;
public BasicAuthFactory(@Nullable CryptoService cryptoService) {
this.cryptoService = cryptoService;
}
public String type() {
@ -34,6 +35,6 @@ public class BasicAuthFactory extends HttpAuthFactory<BasicAuth, ApplicableBasic
@Override
public ApplicableBasicAuth createApplicable(BasicAuth auth) {
return new ApplicableBasicAuth(auth, secretService);
return new ApplicableBasicAuth(auth, cryptoService);
}
}

View File

@ -5,12 +5,13 @@
*/
package org.elasticsearch.xpack.common.secret;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Arrays;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.xpack.security.crypto.CryptoService;
/**
*
*/
@ -22,7 +23,10 @@ public class Secret implements ToXContent {
this.text = text;
}
public char[] text(SecretService service) {
public char[] text(CryptoService service) {
if (service == null) {
return text;
}
return service.decrypt(text);
}

View File

@ -1,32 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.common.secret;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.security.Security;
/**
*
*/
public class SecretModule extends AbstractModule {
private final boolean securityEnabled;
public SecretModule(Settings settings) {
securityEnabled = Security.enabled(settings);
}
@Override
protected void configure() {
if (securityEnabled) {
bind(SecretService.Secure.class).asEagerSingleton();
bind(SecretService.class).to(SecretService.Secure.class);
} else {
bind(SecretService.class).toInstance(SecretService.Insecure.INSTANCE);
}
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.common.secret;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.security.crypto.CryptoService;
/**
*
*/
public interface SecretService {
char[] encrypt(char[] text);
char[] decrypt(char[] text);
class Insecure implements SecretService {
public static final Insecure INSTANCE = new Insecure();
Insecure() {
}
@Override
public char[] encrypt(char[] text) {
return text;
}
@Override
public char[] decrypt(char[] text) {
return text;
}
}
/**
*
*/
class Secure extends AbstractComponent implements SecretService {
private final CryptoService cryptoService;
@Inject
public Secure(Settings settings, CryptoService cryptoService) {
super(settings);
this.cryptoService = cryptoService;
}
@Override
public char[] encrypt(char[] text) {
return cryptoService.encrypt(text);
}
@Override
public char[] decrypt(char[] text) {
return cryptoService.decrypt(text);
}
}
}

View File

@ -5,13 +5,6 @@
*/
package org.elasticsearch.xpack.notification.email;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.xpack.common.secret.SecretService;
import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.MessagingException;
@ -24,6 +17,13 @@ import java.security.PrivilegedAction;
import java.util.Map;
import java.util.Properties;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.xpack.security.crypto.CryptoService;
/**
*
*/
@ -62,13 +62,13 @@ public class Account {
.build();
private final Config config;
private final SecretService secretService;
private final CryptoService cryptoService;
private final ESLogger logger;
private final Session session;
Account(Config config, SecretService secretService, ESLogger logger) {
Account(Config config, CryptoService cryptoService, ESLogger logger) {
this.config = config;
this.secretService = secretService;
this.cryptoService = cryptoService;
this.logger = logger;
session = config.createSession();
}
@ -102,7 +102,7 @@ public class Account {
String password = null;
if (auth != null && auth.password() != null) {
password = new String(auth.password().text(secretService));
password = new String(auth.password().text(cryptoService));
} else if (config.smtp.password != null) {
password = new String(config.smtp.password);
}

View File

@ -5,13 +5,13 @@
*/
package org.elasticsearch.xpack.notification.email;
import java.util.HashMap;
import java.util.Map;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.xpack.common.secret.SecretService;
import java.util.HashMap;
import java.util.Map;
import org.elasticsearch.xpack.security.crypto.CryptoService;
/**
*
@ -21,12 +21,12 @@ public class Accounts {
private final String defaultAccountName;
private final Map<String, Account> accounts;
public Accounts(Settings settings, SecretService secretService, ESLogger logger) {
public Accounts(Settings settings, CryptoService cryptoService, ESLogger logger) {
Settings accountsSettings = settings.getAsSettings("account");
accounts = new HashMap<>();
for (String name : accountsSettings.names()) {
Account.Config config = new Account.Config(name, accountsSettings.getAsSettings(name));
Account account = new Account(config, secretService, logger);
Account account = new Account(config, cryptoService, logger);
accounts.put(name, account);
}

View File

@ -5,32 +5,33 @@
*/
package org.elasticsearch.xpack.notification.email;
import javax.mail.MessagingException;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.common.secret.SecretService;
import javax.mail.MessagingException;
import org.elasticsearch.xpack.security.crypto.CryptoService;
/**
*
*/
public class InternalEmailService extends AbstractLifecycleComponent implements EmailService {
private final SecretService secretService;
private final CryptoService cryptoService;
public static final Setting<Settings> EMAIL_ACCOUNT_SETTING =
Setting.groupSetting("xpack.notification.email.", Setting.Property.Dynamic, Setting.Property.NodeScope);
private volatile Accounts accounts;
@Inject
public InternalEmailService(Settings settings, SecretService secretService, ClusterSettings clusterSettings) {
public InternalEmailService(Settings settings, @Nullable CryptoService cryptoService, ClusterSettings clusterSettings) {
super(settings);
this.secretService = secretService;
this.cryptoService = cryptoService;
clusterSettings.addSettingsUpdateConsumer(EMAIL_ACCOUNT_SETTING, this::setEmailAccountSettings);
setEmailAccountSettings(EMAIL_ACCOUNT_SETTING.get(settings));
}
@ -78,7 +79,7 @@ public class InternalEmailService extends AbstractLifecycleComponent implements
}
protected Accounts createAccounts(Settings settings, ESLogger logger) {
return new Accounts(settings, secretService, logger);
return new Accounts(settings, cryptoService, logger);
}
}

View File

@ -19,7 +19,6 @@ import org.elasticsearch.test.junit.annotations.Network;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.junit.After;
import org.junit.Before;
@ -49,15 +48,13 @@ public class HttpClientTests extends ESTestCase {
private MockWebServer webServer;
private HttpClient httpClient;
private HttpAuthRegistry authRegistry;
private SecretService secretService;
private Environment environment = new Environment(Settings.builder().put("path.home", createTempDir()).build());
private int webPort;
@Before
public void init() throws Exception {
secretService = SecretService.Insecure.INSTANCE;
authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(secretService)));
authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(null)));
webServer = startWebServer();
webPort = webServer.getPort();
httpClient = new HttpClient(Settings.EMPTY, authRegistry, environment);

View File

@ -16,7 +16,6 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.common.text.TextTemplate;
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
import org.jboss.netty.handler.codec.http.HttpHeaders;
@ -139,7 +138,7 @@ public class HttpRequestTemplateTests extends ESTestCase {
HttpRequestTemplate template = builder.build();
HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE,
new BasicAuthFactory(SecretService.Insecure.INSTANCE)));
new BasicAuthFactory(null)));
HttpRequestTemplate.Parser parser = new HttpRequestTemplate.Parser(registry);
XContentBuilder xContentBuilder = template.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS);

View File

@ -11,7 +11,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.notification.email.support.EmailServer;
import org.elasticsearch.xpack.common.secret.Secret;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.junit.After;
import org.junit.Before;
@ -169,7 +168,7 @@ public class AccountTests extends ESTestCase {
.put("smtp.port", server.port())
.put("smtp.user", USERNAME)
.put("smtp.password", PASSWORD)
.build()), SecretService.Insecure.INSTANCE, logger);
.build()), null, logger);
Email email = Email.builder()
.id("_id")
@ -206,7 +205,7 @@ public class AccountTests extends ESTestCase {
.put("smtp.port", server.port())
.put("smtp.user", USERNAME)
.put("smtp.password", PASSWORD)
.build()), SecretService.Insecure.INSTANCE, logger);
.build()), null, logger);
Email email = Email.builder()
.id("_id")
@ -246,7 +245,7 @@ public class AccountTests extends ESTestCase {
Account account = new Account(new Account.Config("default", Settings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", server.port())
.build()), SecretService.Insecure.INSTANCE, logger);
.build()), null, logger);
Email email = Email.builder()
.id("_id")
@ -277,7 +276,7 @@ public class AccountTests extends ESTestCase {
Account account = new Account(new Account.Config("default", Settings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", server.port())
.build()), SecretService.Insecure.INSTANCE, logger);
.build()), null, logger);
Properties mailProperties = account.getConfig().smtp.properties;
assertThat(mailProperties.get("mail.smtp.connectiontimeout"), is(String.valueOf(TimeValue.timeValueMinutes(2).millis())));
@ -292,7 +291,7 @@ public class AccountTests extends ESTestCase {
.put("smtp.connection_timeout", TimeValue.timeValueMinutes(4))
.put("smtp.write_timeout", TimeValue.timeValueMinutes(6))
.put("smtp.timeout", TimeValue.timeValueMinutes(8))
.build()), SecretService.Insecure.INSTANCE, logger);
.build()), null, logger);
Properties mailProperties = account.getConfig().smtp.properties;
@ -307,7 +306,7 @@ public class AccountTests extends ESTestCase {
.put("smtp.host", "localhost")
.put("smtp.port", server.port())
.put("smtp.connection_timeout", 4000)
.build()), SecretService.Insecure.INSTANCE, logger);
.build()), null, logger);
});
}
}

View File

@ -8,7 +8,6 @@ package org.elasticsearch.xpack.notification.email;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.common.secret.SecretService;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@ -24,7 +23,7 @@ public class AccountsTests extends ESTestCase {
.put("default_account", "account1");
addAccountSettings("account1", builder);
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
Accounts accounts = new Accounts(builder.build(), null, logger);
Account account = accounts.account("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -37,7 +36,7 @@ public class AccountsTests extends ESTestCase {
Settings.Builder builder = Settings.builder();
addAccountSettings("account1", builder);
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
Accounts accounts = new Accounts(builder.build(), null, logger);
Account account = accounts.account("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -52,7 +51,7 @@ public class AccountsTests extends ESTestCase {
addAccountSettings("account1", builder);
addAccountSettings("account2", builder);
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
Accounts accounts = new Accounts(builder.build(), null, logger);
Account account = accounts.account("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -70,7 +69,7 @@ public class AccountsTests extends ESTestCase {
addAccountSettings("account1", builder);
addAccountSettings("account2", builder);
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
Accounts accounts = new Accounts(builder.build(), null, logger);
Account account = accounts.account("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -88,7 +87,7 @@ public class AccountsTests extends ESTestCase {
addAccountSettings("account1", builder);
addAccountSettings("account2", builder);
try {
new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
new Accounts(builder.build(), null, logger);
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), is("could not find default email account [unknown]"));
@ -97,7 +96,7 @@ public class AccountsTests extends ESTestCase {
public void testNoAccount() throws Exception {
Settings.Builder builder = Settings.builder();
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
Accounts accounts = new Accounts(builder.build(), null, logger);
try {
accounts.account(null);
fail("no accounts are configured so trying to get the default account should throw an IllegalStateException");
@ -110,7 +109,7 @@ public class AccountsTests extends ESTestCase {
Settings.Builder builder = Settings.builder()
.put("default_account", "unknown");
try {
new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
new Accounts(builder.build(), null, logger);
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), is("could not find default email account [unknown]"));

View File

@ -8,9 +8,9 @@ package org.elasticsearch.xpack.notification.email;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.watcher.client.WatcherClient;
import org.elasticsearch.xpack.watcher.execution.ActionExecutionMode;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
@ -34,7 +34,6 @@ import static org.elasticsearch.xpack.watcher.condition.ConditionBuilders.always
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.cron;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
@ -97,18 +96,10 @@ public class EmailSecretsIntegrationTests extends AbstractWatcherIntegrationTest
assertThat(value, notNullValue());
if (securityEnabled() && encryptSensitiveData) {
assertThat(value, not(is((Object) PASSWORD)));
SecretService secretService = getInstanceFromMaster(SecretService.class);
assertThat(secretService, instanceOf(SecretService.Secure.class));
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
CryptoService cryptoService = getInstanceFromMaster(CryptoService.class);
assertThat(new String(cryptoService.decrypt(((String) value).toCharArray())), is(PASSWORD));
} else {
assertThat(value, is((Object) PASSWORD));
SecretService secretService = getInstanceFromMaster(SecretService.class);
if (securityEnabled()) {
assertThat(secretService, instanceOf(SecretService.Secure.class));
} else {
assertThat(secretService, instanceOf(SecretService.Insecure.class));
}
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
}
// verifying the password is not returned by the GET watch API

View File

@ -10,7 +10,6 @@ import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.common.secret.Secret;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.junit.After;
import org.junit.Before;
@ -33,7 +32,7 @@ public class InternalEmailServiceTests extends ESTestCase {
@Before
public void init() throws Exception {
accounts = mock(Accounts.class);
service = new InternalEmailService(Settings.EMPTY, SecretService.Insecure.INSTANCE,
service = new InternalEmailService(Settings.EMPTY, null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(InternalEmailService.EMAIL_ACCOUNT_SETTING))) {
@Override
protected Accounts createAccounts(Settings settings, ESLogger logger) {

View File

@ -11,7 +11,6 @@ import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.xpack.common.secret.SecretService;
import java.util.Collections;
import java.util.Locale;
@ -123,7 +122,7 @@ public class ManualPublicSmtpServersTester {
static InternalEmailService startEmailService(Settings.Builder builder) {
Settings settings = builder.build();
InternalEmailService service = new InternalEmailService(settings, SecretService.Insecure.INSTANCE,
InternalEmailService service = new InternalEmailService(settings, null,
new ClusterSettings(settings, Collections.singleton(InternalEmailService.EMAIL_ACCOUNT_SETTING)));
service.start();
return service;

View File

@ -7,7 +7,6 @@ package org.elasticsearch.xpack.notification.email;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.common.secret.SecretService;
import javax.mail.BodyPart;
import javax.mail.Part;
@ -38,7 +37,7 @@ public class ProfileTests extends ESTestCase {
.put("account.foo.smtp.host", "_host")
.build();
Accounts accounts = new Accounts(settings, SecretService.Insecure.INSTANCE, logger);
Accounts accounts = new Accounts(settings, null, logger);
Session session = accounts.account("foo").getConfig().createSession();
MimeMessage mimeMessage = Profile.STANDARD.toMimeMessage(email, session);

View File

@ -17,7 +17,6 @@ import org.elasticsearch.xpack.common.http.HttpResponse;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
import org.junit.Before;
@ -42,8 +41,7 @@ public class HttpEmailAttachementParserTests extends ESTestCase {
@Before
public void init() throws Exception {
SecretService.Insecure secretService = SecretService.Insecure.INSTANCE;
HttpAuthRegistry authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(secretService)));
HttpAuthRegistry authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(null)));
httpRequestTemplateParser = new HttpRequestTemplate.Parser(authRegistry);
httpClient = mock(HttpClient.class);

View File

@ -15,17 +15,17 @@ import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.xcontent.XContentLocation;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.support.clock.Clock;
import org.elasticsearch.xpack.support.clock.SystemClock;
import org.elasticsearch.xpack.common.secret.Secret;
import org.elasticsearch.xpack.common.secret.SecretService;
/**
* A xcontent parser that is used by watcher. This is a special parser that is
* aware of watcher services. In particular, it's aware of the used {@link Clock}
* and the {@link SecretService}. The former (clock) may be used when the current time
* is required during the parse phase of construct. The latter (secret service) is used
* to convert secret values (e.g. passwords, security tokens, etc..) to {@link Secret}s.
* and the {@link CryptoService}. The former (clock) may be used when the current time
* is required during the parse phase of construct. The latter (crypto service) is used
* to encode secret values (e.g. passwords, security tokens, etc..) to {@link Secret}s.
* {@link Secret}s are encrypted values that are stored in memory and are decrypted
* on demand when needed.
*/
@ -35,8 +35,8 @@ public class WatcherXContentParser implements XContentParser {
char[] chars = parser.text().toCharArray();
if (parser instanceof WatcherXContentParser) {
WatcherXContentParser watcherParser = (WatcherXContentParser) parser;
if (watcherParser.secretService != null) {
chars = watcherParser.secretService.encrypt(chars);
if (watcherParser.cryptoService != null) {
chars = watcherParser.cryptoService.encrypt(chars);
}
}
return new Secret(chars);
@ -50,8 +50,8 @@ public class WatcherXContentParser implements XContentParser {
char[] chars = parser.text().toCharArray();
if (parser instanceof WatcherXContentParser) {
WatcherXContentParser watcherParser = (WatcherXContentParser) parser;
if (watcherParser.secretService != null) {
chars = watcherParser.secretService.encrypt(text.toCharArray());
if (watcherParser.cryptoService != null) {
chars = watcherParser.cryptoService.encrypt(text.toCharArray());
}
return new Secret(chars);
}
@ -67,12 +67,12 @@ public class WatcherXContentParser implements XContentParser {
private final Clock clock;
private final XContentParser parser;
@Nullable private final SecretService secretService;
@Nullable private final CryptoService cryptoService;
public WatcherXContentParser(XContentParser parser, Clock clock, @Nullable SecretService secretService) {
public WatcherXContentParser(XContentParser parser, Clock clock, @Nullable CryptoService cryptoService) {
this.clock = clock;
this.parser = parser;
this.secretService = secretService;
this.cryptoService = cryptoService;
}
@Override

View File

@ -19,7 +19,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.xpack.common.secret.Secret;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.support.clock.Clock;
import org.elasticsearch.xpack.support.clock.HaltedClock;
import org.elasticsearch.xpack.watcher.Watcher;
@ -213,7 +213,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
private final TransformRegistry transformRegistry;
private final ActionRegistry actionRegistry;
private final InputRegistry inputRegistry;
private final SecretService secretService;
private final CryptoService cryptoService;
private final ExecutableInput defaultInput;
private final ExecutableCondition defaultCondition;
private final ExecutableActions defaultActions;
@ -222,7 +222,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
@Inject
public Parser(Settings settings, ConditionRegistry conditionRegistry, TriggerService triggerService,
TransformRegistry transformRegistry, ActionRegistry actionRegistry,
InputRegistry inputRegistry, SecretService secretService, Clock clock) {
InputRegistry inputRegistry, @Nullable CryptoService cryptoService, Clock clock) {
super(settings);
this.conditionRegistry = conditionRegistry;
@ -230,7 +230,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
this.triggerService = triggerService;
this.actionRegistry = actionRegistry;
this.inputRegistry = inputRegistry;
this.secretService = Watcher.ENCRYPT_SENSITIVE_DATA_SETTING.get(settings) ? secretService : SecretService.Insecure.INSTANCE;
this.cryptoService = Watcher.ENCRYPT_SENSITIVE_DATA_SETTING.get(settings) ? cryptoService : null;
this.defaultInput = new ExecutableNoneInput(logger);
this.defaultCondition = new ExecutableAlwaysCondition(logger);
this.defaultActions = new ExecutableActions(Collections.emptyList());
@ -249,10 +249,8 @@ public class Watch implements TriggerEngine.Job, ToXContent {
* Parses the watch represented by the given source. When parsing, any sensitive data that the
* source might contain (e.g. passwords) will be converted to {@link Secret secrets}
* Such that the returned watch will potentially hide this sensitive data behind a "secret". A secret
* is an abstraction around sensitive data (text). There can be different implementations of how the
* secret holds the data, depending on the wired up {@link SecretService}. When security is enabled, a
* {@link SecretService.Secure} is used, that potentially encrypts the data
* using the configured system key.
* is an abstraction around sensitive data (text). When security is enabled, the
* {@link CryptoService} is used to encrypt the secrets.
*
* This method is only called once - when the user adds a new watch. From that moment on, all representations
* of the watch in the system will be use secrets for sensitive data.
@ -269,7 +267,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
}
XContentParser parser = null;
try {
parser = new WatcherXContentParser(createParser(source), new HaltedClock(now), withSecrets ? secretService : null);
parser = new WatcherXContentParser(createParser(source), new HaltedClock(now), withSecrets ? cryptoService : null);
parser.nextToken();
return parse(id, includeStatus, parser);
} catch (IOException ioe) {

View File

@ -25,7 +25,6 @@ import org.elasticsearch.xpack.common.http.HttpResponse;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.common.secret.Secret;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.common.text.TextTemplate;
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
import org.elasticsearch.xpack.watcher.support.xcontent.WatcherParams;
@ -82,8 +81,7 @@ import static org.mockito.Mockito.when;
*/
public class EmailActionTests extends ESTestCase {
private SecretService secretService = mock(SecretService.class);
private HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
private HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
private HttpClient httpClient = mock(HttpClient.class);
private EmailAttachmentsParser emailAttachmentParser;

View File

@ -28,7 +28,6 @@ import org.elasticsearch.xpack.common.http.HttpResponse;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.common.text.TextTemplate;
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
@ -87,10 +86,9 @@ public class WebhookActionTests extends ESTestCase {
@Before
public void init() throws Exception {
templateEngine = new MockTextTemplateEngine();
SecretService secretService = mock(SecretService.class);
testBody = TextTemplate.inline(TEST_BODY_STRING).build();
testPath = TextTemplate.inline(TEST_PATH_STRING).build();
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
}
public void testExecute() throws Exception {

View File

@ -32,7 +32,6 @@ import org.elasticsearch.xpack.common.http.auth.HttpAuth;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.common.text.TextTemplate;
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule;
@ -71,15 +70,13 @@ import static org.mockito.Mockito.when;
public class HttpInputTests extends ESTestCase {
private HttpClient httpClient;
private HttpInputFactory httpParser;
private SecretService secretService;
private TextTemplateEngine templateEngine;
@Before
public void init() throws Exception {
httpClient = mock(HttpClient.class);
templateEngine = mock(TextTemplateEngine.class);
secretService = mock(SecretService.class);
HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
httpParser = new HttpInputFactory(Settings.EMPTY, httpClient, templateEngine, new HttpRequestTemplate.Parser(registry));
}

View File

@ -12,12 +12,12 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.watcher.client.WatcherClient;
import org.elasticsearch.xpack.watcher.execution.ActionExecutionMode;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.auth.basic.ApplicableBasicAuth;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
@ -117,18 +117,10 @@ public class HttpSecretsIntegrationTests extends AbstractWatcherIntegrationTestC
assertThat(value, notNullValue());
if (securityEnabled() && encryptSensitiveData) {
assertThat(value, not(is((Object) PASSWORD)));
SecretService secretService = getInstanceFromMaster(SecretService.class);
assertThat(secretService, instanceOf(SecretService.Secure.class));
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
CryptoService cryptoService = getInstanceFromMaster(CryptoService.class);
assertThat(new String(cryptoService.decrypt(((String) value).toCharArray())), is(PASSWORD));
} else {
assertThat(value, is((Object) PASSWORD));
SecretService secretService = getInstanceFromMaster(SecretService.class);
if (securityEnabled()) {
assertThat(secretService, instanceOf(SecretService.Secure.class));
} else {
assertThat(secretService, instanceOf(SecretService.Insecure.class));
}
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
}
// verifying the password is not returned by the GET watch API
@ -189,18 +181,10 @@ public class HttpSecretsIntegrationTests extends AbstractWatcherIntegrationTestC
if (securityEnabled() && encryptSensitiveData) {
assertThat(value, not(is((Object) PASSWORD)));
SecretService secretService = getInstanceFromMaster(SecretService.class);
assertThat(secretService, instanceOf(SecretService.Secure.class));
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
CryptoService cryptoService = getInstanceFromMaster(CryptoService.class);
assertThat(new String(cryptoService.decrypt(((String) value).toCharArray())), is(PASSWORD));
} else {
assertThat(value, is((Object) PASSWORD));
SecretService secretService = getInstanceFromMaster(SecretService.class);
if (securityEnabled()) {
assertThat(secretService, instanceOf(SecretService.Secure.class));
} else {
assertThat(secretService, instanceOf(SecretService.Insecure.class));
}
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
}
// verifying the password is not returned by the GET watch API

View File

@ -23,7 +23,6 @@ import org.elasticsearch.xpack.common.http.HttpMethod;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
import org.elasticsearch.xpack.common.secret.SecretService;
import org.elasticsearch.xpack.common.text.TextTemplate;
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
import org.elasticsearch.xpack.notification.email.DataAttachment;
@ -149,7 +148,6 @@ public class WatchTests extends ESTestCase {
private TextTemplateEngine templateEngine;
private HtmlSanitizer htmlSanitizer;
private HttpAuthRegistry authRegistry;
private SecretService secretService;
private WatcherLicensee watcherLicensee;
private ESLogger logger;
private Settings settings = Settings.EMPTY;
@ -163,9 +161,8 @@ public class WatchTests extends ESTestCase {
emailService = mock(EmailService.class);
templateEngine = mock(TextTemplateEngine.class);
htmlSanitizer = mock(HtmlSanitizer.class);
secretService = mock(SecretService.class);
watcherLicensee = mock(WatcherLicensee.class);
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
logger = Loggers.getLogger(WatchTests.class);
searchTemplateService = mock(WatcherSearchTemplateService.class);
}
@ -181,7 +178,6 @@ public class WatchTests extends ESTestCase {
ScheduleRegistry scheduleRegistry = registry(schedule);
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, clock);
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
SecretService secretService = SecretService.Insecure.INSTANCE;
ExecutableInput input = randomInput();
InputRegistry inputRegistry = registry(input);
@ -209,7 +205,7 @@ public class WatchTests extends ESTestCase {
BytesReference bytes = XContentFactory.jsonBuilder().value(watch).bytes();
logger.info("{}", bytes.utf8ToString());
Watch.Parser watchParser = new Watch.Parser(settings, conditionRegistry, triggerService, transformRegistry, actionRegistry,
inputRegistry, secretService, clock);
inputRegistry, null, clock);
Watch parsedWatch = watchParser.parse("_name", includeStatus, bytes);
@ -231,7 +227,6 @@ public class WatchTests extends ESTestCase {
ScheduleRegistry scheduleRegistry = registry(randomSchedule());
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, clock);
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
SecretService secretService = SecretService.Insecure.INSTANCE;
ExecutableCondition condition = randomCondition();
ConditionRegistry conditionRegistry = registry(condition);
ExecutableInput input = randomInput();
@ -248,7 +243,7 @@ public class WatchTests extends ESTestCase {
.startArray("actions").endArray()
.endObject();
Watch.Parser watchParser = new Watch.Parser(settings, conditionRegistry, triggerService, transformRegistry, actionRegistry,
inputRegistry, secretService, clock);
inputRegistry, null, clock);
try {
watchParser.parse("failure", false, jsonBuilder.bytes());
fail("This watch should fail to parse as actions is an array");
@ -262,7 +257,6 @@ public class WatchTests extends ESTestCase {
ScheduleRegistry scheduleRegistry = registry(schedule);
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, SystemClock.INSTANCE);
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
SecretService secretService = SecretService.Insecure.INSTANCE;
ConditionRegistry conditionRegistry = registry(new ExecutableAlwaysCondition(logger));
InputRegistry inputRegistry = registry(new ExecutableNoneInput(logger));
@ -277,7 +271,7 @@ public class WatchTests extends ESTestCase {
.endObject();
builder.endObject();
Watch.Parser watchParser = new Watch.Parser(settings, conditionRegistry, triggerService, transformRegistry, actionRegistry,
inputRegistry, secretService, SystemClock.INSTANCE);
inputRegistry, null, SystemClock.INSTANCE);
Watch watch = watchParser.parse("failure", false, builder.bytes());
assertThat(watch, notNullValue());
assertThat(watch.trigger(), instanceOf(ScheduleTrigger.class));