Remove Watcher Account "unsecure" settings (#36736)

Removes all sensitive settings (passwords, auth tokens, urls, etc...) for
watcher notifications accounts. These settings were deprecated (and
herein removed) in favor of their secure sibling that is set inside the
elasticsearch keystore. For example:
`xpack.notification.email.account.<id>.smtp.password`
is no longer a valid setting, and it is replaced by
`xpack.notification.email.account.<id>.smtp.secure_password`
This commit is contained in:
Albert Zaharovits 2019-01-20 12:51:24 +02:00 committed by GitHub
parent fc99eb3e65
commit 5308746270
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 243 additions and 226 deletions

View File

@ -131,3 +131,26 @@ The removal of these default settings also removes the ability for a component t
fallback to a default configuration when using TLS. Each component (realm, transport, http,
http client, etc) must now be configured with their own settings for TLS if it is being
used.
[float]
[[watcher-notifications-account-settings]]
==== Watcher notifications account settings
The following settings have been removed in favor of the secure variants.
The <<secure-settings, secure settings>> have to be defined inside each cluster
node's keystore, i.e., they are not to be specified via the cluster settings API.
- `xpack.notification.email.account.<id>.smtp.password`, instead use
`xpack.notification.email.account.<id>.smtp.secure_password`
- `xpack.notification.hipchat.account.<id>.auth_token`, instead use
`xpack.notification.hipchat.account.<id>.secure_auth_token`
- `xpack.notification.jira.account.<id>.url`, instead use
`xpack.notification.jira.account.<id>.secure_url`
- `xpack.notification.jira.account.<id>.user`, instead use
`xpack.notification.jira.account.<id>.secure_user`
- `xpack.notification.jira.account.<id>.password`, instead use
`xpack.notification.jira.account.<id>.secure_password`
- `xpack.notification.pagerduty.account.<id>.service_api_key`, instead use
`xpack.notification.pagerduty.account.<id>.secure_service_api_key`
- `xpack.notification.slack.account.<id>.url`, instead use
`xpack.notification.slack.account.<id>.secure_url`

View File

@ -115,7 +115,7 @@ can specify the following email account attributes:
`smtp.user` (<<cluster-update-settings,Dynamic>>);;
The user name for SMTP. Required.
`smtp.password` (<<cluster-update-settings,Dynamic>>);;
`smtp.secure_password` (<<secure-settings,Secure>>);;
The password for the specified SMTP user.
`smtp.starttls.enable` (<<cluster-update-settings,Dynamic>>);;
@ -222,9 +222,8 @@ via HipChat. You can specify the following HipChat account attributes:
The HipChat account profile to use: `integration`,
`user`, or `v1`. Required.
`auth_token`;;
The authentication token to use to access
the HipChat API. Required.
`secure_auth_token` (<<secure-settings,Secure>>);;
The authentication token to use to access the HipChat API. Required.
`host`;;
The HipChat server hostname. Defaults to `api.hipchat.com`.
@ -268,9 +267,8 @@ via Slack. You can specify the following Slack account attributes:
[[slack-account-attributes]]
`url`;;
The Incoming Webhook URL to use to post
messages to Slack. Required.
`secure_url` (<<secure-settings,Secure>>);;
The Incoming Webhook URL to use to post messages to Slack. Required.
`message_defaults.from`;;
The sender name to display in the
@ -309,13 +307,13 @@ issues in Jira. You can specify the following Jira account attributes:
[[jira-account-attributes]]
`url`;;
`secure_url` (<<secure-settings,Secure>>);;
The URL of the Jira Software server. Required.
`user`;;
`secure_user` (<<secure-settings,Secure>>);;
The name of the user to connect to the Jira Software server. Required.
`password`;;
`secure_password` (<<secure-settings,Secure>>);;
The password of the user to connect to the Jira Software server. Required.
`issue_defaults`;;
@ -341,7 +339,7 @@ via PagerDuty. You can specify the following PagerDuty account attributes:
A name for the PagerDuty account associated with the API key you
are using to access PagerDuty. Required.
`service_api_key`;;
`secure_service_api_key` (<<secure-settings,Secure>>);;
The https://developer.pagerduty.com/documentation/rest/authentication[
PagerDuty API key] to use to access PagerDuty. Required.

View File

@ -32,8 +32,7 @@ import java.util.Set;
public class Account {
static final String SMTP_PROTOCOL = "smtp";
private static final String SMTP_PASSWORD = "password";
private static final Setting<SecureString> SECURE_PASSWORD_SETTING = SecureSetting.secureString("secure_" + SMTP_PASSWORD, null);
public static final Setting<SecureString> SECURE_PASSWORD_SETTING = SecureSetting.secureString("secure_password", null);
static {
SecurityManager sm = System.getSecurityManager();
@ -213,7 +212,7 @@ public class Account {
port = settings.getAsInt("port", settings.getAsInt("localport", settings.getAsInt("local_port", 25)));
user = settings.get("user", settings.get("from", null));
password = getSecureSetting(SMTP_PASSWORD, settings, SECURE_PASSWORD_SETTING);
password = getSecureSetting(settings, SECURE_PASSWORD_SETTING);
//password = passStr != null ? passStr.toCharArray() : null;
properties = loadSmtpProperties(settings);
}
@ -225,17 +224,12 @@ public class Account {
* Note: if your setting was not previously secure, than the string reference that is in the setting object is still
* insecure. This is only constructing a new SecureString with the char[] of the insecure setting.
*/
private static SecureString getSecureSetting(String settingName, Settings settings, Setting<SecureString> secureSetting) {
String value = settings.get(settingName);
if (value == null) {
SecureString secureString = secureSetting.get(settings);
if (secureString != null && secureString.length() > 0) {
return secureString;
} else {
return null;
}
private static SecureString getSecureSetting(Settings settings, Setting<SecureString> secureSetting) {
SecureString secureString = secureSetting.get(settings);
if (secureString != null && secureString.length() > 0) {
return secureString;
} else {
return new SecureString(value.toCharArray());
return null;
}
}

View File

@ -65,10 +65,6 @@ public class EmailService extends NotificationService<Account> {
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.user",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_SMTP_PASSWORD =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.password",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private static final Setting.AffixSetting<SecureString> SETTING_SECURE_PASSWORD =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.secure_password",
(key) -> SecureSetting.secureString(key, null));
@ -122,7 +118,6 @@ public class EmailService extends NotificationService<Account> {
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_HOST, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_PORT, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_USER, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_PASSWORD, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_TIMEOUT, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_CONNECTION_TIMEOUT, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_WRITE_TIMEOUT, (s, o) -> {}, (s, o) -> {});
@ -182,7 +177,7 @@ public class EmailService extends NotificationService<Account> {
private static List<Setting<?>> getDynamicSettings() {
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_PROFILE, SETTING_EMAIL_DEFAULTS, SETTING_SMTP_AUTH, SETTING_SMTP_HOST,
SETTING_SMTP_PASSWORD, SETTING_SMTP_PORT, SETTING_SMTP_STARTTLS_ENABLE, SETTING_SMTP_USER, SETTING_SMTP_STARTTLS_REQUIRED,
SETTING_SMTP_PORT, SETTING_SMTP_STARTTLS_ENABLE, SETTING_SMTP_USER, SETTING_SMTP_STARTTLS_REQUIRED,
SETTING_SMTP_TIMEOUT, SETTING_SMTP_CONNECTION_TIMEOUT, SETTING_SMTP_WRITE_TIMEOUT, SETTING_SMTP_LOCAL_ADDRESS,
SETTING_SMTP_LOCAL_PORT, SETTING_SMTP_SEND_PARTIAL, SETTING_SMTP_WAIT_ON_QUIT, SETTING_SMTP_SSL_TRUST_ADDRESS);
}

View File

@ -23,7 +23,6 @@ import java.util.Map;
public abstract class HipChatAccount {
public static final String AUTH_TOKEN_SETTING = "auth_token";
public static final String ROOM_SETTING = HipChatMessage.Field.ROOM.getPreferredName();
public static final String DEFAULT_ROOM_SETTING = "message_defaults." + HipChatMessage.Field.ROOM.getPreferredName();
public static final String DEFAULT_USER_SETTING = "message_defaults." + HipChatMessage.Field.USER.getPreferredName();
@ -32,7 +31,7 @@ public abstract class HipChatAccount {
public static final String DEFAULT_COLOR_SETTING = "message_defaults." + HipChatMessage.Field.COLOR.getPreferredName();
public static final String DEFAULT_NOTIFY_SETTING = "message_defaults." + HipChatMessage.Field.NOTIFY.getPreferredName();
private static final Setting<SecureString> SECURE_AUTH_TOKEN_SETTING = SecureSetting.secureString("secure_" + AUTH_TOKEN_SETTING, null);
static final Setting<SecureString> SECURE_AUTH_TOKEN_SETTING = SecureSetting.secureString("secure_auth_token", null);
protected final Logger logger;
protected final String name;
@ -52,16 +51,12 @@ public abstract class HipChatAccount {
}
private static String getAuthToken(String name, Settings settings) {
String authToken = settings.get(AUTH_TOKEN_SETTING);
if (authToken == null || authToken.length() == 0) {
SecureString secureString = SECURE_AUTH_TOKEN_SETTING.get(settings);
if (secureString == null || secureString.length() < 1) {
throw new SettingsException("hipchat account [" + name + "] missing required [" + AUTH_TOKEN_SETTING + "] setting");
}
authToken = secureString.toString();
SecureString secureString = SECURE_AUTH_TOKEN_SETTING.get(settings);
if (secureString == null || secureString.length() < 1) {
throw new SettingsException(
"hipchat account [" + name + "] missing required [" + SECURE_AUTH_TOKEN_SETTING.getKey() + "] secure setting");
}
return authToken;
return secureString.toString();
}
public abstract String type();

View File

@ -34,11 +34,6 @@ public class HipChatService extends NotificationService<HipChatAccount> {
static final Setting<Integer> SETTING_DEFAULT_PORT =
Setting.intSetting("xpack.notification.hipchat.port", 443, Setting.Property.Dynamic, Setting.Property.NodeScope);
private static final Setting.AffixSetting<String> SETTING_AUTH_TOKEN =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "auth_token",
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope, Setting.Property.Filtered,
Setting.Property.Deprecated));
private static final Setting.AffixSetting<SecureString> SETTING_AUTH_TOKEN_SECURE =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "secure_auth_token",
(key) -> SecureSetting.secureString(key, null));
@ -75,7 +70,6 @@ public class HipChatService extends NotificationService<HipChatAccount> {
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_HOST, (s) -> {});
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_PORT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_AUTH_TOKEN, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_PROFILE, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_ROOM, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_HOST, (s, o) -> {}, (s, o) -> {});
@ -101,7 +95,7 @@ public class HipChatService extends NotificationService<HipChatAccount> {
}
private static List<Setting<?>> getDynamicSettings() {
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_AUTH_TOKEN, SETTING_PROFILE, SETTING_ROOM, SETTING_MESSAGE_DEFAULTS,
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_PROFILE, SETTING_ROOM, SETTING_MESSAGE_DEFAULTS,
SETTING_DEFAULT_HOST, SETTING_DEFAULT_PORT, SETTING_HOST, SETTING_PORT);
}

View File

@ -6,7 +6,6 @@
package org.elasticsearch.xpack.watcher.notification.jira;
import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.SecureSetting;
import org.elasticsearch.common.settings.SecureString;
@ -42,15 +41,12 @@ public class JiraAccount {
**/
public static final String DEFAULT_PATH = "/rest/api/2/issue";
static final String USER_SETTING = "user";
static final String PASSWORD_SETTING = "password";
static final String URL_SETTING = "url";
static final String ISSUE_DEFAULTS_SETTING = "issue_defaults";
static final String ALLOW_HTTP_SETTING = "allow_http";
private static final Setting<SecureString> SECURE_USER_SETTING = SecureSetting.secureString("secure_" + USER_SETTING, null);
private static final Setting<SecureString> SECURE_PASSWORD_SETTING = SecureSetting.secureString("secure_" + PASSWORD_SETTING, null);
private static final Setting<SecureString> SECURE_URL_SETTING = SecureSetting.secureString("secure_" + URL_SETTING, null);
public static final Setting<SecureString> SECURE_USER_SETTING = SecureSetting.secureString("secure_user", null);
public static final Setting<SecureString> SECURE_PASSWORD_SETTING = SecureSetting.secureString("secure_password", null);
public static final Setting<SecureString> SECURE_URL_SETTING = SecureSetting.secureString("secure_url", null);
private final HttpClient httpClient;
private final String name;
@ -62,7 +58,7 @@ public class JiraAccount {
public JiraAccount(String name, Settings settings, HttpClient httpClient) {
this.httpClient = httpClient;
this.name = name;
String url = getSetting(name, URL_SETTING, settings, SECURE_URL_SETTING);
String url = getSetting(name, settings, SECURE_URL_SETTING);
try {
URI uri = new URI(url);
Scheme protocol = Scheme.parse(uri.getScheme());
@ -71,16 +67,11 @@ public class JiraAccount {
}
this.url = uri;
} catch (URISyntaxException | IllegalArgumentException e) {
throw new SettingsException("invalid jira [" + name + "] account settings. invalid [" + URL_SETTING + "] setting", e);
}
this.user = getSetting(name, USER_SETTING, settings, SECURE_USER_SETTING);
if (Strings.isEmpty(this.user)) {
throw requiredSettingException(name, USER_SETTING);
}
this.password = getSetting(name, PASSWORD_SETTING, settings, SECURE_PASSWORD_SETTING);
if (Strings.isEmpty(this.password)) {
throw requiredSettingException(name, PASSWORD_SETTING);
throw new SettingsException(
"invalid jira [" + name + "] account settings. invalid [" + SECURE_URL_SETTING.getKey() + "] setting", e);
}
this.user = getSetting(name, settings, SECURE_USER_SETTING);
this.password = getSetting(name, settings, SECURE_PASSWORD_SETTING);
try (XContentBuilder builder = XContentBuilder.builder(XContentType.JSON.xContent())) {
builder.startObject();
settings.getAsSettings(ISSUE_DEFAULTS_SETTING).toXContent(builder, ToXContent.EMPTY_PARAMS);
@ -95,17 +86,12 @@ public class JiraAccount {
}
}
private static String getSetting(String accountName, String settingName, Settings settings, Setting<SecureString> secureSetting) {
String value = settings.get(settingName);
if (value == null) {
SecureString secureString = secureSetting.get(settings);
if (secureString == null || secureString.length() < 1) {
throw requiredSettingException(accountName, settingName);
}
value = secureString.toString();
private static String getSetting(String accountName, Settings settings, Setting<SecureString> secureSetting) {
SecureString secureString = secureSetting.get(settings);
if (secureString == null || secureString.length() < 1) {
throw requiredSettingException(accountName, secureSetting.getKey());
}
return value;
return secureString.toString();
}
public String getName() {

View File

@ -32,18 +32,6 @@ public class JiraService extends NotificationService<JiraAccount> {
Setting.affixKeySetting("xpack.notification.jira.account.", "allow_http",
(key) -> Setting.boolSetting(key, false, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_URL =
Setting.affixKeySetting("xpack.notification.jira.account.", "url",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private static final Setting.AffixSetting<String> SETTING_USER =
Setting.affixKeySetting("xpack.notification.jira.account.", "user",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private static final Setting.AffixSetting<String> SETTING_PASSWORD =
Setting.affixKeySetting("xpack.notification.jira.account.", "password",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered, Property.Deprecated));
private static final Setting.AffixSetting<SecureString> SETTING_SECURE_USER =
Setting.affixKeySetting("xpack.notification.jira.account.", "secure_user",
(key) -> SecureSetting.secureString(key, null));
@ -68,9 +56,6 @@ public class JiraService extends NotificationService<JiraAccount> {
// ensure logging of setting changes
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_ALLOW_HTTP, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_URL, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_USER, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_PASSWORD, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_DEFAULTS, (s, o) -> {}, (s, o) -> {});
// do an initial load
reload(settings);
@ -82,7 +67,7 @@ public class JiraService extends NotificationService<JiraAccount> {
}
private static List<Setting<?>> getDynamicSettings() {
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_ALLOW_HTTP, SETTING_URL, SETTING_USER, SETTING_PASSWORD, SETTING_DEFAULTS);
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_ALLOW_HTTP, SETTING_DEFAULTS);
}
private static List<Setting<?>> getSecureSettings() {

View File

@ -19,19 +19,17 @@ import java.io.IOException;
public class PagerDutyAccount {
private static final String SERVICE_KEY_SETTING = "service_api_key";
private static final String TRIGGER_DEFAULTS_SETTING = "event_defaults";
private static final Setting<SecureString> SECURE_SERVICE_API_KEY_SETTING =
SecureSetting.secureString("secure_" + SERVICE_KEY_SETTING, null);
public static final Setting<SecureString> SECURE_SERVICE_API_KEY_SETTING = SecureSetting.secureString("secure_service_api_key", null);
private final String name;
private final String serviceKey;
private final HttpClient httpClient;
private final IncidentEventDefaults eventDefaults;
PagerDutyAccount(String name, Settings accountSettings, Settings serviceSettings, HttpClient httpClient) {
PagerDutyAccount(String name, Settings accountSettings, HttpClient httpClient) {
this.name = name;
this.serviceKey = getServiceKey(name, accountSettings, serviceSettings);
this.serviceKey = getServiceKey(name, accountSettings);
this.httpClient = httpClient;
this.eventDefaults = new IncidentEventDefaults(accountSettings.getAsSettings(TRIGGER_DEFAULTS_SETTING));
@ -51,17 +49,12 @@ public class PagerDutyAccount {
return SentEvent.responded(event, request, response);
}
private static String getServiceKey(String name, Settings accountSettings, Settings serviceSettings) {
String serviceKey = accountSettings.get(SERVICE_KEY_SETTING, serviceSettings.get(SERVICE_KEY_SETTING, null));
if (serviceKey == null) {
SecureString secureString = SECURE_SERVICE_API_KEY_SETTING.get(accountSettings);
if (secureString == null || secureString.length() < 1) {
throw new SettingsException("invalid pagerduty account [" + name + "]. missing required [" + SERVICE_KEY_SETTING +
"] setting");
}
serviceKey = secureString.toString();
private static String getServiceKey(String name, Settings accountSettings) {
SecureString secureString = SECURE_SERVICE_API_KEY_SETTING.get(accountSettings);
if (secureString == null || secureString.length() < 1) {
throw new SettingsException(
"invalid pagerduty account [" + name + "]. missing required [" + SECURE_SERVICE_API_KEY_SETTING.getKey() + "] setting");
}
return serviceKey;
return secureString.toString();
}
}

View File

@ -26,10 +26,6 @@ public class PagerDutyService extends NotificationService<PagerDutyAccount> {
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
Setting.simpleString("xpack.notification.pagerduty.default_account", Property.Dynamic, Property.NodeScope);
private static final Setting.AffixSetting<String> SETTING_SERVICE_API_KEY =
Setting.affixKeySetting("xpack.notification.pagerduty.account.", "service_api_key",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered, Property.Deprecated));
private static final Setting.AffixSetting<SecureString> SETTING_SECURE_SERVICE_API_KEY =
Setting.affixKeySetting("xpack.notification.pagerduty.account.", "secure_service_api_key",
(key) -> SecureSetting.secureString(key, null));
@ -45,7 +41,6 @@ public class PagerDutyService extends NotificationService<PagerDutyAccount> {
this.httpClient = httpClient;
// ensure logging of setting changes
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SERVICE_API_KEY, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_DEFAULTS, (s, o) -> {}, (s, o) -> {});
// do an initial load
reload(settings);
@ -53,11 +48,11 @@ public class PagerDutyService extends NotificationService<PagerDutyAccount> {
@Override
protected PagerDutyAccount createAccount(String name, Settings accountSettings) {
return new PagerDutyAccount(name, accountSettings, accountSettings, httpClient);
return new PagerDutyAccount(name, accountSettings, httpClient);
}
private static List<Setting<?>> getDynamicSettings() {
return Arrays.asList(SETTING_SERVICE_API_KEY, SETTING_DEFAULTS, SETTING_DEFAULT_ACCOUNT);
return Arrays.asList(SETTING_DEFAULTS, SETTING_DEFAULT_ACCOUNT);
}
private static List<Setting<?>> getSecureSettings() {

View File

@ -32,11 +32,9 @@ import java.util.List;
public class SlackAccount {
public static final String URL_SETTING = "url";
public static final String MESSAGE_DEFAULTS_SETTING = "message_defaults";
private static final Setting<SecureString> SECURE_URL_SETTING = SecureSetting.secureString("secure_" + URL_SETTING, null);
private static final Setting<SecureString> SECURE_URL_SETTING = SecureSetting.secureString("secure_url", null);
final String name;
final URI url;
@ -44,9 +42,9 @@ public class SlackAccount {
final Logger logger;
final SlackMessageDefaults messageDefaults;
public SlackAccount(String name, Settings settings, Settings defaultSettings, HttpClient httpClient, Logger logger) {
public SlackAccount(String name, Settings settings, HttpClient httpClient, Logger logger) {
this.name = name;
this.url = url(name, settings, defaultSettings);
this.url = url(name, settings);
this.messageDefaults = new SlackMessageDefaults(settings.getAsSettings(MESSAGE_DEFAULTS_SETTING));
this.httpClient = httpClient;
this.logger = logger;
@ -120,21 +118,17 @@ public class SlackAccount {
}
}
static URI url(String name, Settings settings, Settings defaultSettings) {
String url = settings.get(URL_SETTING, defaultSettings.get(URL_SETTING, null));
if (url == null) {
SecureString secureStringUrl = SECURE_URL_SETTING.get(settings);
if (secureStringUrl != null && secureStringUrl.length() > 0) {
url = secureStringUrl.toString();
}
}
if (url == null) {
throw new SettingsException("invalid slack [" + name + "] account settings. missing required [" + URL_SETTING + "] setting");
static URI url(String name, Settings settings) {
SecureString secureStringUrl = SECURE_URL_SETTING.get(settings);
if (secureStringUrl == null || secureStringUrl.length() < 1) {
throw new SettingsException(
"invalid slack [" + name + "] account settings. missing required [" + SECURE_URL_SETTING.getKey() + "] setting");
}
try {
return new URI(url);
return new URI(secureStringUrl.toString());
} catch (URISyntaxException e) {
throw new SettingsException("invalid slack [" + name + "] account settings. invalid [" + URL_SETTING + "] setting", e);
throw new SettingsException(
"invalid slack [" + name + "] account settings. invalid [" + SECURE_URL_SETTING.getKey() + "] setting", e);
}
}
}

View File

@ -28,10 +28,6 @@ public class SlackService extends NotificationService<SlackAccount> {
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
Setting.simpleString("xpack.notification.slack.default_account", Property.Dynamic, Property.NodeScope);
private static final Setting.AffixSetting<String> SETTING_URL =
Setting.affixKeySetting("xpack.notification.slack.account.", "url",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered, Property.Deprecated));
private static final Setting.AffixSetting<SecureString> SETTING_URL_SECURE =
Setting.affixKeySetting("xpack.notification.slack.account.", "secure_url", (key) -> SecureSetting.secureString(key, null));
@ -48,7 +44,6 @@ public class SlackService extends NotificationService<SlackAccount> {
this.httpClient = httpClient;
// ensure logging of setting changes
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_URL, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_DEFAULTS, (s, o) -> {}, (s, o) -> {});
// do an initial load
reload(settings);
@ -56,11 +51,11 @@ public class SlackService extends NotificationService<SlackAccount> {
@Override
protected SlackAccount createAccount(String name, Settings accountSettings) {
return new SlackAccount(name, accountSettings, accountSettings, httpClient, logger);
return new SlackAccount(name, accountSettings, httpClient, logger);
}
private static List<Setting<?>> getDynamicSettings() {
return Arrays.asList(SETTING_URL, SETTING_DEFAULT_ACCOUNT, SETTING_DEFAULTS);
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_DEFAULTS);
}
private static List<Setting<?>> getSecureSettings() {

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.watcher.actions.email;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -82,13 +83,15 @@ public class EmailAttachmentTests extends AbstractWatcherIntegrationTestCase {
@Override
protected Settings nodeSettings(int nodeOrdinal) {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.email.account.test.smtp.secure_password", EmailServer.PASSWORD);
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("xpack.notification.email.account.test.smtp.auth", true)
.put("xpack.notification.email.account.test.smtp.user", EmailServer.USERNAME)
.put("xpack.notification.email.account.test.smtp.password", EmailServer.PASSWORD)
.put("xpack.notification.email.account.test.smtp.port", server.port())
.put("xpack.notification.email.account.test.smtp.host", "localhost")
.setSecureSettings(secureSettings)
.build();
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.watcher.actions.email;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
@ -42,12 +43,14 @@ public class EmailMessageIdTests extends ESTestCase {
public void startSmtpServer() {
server = EmailServer.localhost(logger);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.email.account.test.smtp.secure_password", EmailServer.PASSWORD);
Settings settings = Settings.builder()
.put("xpack.notification.email.account.test.smtp.auth", true)
.put("xpack.notification.email.account.test.smtp.user", EmailServer.USERNAME)
.put("xpack.notification.email.account.test.smtp.password", EmailServer.PASSWORD)
.put("xpack.notification.email.account.test.smtp.port", server.port())
.put("xpack.notification.email.account.test.smtp.host", "localhost")
.setSecureSettings(secureSettings)
.build();
Set<Setting<?>> registeredSettings = new HashSet<>(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.watcher.actions.jira;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.test.ESTestCase;
@ -63,11 +64,11 @@ public class ExecutableJiraActionTests extends ESTestCase {
final String user = randomAlphaOfLength(10);
final String password = randomAlphaOfLength(10);
Settings accountSettings = Settings.builder()
.put("url", url)
.put("user", user)
.put("password", password)
.build();
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(JiraAccount.SECURE_URL_SETTING.getKey(), url);
secureSettings.setString(JiraAccount.SECURE_USER_SETTING.getKey(), user);
secureSettings.setString(JiraAccount.SECURE_PASSWORD_SETTING.getKey(), password);
Settings accountSettings = Settings.builder().setSecureSettings(secureSettings).build();
JiraAccount account = new JiraAccount("account1", accountSettings, httpClient);
@ -259,10 +260,12 @@ public class ExecutableJiraActionTests extends ESTestCase {
}
private JiraAction.Simulated simulateExecution(Map<String, Object> actionFields, Map<String, String> accountFields) throws Exception {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(JiraAccount.SECURE_URL_SETTING.getKey(), "https://internal-jira.elastic.co:443");
secureSettings.setString(JiraAccount.SECURE_USER_SETTING.getKey(), "elastic");
secureSettings.setString(JiraAccount.SECURE_PASSWORD_SETTING.getKey(), "secret");
Settings.Builder settings = Settings.builder()
.put("url", "https://internal-jira.elastic.co:443")
.put("user", "elastic")
.put("password", "secret")
.setSecureSettings(secureSettings)
.putProperties(accountFields, s -> "issue_defaults." + s);
JiraAccount account = new JiraAccount("account", settings.build(), mock(HttpClient.class));

View File

@ -9,6 +9,7 @@ import org.apache.http.HttpStatus;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -216,10 +217,13 @@ public class JiraActionTests extends ESTestCase {
HttpClient httpClient = mock(HttpClient.class);
when(httpClient.execute(any(HttpRequest.class))).thenReturn(new HttpResponse(HttpStatus.SC_CREATED));
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("secure_url", "https://internal-jira.elastic.co:443");
secureSettings.setString("secure_user", "elastic");
secureSettings.setString("secure_password", "secret");
Settings.Builder settings = Settings.builder()
.put("url", "https://internal-jira.elastic.co:443")
.put("user", "elastic")
.put("password", "secret")
.setSecureSettings(secureSettings)
.put("issue_defaults.customfield_000", "foo")
.put("issue_defaults.customfield_001", "bar");

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.xpack.watcher.actions.slack;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext;
@ -40,8 +41,10 @@ public class ExecutableSlackActionTests extends ESTestCase {
ArgumentCaptor<HttpRequest> argumentCaptor = ArgumentCaptor.forClass(HttpRequest.class);
when(httpClient.execute(argumentCaptor.capture())).thenReturn(new HttpResponse(200));
Settings accountSettings = Settings.builder().put("url", "http://example.org").build();
SlackAccount account = new SlackAccount("account1", accountSettings, Settings.EMPTY, httpClient, logger);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("secure_url", "http://example.org");
Settings accountSettings = Settings.builder().setSecureSettings(secureSettings).build();
SlackAccount account = new SlackAccount("account1", accountSettings, httpClient, logger);
SlackService service = mock(SlackService.class);
when(service.getAccount(eq("account1"))).thenReturn(account);

View File

@ -16,6 +16,7 @@ import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.test.ESTestCase;
@ -121,7 +122,11 @@ public class HistoryStoreTests extends ESTestCase {
final String password = randomFrom("secret", "supersecret", "123456");
final String url = "https://" + randomFrom("localhost", "internal-jira.elastic.co") + ":" + randomFrom(80, 8080, 449, 9443);
Settings settings = Settings.builder().put("url", url).put("user", username).put("password", password).build();
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("secure_url", url);
secureSettings.setString("secure_user", username);
secureSettings.setString("secure_password", password);
Settings settings = Settings.builder().setSecureSettings(secureSettings).build();
JiraAccount account = new JiraAccount("_account", settings, httpClient);
JiraIssue jiraIssue = account.createIssue(singletonMap("foo", "bar"), null);

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.watcher.history;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
import org.elasticsearch.search.aggregations.Aggregations;
@ -52,16 +53,17 @@ public class HistoryTemplateEmailMappingsTests extends AbstractWatcherIntegratio
@Override
protected Settings nodeSettings(int nodeOrdinal) {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.email.account.test.smtp.secure_password", EmailServer.PASSWORD);
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
// email
.put("xpack.notification.email.account.test.smtp.auth", true)
.put("xpack.notification.email.account.test.smtp.user", EmailServer.USERNAME)
.put("xpack.notification.email.account.test.smtp.password", EmailServer.PASSWORD)
.put("xpack.notification.email.account.test.smtp.port", server.port())
.put("xpack.notification.email.account.test.smtp.host", "localhost")
.setSecureSettings(secureSettings)
.build();
}

View File

@ -116,8 +116,9 @@ public class AccountTests extends ESTestCase {
String password = null;
if (randomBoolean()) {
password = randomAlphaOfLength(8);
smtpBuilder.put("password", password);
smtpProps.put("mail.smtp.password", password);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("smtp." + Account.SECURE_PASSWORD_SETTING.getKey(), password);
builder.setSecureSettings(secureSettings);
}
for (int i = 0; i < 5; i++) {
String name = randomAlphaOfLength(5);
@ -157,11 +158,13 @@ public class AccountTests extends ESTestCase {
}
public void testSend() throws Exception {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("smtp." + Account.SECURE_PASSWORD_SETTING.getKey(), EmailServer.PASSWORD);
Account account = new Account(new Account.Config("default", Settings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", server.port())
.put("smtp.user", EmailServer.USERNAME)
.put("smtp.password", EmailServer.PASSWORD)
.setSecureSettings(secureSettings)
.build()), null, logger);
Email email = Email.builder()
@ -192,11 +195,13 @@ public class AccountTests extends ESTestCase {
}
public void testSendCCAndBCC() throws Exception {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("smtp." + Account.SECURE_PASSWORD_SETTING.getKey(), EmailServer.PASSWORD);
Account account = new Account(new Account.Config("default", Settings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", server.port())
.put("smtp.user", EmailServer.USERNAME)
.put("smtp.password", EmailServer.PASSWORD)
.setSecureSettings(secureSettings)
.build()), null, logger);
Email email = Email.builder()
@ -293,29 +298,4 @@ public class AccountTests extends ESTestCase {
});
}
public void testEnsurePasswordSetAsSecureSetting() {
String password = "password";
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("smtp.secure_password", password);
Settings settings = Settings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", server.port())
.put("smtp.connection_timeout", TimeValue.timeValueMinutes(4))
.setSecureSettings(secureSettings)
.build();
Account.Config config = new Account.Config("default", settings);
assertThat(config.smtp.password.getChars(), equalTo(password.toCharArray()));
settings = Settings.builder()
.put("smtp.host", "localhost")
.put("smtp.port", server.port())
.put("smtp.connection_timeout", TimeValue.timeValueMinutes(4))
.put("smtp.password", password)
.build();
config = new Account.Config("default", settings);
assertThat(config.smtp.password.getChars(), equalTo(password.toCharArray()));
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.watcher.notification.hipchat;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
@ -50,9 +51,11 @@ public class HipChatAccountsTests extends ESTestCase {
}
private void addAccountSettings(String name, Settings.Builder builder) {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.hipchat.account." + name + ".secure_auth_token", randomAlphaOfLength(50));
HipChatAccount.Profile profile = randomFrom(HipChatAccount.Profile.values());
builder.put("xpack.notification.hipchat.account." + name + ".profile", profile.value());
builder.put("xpack.notification.hipchat.account." + name + ".auth_token", randomAlphaOfLength(50));
builder.setSecureSettings(secureSettings);
if (profile == HipChatAccount.Profile.INTEGRATION) {
builder.put("xpack.notification.hipchat.account." + name + ".room", randomAlphaOfLength(10));
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.watcher.notification.hipchat;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.test.ESTestCase;
@ -40,9 +41,11 @@ public class HipChatServiceTests extends ESTestCase {
HipChatMessage.Color defaultColor = randomBoolean() ? null : randomFrom(HipChatMessage.Color.values());
HipChatMessage.Format defaultFormat = randomBoolean() ? null : randomFrom(HipChatMessage.Format.values());
Boolean defaultNotify = randomBoolean() ? null : (Boolean) randomBoolean();
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
Settings.Builder settingsBuilder = Settings.builder()
.put("xpack.notification.hipchat.account." + accountName + ".profile", HipChatAccount.Profile.V1.value())
.put("xpack.notification.hipchat.account." + accountName + ".auth_token", "_token");
.setSecureSettings(secureSettings);
if (host != null) {
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".host", host);
}
@ -86,10 +89,12 @@ public class HipChatServiceTests extends ESTestCase {
HipChatMessage.Color defaultColor = randomBoolean() ? null : randomFrom(HipChatMessage.Color.values());
HipChatMessage.Format defaultFormat = randomBoolean() ? null : randomFrom(HipChatMessage.Format.values());
Boolean defaultNotify = randomBoolean() ? null : (Boolean) randomBoolean();
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
Settings.Builder settingsBuilder = Settings.builder()
.put("xpack.notification.hipchat.account." + accountName + ".profile",
HipChatAccount.Profile.INTEGRATION.value())
.put("xpack.notification.hipchat.account." + accountName + ".auth_token", "_token")
.setSecureSettings(secureSettings)
.put("xpack.notification.hipchat.account." + accountName + ".room", room);
if (host != null) {
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".host", host);
@ -122,10 +127,12 @@ public class HipChatServiceTests extends ESTestCase {
public void testSingleAccountIntegrationNoRoomSetting() throws Exception {
String accountName = randomAlphaOfLength(10);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
Settings.Builder settingsBuilder = Settings.builder()
.put("xpack.notification.hipchat.account." + accountName + ".profile",
HipChatAccount.Profile.INTEGRATION.value())
.put("xpack.notification.hipchat.account." + accountName + ".auth_token", "_token");
.setSecureSettings(secureSettings);
SettingsException e = expectThrows(SettingsException.class, () ->
new HipChatService(settingsBuilder.build(), httpClient,
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings()))).getAccount(null));
@ -141,9 +148,12 @@ public class HipChatServiceTests extends ESTestCase {
HipChatMessage.Color defaultColor = randomBoolean() ? null : randomFrom(HipChatMessage.Color.values());
HipChatMessage.Format defaultFormat = randomBoolean() ? null : randomFrom(HipChatMessage.Format.values());
Boolean defaultNotify = randomBoolean() ? null : (Boolean) randomBoolean();
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
Settings.Builder settingsBuilder = Settings.builder()
.put("xpack.notification.hipchat.account." + accountName + ".profile", HipChatAccount.Profile.USER.value())
.put("xpack.notification.hipchat.account." + accountName + ".auth_token", "_token");
.setSecureSettings(secureSettings);
if (host != null) {
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".host", host);
}
@ -189,6 +199,8 @@ public class HipChatServiceTests extends ESTestCase {
Settings.Builder settingsBuilder = Settings.builder();
String defaultAccount = "_a" + randomIntBetween(0, 4);
settingsBuilder.put("xpack.notification.hipchat.default_account", defaultAccount);
final MockSecureSettings secureSettings = new MockSecureSettings();
settingsBuilder.setSecureSettings(secureSettings);
final boolean customGlobalServer = randomBoolean();
if (customGlobalServer) {
@ -201,7 +213,7 @@ public class HipChatServiceTests extends ESTestCase {
String prefix = "xpack.notification.hipchat.account." + name;
HipChatAccount.Profile profile = randomFrom(HipChatAccount.Profile.values());
settingsBuilder.put(prefix + ".profile", profile);
settingsBuilder.put(prefix + ".auth_token", "_token" + i);
secureSettings.setString(prefix + ".secure_auth_token", "_token" + i);
if (profile == HipChatAccount.Profile.INTEGRATION) {
settingsBuilder.put(prefix + ".room", "_room" + i);
}

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.watcher.notification.hipchat;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.xcontent.ToXContent;
@ -36,7 +37,9 @@ public class IntegrationAccountTests extends ESTestCase {
Settings.Builder sb = Settings.builder();
String authToken = randomAlphaOfLength(50);
sb.put(IntegrationAccount.AUTH_TOKEN_SETTING, authToken);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
sb.setSecureSettings(secureSettings);
String host = HipChatServer.DEFAULT.host();
if (randomBoolean()) {
@ -90,13 +93,16 @@ public class IntegrationAccountTests extends ESTestCase {
new IntegrationAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), is("hipchat account [_name] missing required [auth_token] setting"));
assertThat(e.getMessage(), is("hipchat account [_name] missing required [secure_auth_token] secure setting"));
}
}
public void testSettingsWithoutRoom() throws Exception {
Settings.Builder sb = Settings.builder();
sb.put(IntegrationAccount.AUTH_TOKEN_SETTING, randomAlphaOfLength(50));
String authToken = randomAlphaOfLength(50);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
sb.setSecureSettings(secureSettings);
try {
new IntegrationAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
fail("Expected SettingsException");
@ -107,7 +113,10 @@ public class IntegrationAccountTests extends ESTestCase {
public void testSettingsWithoutMultipleRooms() throws Exception {
Settings.Builder sb = Settings.builder();
sb.put(IntegrationAccount.AUTH_TOKEN_SETTING, randomAlphaOfLength(50));
String authToken = randomAlphaOfLength(50);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
sb.setSecureSettings(secureSettings);
sb.put(IntegrationAccount.ROOM_SETTING, "_r1,_r2");
try {
new IntegrationAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
@ -121,10 +130,12 @@ public class IntegrationAccountTests extends ESTestCase {
String token = randomAlphaOfLength(10);
HttpClient httpClient = mock(HttpClient.class);
String room = "Room with Spaces";
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), token);
IntegrationAccount account = new IntegrationAccount("_name", Settings.builder()
.put("host", "_host")
.put("port", "443")
.put("auth_token", token)
.setSecureSettings(secureSettings)
.put("room", room)
.build(), HipChatServer.DEFAULT, httpClient, mock(Logger.class));

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.watcher.notification.hipchat;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.test.ESTestCase;
@ -43,7 +44,9 @@ public class UserAccountTests extends ESTestCase {
Settings.Builder sb = Settings.builder();
String authToken = randomAlphaOfLength(50);
sb.put(UserAccount.AUTH_TOKEN_SETTING, authToken);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(UserAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
sb.setSecureSettings(secureSettings);
String host = HipChatServer.DEFAULT.host();
if (randomBoolean()) {
@ -111,16 +114,18 @@ public class UserAccountTests extends ESTestCase {
new UserAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), is("hipchat account [_name] missing required [auth_token] setting"));
assertThat(e.getMessage(), is("hipchat account [_name] missing required [secure_auth_token] secure setting"));
}
}
public void testSend() throws Exception {
HttpClient httpClient = mock(HttpClient.class);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "_token");
UserAccount account = new UserAccount("_name", Settings.builder()
.put("host", "_host")
.put("port", "443")
.put("auth_token", "_token")
.setSecureSettings(secureSettings)
.build(), HipChatServer.DEFAULT, httpClient, mock(Logger.class));
HipChatMessage.Format format = randomFrom(HipChatMessage.Format.values());
@ -240,9 +245,11 @@ public class UserAccountTests extends ESTestCase {
}
public void testColorIsOptional() throws Exception {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "awesome-auth-token");
Settings settings = Settings.builder()
.put("user", "testuser")
.put("auth_token", "awesome-auth-token")
.setSecureSettings(secureSettings)
.build();
UserAccount userAccount = createUserAccount(settings);
@ -256,9 +263,11 @@ public class UserAccountTests extends ESTestCase {
}
public void testFormatIsOptional() throws Exception {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "awesome-auth-token");
Settings settings = Settings.builder()
.put("user", "testuser")
.put("auth_token", "awesome-auth-token")
.setSecureSettings(secureSettings)
.build();
UserAccount userAccount = createUserAccount(settings);
@ -272,9 +281,11 @@ public class UserAccountTests extends ESTestCase {
}
public void testRoomNameIsUrlEncoded() throws Exception {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "awesome-auth-token");
Settings settings = Settings.builder()
.put("user", "testuser")
.put("auth_token", "awesome-auth-token")
.setSecureSettings(secureSettings)
.build();
HipChatServer hipChatServer = mock(HipChatServer.class);
HttpClient httpClient = mock(HttpClient.class);

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.watcher.notification.hipchat;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.test.ESTestCase;
@ -32,7 +33,9 @@ public class V1AccountTests extends ESTestCase {
Settings.Builder sb = Settings.builder();
String authToken = randomAlphaOfLength(50);
sb.put(V1Account.AUTH_TOKEN_SETTING, authToken);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(V1Account.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
sb.setSecureSettings(secureSettings);
String host = HipChatServer.DEFAULT.host();
if (randomBoolean()) {
@ -96,16 +99,19 @@ public class V1AccountTests extends ESTestCase {
new V1Account("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), is("hipchat account [_name] missing required [auth_token] setting"));
assertThat(e.getMessage(), is("hipchat account [_name] missing required [secure_auth_token] secure setting"));
}
}
public void testSend() throws Exception {
HttpClient httpClient = mock(HttpClient.class);
String authToken = randomAlphaOfLength(50);
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "_token");
V1Account account = new V1Account("_name", Settings.builder()
.put("host", "_host")
.put("port", "443")
.put("auth_token", "_token")
.setSecureSettings(secureSettings)
.build(), HipChatServer.DEFAULT, httpClient, mock(Logger.class));
HipChatMessage.Format format = randomFrom(HipChatMessage.Format.values());

View File

@ -9,6 +9,7 @@ import org.apache.http.HttpStatus;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.test.ESTestCase;
@ -53,29 +54,38 @@ public class JiraAccountTests extends ESTestCase {
public void testJiraAccountSettings() {
final String url = "https://internal-jira.elastic.co:443";
final MockSecureSettings secureSettings = new MockSecureSettings();
SettingsException e = expectThrows(SettingsException.class, () -> new JiraAccount(null, Settings.EMPTY, null));
assertThat(e.getMessage(), containsString("invalid jira [null] account settings. missing required [url] setting"));
assertThat(e.getMessage(), containsString("invalid jira [null] account settings. missing required [secure_url] setting"));
Settings settings1 = Settings.builder().put("url", url).build();
secureSettings.setString("secure_url", url);
Settings settings1 = Settings.builder().setSecureSettings(secureSettings).build();
e = expectThrows(SettingsException.class, () -> new JiraAccount("test", settings1, null));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [user] setting"));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [secure_user] setting"));
Settings settings2 = Settings.builder().put("url", url).put("user", "").build();
secureSettings.setString("secure_user", "");
Settings settings2 = Settings.builder().setSecureSettings(secureSettings).build();
e = expectThrows(SettingsException.class, () -> new JiraAccount("test", settings2, null));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [user] setting"));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [secure_user] setting"));
Settings settings3 = Settings.builder().put("url", url).put("user", "foo").build();
secureSettings.setString("secure_user", "foo");
Settings settings3 = Settings.builder().setSecureSettings(secureSettings).build();
e = expectThrows(SettingsException.class, () -> new JiraAccount("test", settings3, null));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [password] setting"));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [secure_password] setting"));
Settings settings4 = Settings.builder().put("url", url).put("user", "foo").put("password", "").build();
secureSettings.setString("secure_password", "");
Settings settings4 = Settings.builder().setSecureSettings(secureSettings).build();
e = expectThrows(SettingsException.class, () -> new JiraAccount("test", settings4, null));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [password] setting"));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. missing required [secure_password] setting"));
}
public void testUnsecureAccountUrl() throws Exception {
Settings settings = Settings.builder().put("url", "http://localhost").put("user", "foo").put("password", "bar").build();
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(JiraAccount.SECURE_USER_SETTING.getKey(), "foo");
secureSettings.setString(JiraAccount.SECURE_PASSWORD_SETTING.getKey(), "password");
secureSettings.setString(JiraAccount.SECURE_URL_SETTING.getKey(), "http://localhost");
Settings settings = Settings.builder().setSecureSettings(secureSettings).build();
SettingsException e = expectThrows(SettingsException.class, () -> new JiraAccount("test", settings, null));
assertThat(e.getMessage(), containsString("invalid jira [test] account settings. unsecure scheme [HTTP]"));
@ -128,15 +138,19 @@ public class JiraAccountTests extends ESTestCase {
}
public void testCustomUrls() throws Exception {
assertCustomUrl(Settings.builder().put("url", "https://localhost/foo").build(), "/foo");
assertCustomUrl(Settings.builder().put("url", "https://localhost/foo/").build(), "/foo/");
assertCustomUrl("https://localhost/foo", "/foo");
assertCustomUrl("https://localhost/foo/", "/foo/");
// this ensures we retain backwards compatibility
assertCustomUrl(Settings.builder().put("url", "https://localhost/").build(), JiraAccount.DEFAULT_PATH);
assertCustomUrl(Settings.builder().put("url", "https://localhost").build(), JiraAccount.DEFAULT_PATH);
assertCustomUrl("https://localhost/", JiraAccount.DEFAULT_PATH);
assertCustomUrl("https://localhost", JiraAccount.DEFAULT_PATH);
}
private void assertCustomUrl(Settings urlSettings, String expectedPath) throws IOException {
Settings settings = Settings.builder().put(urlSettings).put("user", "foo").put("password", "bar").build();
private void assertCustomUrl(String urlSettings, String expectedPath) throws IOException {
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("secure_url", urlSettings);
secureSettings.setString("secure_user", "foo");
secureSettings.setString("secure_password", "bar");
Settings settings = Settings.builder().setSecureSettings(secureSettings).build();
HttpClient client = mock(HttpClient.class);
HttpResponse response = new HttpResponse(200);
@ -153,9 +167,14 @@ public class JiraAccountTests extends ESTestCase {
}
private void addAccountSettings(String name, Settings.Builder builder) {
builder.put("xpack.notification.jira.account." + name + "." + JiraAccount.URL_SETTING, "https://internal-jira.elastic.co:443");
builder.put("xpack.notification.jira.account." + name + "." + JiraAccount.USER_SETTING, randomAlphaOfLength(10));
builder.put("xpack.notification.jira.account." + name + "." + JiraAccount.PASSWORD_SETTING, randomAlphaOfLength(10));
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("xpack.notification.jira.account." + name + "." + JiraAccount.SECURE_URL_SETTING.getKey(),
"https://internal-jira.elastic.co:443");
secureSettings.setString("xpack.notification.jira.account." + name + "." + JiraAccount.SECURE_USER_SETTING.getKey(),
randomAlphaOfLength(10));
secureSettings.setString("xpack.notification.jira.account." + name + "." + JiraAccount.SECURE_PASSWORD_SETTING.getKey(),
randomAlphaOfLength(10));
builder.setSecureSettings(secureSettings);
Map<String, Object> defaults = randomIssueDefaults();
for (Map.Entry<String, Object> setting : defaults.entrySet()) {

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.watcher.notification.pagerduty;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.MockSecureSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.test.ESTestCase;
@ -83,7 +84,11 @@ public class PagerDutyAccountsTests extends ESTestCase {
}
private void addAccountSettings(String name, Settings.Builder builder) {
builder.put("xpack.notification.pagerduty.account." + name + ".service_api_key", randomAlphaOfLength(50));
final MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString(
"xpack.notification.pagerduty.account." + name + "." + PagerDutyAccount.SECURE_SERVICE_API_KEY_SETTING.getKey(),
randomAlphaOfLength(50));
builder.setSecureSettings(secureSettings);
Settings defaults = SlackMessageDefaultsTests.randomSettings();
for (String setting : defaults.keySet()) {
builder.copy("xpack.notification.pagerduty.message_defaults." + setting, setting, defaults);

View File

@ -22,7 +22,7 @@ integTestCluster {
setting 'xpack.notification.email.account._email.smtp.host', 'host.domain'
setting 'xpack.notification.email.account._email.smtp.port', '587'
setting 'xpack.notification.email.account._email.smtp.user', '_user'
setting 'xpack.notification.email.account._email.smtp.password', '_passwd'
keystoreSetting 'xpack.notification.email.account._email.smtp.secure_password', '_passwd'
setting 'xpack.license.self_generated.type', 'trial'
extraConfigFile 'roles.yml', 'roles.yml'
setupCommand 'setupTestAdminUser',