Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NMS-15759: Allow metadata for notification credentials #6597

Merged
merged 9 commits into from
Sep 1, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,17 @@ Generates xref:operation:deep-dive/notifications/introduction.adoc[notifications
| no

| javamail-configuration.properties
| Configuration to send notification mails via specific mail servers.
| Configuration to send notification mails via specific mail servers. Metadata expression can be used for the authenticateUser and authenticatePassword fields in order to reference credentials stored in the secure credentials vault.
christianpape marked this conversation as resolved.
Show resolved Hide resolved
| no
| no

| microblog-configuration.properties
| Configuration to send notification mails via specific mail servers. Metadata expression can be used for the authen-* and oauth-* fields in order to reference credentials stored in the secure credentials vault.
christianpape marked this conversation as resolved.
Show resolved Hide resolved
| no
| no

| xmpp-configuration.properties
| Configuration to send notification mails via specific mail servers. Metadata expression can be used for the xmpp.user and xmpp.pass fields in order to reference credentials stored in the secure credentials vault.
christianpape marked this conversation as resolved.
Show resolved Hide resolved
| no
| no
|===
Expand Down
4 changes: 4 additions & 0 deletions opennms-ackd/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,9 @@
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opennms.core.mate</groupId>
<artifactId>org.opennms.core.mate.model</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,24 @@

package org.opennms.netmgt.ackd.readers;

import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.junit.Assert;

import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -60,7 +54,6 @@
import org.opennms.core.test.db.annotations.JUnitTemporaryDatabase;
import org.opennms.javamail.JavaMailerException;
import org.opennms.javamail.JavaSendMailer;
import org.opennms.netmgt.ackd.AckReader;
import org.opennms.netmgt.ackd.Ackd;
import org.opennms.netmgt.config.ackd.AckdConfiguration;
import org.opennms.netmgt.config.javamail.End2endMailConfig;
Expand Down
5 changes: 5 additions & 0 deletions opennms-javamail/opennms-javamail-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@
<groupId>org.opennms.core.test-api</groupId>
<artifactId>org.opennms.core.test-api.lib</artifactId>
</dependency>
<dependency>
<groupId>org.opennms.core.mate</groupId>
<artifactId>org.opennms.core.mate.api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public Authenticator createAuthenticator(final String user, final String passwor
auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
return new PasswordAuthentication(JavaMailerConfig.interpolate(user), JavaMailerConfig.interpolate(password));
}
};
return auth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,14 @@
import java.io.InputStream;
import java.util.Properties;

import org.opennms.core.mate.api.EntityScopeProvider;
import org.opennms.core.mate.api.Interpolator;
import org.opennms.core.mate.api.Scope;
import org.opennms.core.spring.BeanUtils;
import org.opennms.core.utils.ConfigFileConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.FatalBeanException;

/**
* Provides access to the default javamail configuration data.
Expand All @@ -45,22 +50,79 @@ public abstract class JavaMailerConfig {

private static final Logger LOG = LoggerFactory.getLogger(JavaMailerConfig.class);

private static Scope secureCredentialsVaultScope;

private static synchronized Scope getSecureCredentialsScope() {
if (secureCredentialsVaultScope == null) {
try {
final EntityScopeProvider entityScopeProvider = BeanUtils.getBean("daoContext", "entityScopeProvider", EntityScopeProvider.class);

if (entityScopeProvider != null) {
secureCredentialsVaultScope = entityScopeProvider.getScopeForScv();
} else {
LOG.warn("JavaMailConfig: EntityScopeProvider is null, SecureCredentialsVault not available for metadata interpolation");
}
} catch (FatalBeanException e) {
e.printStackTrace();
LOG.warn("JavaMailConfig: Error retrieving EntityScopeProvider bean");
}
}

return secureCredentialsVaultScope;
}

public static void setSecureCredentialsVaultScope(final Scope secureCredentialsVaultScope) {
JavaMailerConfig.secureCredentialsVaultScope = secureCredentialsVaultScope;
}


/**
* This loads the configuration file.
*
* @return a Properties object representing the configuration properties
* @throws java.io.IOException if any.
*/
public static synchronized Properties getProperties() throws IOException {
LOG.debug("Loading javamail properties.");
LOG.debug("JavaMailConfig: Loading javamail properties");
Properties properties = new Properties();
File configFile = ConfigFileConstants.getFile(ConfigFileConstants.JAVA_MAIL_CONFIG_FILE_NAME);
InputStream in = new FileInputStream(configFile);
properties.load(in);
in.close();
return interpolate(properties);
}

private static Properties interpolate(final Properties properties, final String key, final Scope scope) {
final String value = properties.getProperty(key);

if (value != null) {
properties.put(key, Interpolator.interpolate(value, scope).output);
}

return properties;
}

private static Properties interpolate(final Properties properties) {
final Scope scope = getSecureCredentialsScope();

if (scope == null) {
LOG.warn("JavaMailConfig: Scope is null, cannot interpolate metadata of properties");
return properties;
}

interpolate(properties, "org.opennms.core.utils.authenticateUser", scope);
interpolate(properties, "org.opennms.core.utils.authenticatePassword", scope);

return properties;
}

public static String interpolate(final String string) {
final Scope scope = getSecureCredentialsScope();

if (scope == null) {
LOG.warn("JavaMailConfig: Scope is null, cannot interpolate metadata of string");
return string;
}

return Interpolator.interpolate(string, scope).output;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public Authenticator createAuthenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
if (m_config.getUserAuth() != null) {
final UserAuth userAuth = m_config.getUserAuth();
return new PasswordAuthentication(userAuth.getUserName(), userAuth.getPassword());
return new PasswordAuthentication(JavaMailerConfig.interpolate(userAuth.getUserName()), JavaMailerConfig.interpolate(userAuth.getPassword()));
}
LOG.debug("No user authentication configured.");
return new PasswordAuthentication(null,null);
Expand Down Expand Up @@ -362,7 +362,7 @@ public void send(MimeMessage message) throws JavaMailerException {
if (m_config.isUseAuthentication() && m_config.getUserAuth() != null) {
LOG.debug("authenticating to {}", sendmailHost.getHost());
final UserAuth userAuth = m_config.getUserAuth();
t.connect(sendmailHost.getHost(), sendmailHost.getPort(), userAuth.getUserName(), userAuth.getPassword());
t.connect(sendmailHost.getHost(), sendmailHost.getPort(), JavaMailerConfig.interpolate(userAuth.getUserName()), JavaMailerConfig.interpolate(userAuth.getPassword()));
} else {
LOG.debug("not authenticating to {}", sendmailHost.getHost());
t.connect(sendmailHost.getHost(), sendmailHost.getPort(), null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,23 @@

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.mail.Message;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opennms.core.mate.api.ContextKey;
import org.opennms.core.mate.api.MapScope;
import org.opennms.core.mate.api.Scope;
import org.opennms.core.test.MockLogAppender;
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.test.ThrowableAnticipator;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.test.annotation.IfProfileValue;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

Expand All @@ -70,6 +72,12 @@ public void setUp() throws IOException {
System.out.println("homeDir: "+homeDir.getAbsolutePath());

System.setProperty("opennms.home", homeDir.getAbsolutePath());

final Map<ContextKey, String> map = new HashMap<>();
map.put(new ContextKey("scv","javamailer:username"), "john");
map.put(new ContextKey("scv","javamailer:password"), "doe");

JavaMailerConfig.setSecureCredentialsVaultScope(new MapScope(Scope.ScopeName.GLOBAL, map));
}

@After
Expand Down Expand Up @@ -133,4 +141,11 @@ public void testNullReplyTo() throws Exception {
assertEquals(1, message.getReplyTo().length);
assertEquals("test@opennms.org", jm.buildMessage().getReplyTo()[0].toString());
}

@Test
public void testMetadata() throws Exception {
final JavaMailer jm = new JavaMailer();
assertEquals("john", jm.getUser());
assertEquals("doe", jm.getPassword());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,30 @@

package org.opennms.javamail;

import java.io.IOException;
import static org.junit.Assert.assertEquals;

import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.mail.Authenticator;
import javax.mail.Flags.Flag;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Flags.Flag;
import javax.mail.PasswordAuthentication;
import javax.mail.search.OrTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SubjectTerm;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.opennms.core.mate.api.ContextKey;
import org.opennms.core.mate.api.MapScope;
import org.opennms.core.mate.api.Scope;
import org.opennms.netmgt.config.javamail.ReadmailConfig;
import org.opennms.netmgt.config.javamail.ReadmailHost;
import org.opennms.netmgt.config.javamail.ReadmailProtocol;
Expand All @@ -52,7 +62,16 @@
import org.opennms.netmgt.config.javamail.UserAuth;

public class JavaReadMailerTest {


@Before
public void setup() {
final Map<ContextKey, String> map = new HashMap<>();
map.put(new ContextKey("scv","javamailer:username"), "john");
map.put(new ContextKey("scv","javamailer:password"), "doe");

JavaMailerConfig.setSecureCredentialsVaultScope(new MapScope(Scope.ScopeName.GLOBAL, map));
}

/**
* Un-ignore this test with a proper gmail account
* @throws JavaMailerException
Expand Down Expand Up @@ -100,7 +119,7 @@ public void testReadMessagesWithSearchTerm() throws JavaMailerException, Messagi
e.printStackTrace();
}

Assert.assertEquals(3, msgs.size());
assertEquals(3, msgs.size());

st = new OrTerm(new SubjectTerm(".*"+term1+" #.*"), new SubjectTerm(".*"+term2+" #.*"));

Expand All @@ -112,7 +131,7 @@ public void testReadMessagesWithSearchTerm() throws JavaMailerException, Messagi

//Should find only term1 and term2 messages
Assert.assertNotNull(msgs);
Assert.assertEquals(2, msgs.size());
assertEquals(2, msgs.size());

//Now cleanup
//Delete the term1 and term2 messages
Expand Down Expand Up @@ -222,5 +241,16 @@ private JavaReadMailer createGoogleReadMailer(String gmailAccount, String gmailP
return mailer;
}

@Test
public void testMetadata() throws Exception {
final JavaReadMailer javaReadMailer = createGoogleReadMailer(null, null);

Authenticator authenticator = javaReadMailer.createAuthenticator("${scv:javamailer:username|ABC}", "${scv:javamailer:password|DEF}");
final Method method = authenticator.getClass().getDeclaredMethod("getPasswordAuthentication");
method.setAccessible(true);
final PasswordAuthentication passwordAuthentication = (PasswordAuthentication) method.invoke(authenticator);

assertEquals("john", passwordAuthentication.getUserName());
assertEquals("doe", passwordAuthentication.getPassword());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,19 @@

import static org.junit.Assert.assertEquals;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.internet.MimeMessage;

import org.junit.Before;
import org.junit.Test;
import org.opennms.core.mate.api.ContextKey;
import org.opennms.core.mate.api.MapScope;
import org.opennms.core.mate.api.Scope;
import org.opennms.netmgt.config.javamail.SendmailConfig;
import org.opennms.netmgt.config.javamail.SendmailHost;
import org.opennms.netmgt.config.javamail.SendmailProtocol;
Expand All @@ -41,6 +51,15 @@

public class JavaSendMailerTest {

@Before
public void setup() {
final Map<ContextKey, String> map = new HashMap<>();
map.put(new ContextKey("scv","javamailer:username"), "john");
map.put(new ContextKey("scv","javamailer:password"), "doe");

JavaMailerConfig.setSecureCredentialsVaultScope(new MapScope(Scope.ScopeName.GLOBAL, map));
}

private JavaSendMailer createSendMailer() throws JavaMailerException {

SendmailConfig config = new SendmailConfig();
Expand Down Expand Up @@ -126,4 +145,17 @@ public void testNullReplyTo() throws Exception {
assertEquals(1, mimeMessage.getReplyTo().length);
assertEquals("root@foo.bar.com", mimeMessage.getReplyTo()[0].toString());
}

@Test
public void testMetadata() throws Exception {
final JavaSendMailer javaSendMailer = createSendMailer();

Authenticator authenticator = javaSendMailer.createAuthenticator("${scv:javamailer:username|ABC}", "${scv:javamailer:password|DEF}");
final Method method = authenticator.getClass().getDeclaredMethod("getPasswordAuthentication");
method.setAccessible(true);
final PasswordAuthentication passwordAuthentication = (PasswordAuthentication) method.invoke(authenticator);

assertEquals("john", passwordAuthentication.getUserName());
assertEquals("doe", passwordAuthentication.getPassword());
}
}
Loading