diff --git a/de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/MailConfigTest.java b/de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/MailConfigTest.java index 568134d..a6ebcaa 100644 --- a/de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/MailConfigTest.java +++ b/de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/MailConfigTest.java @@ -8,12 +8,14 @@ import static org.junit.jupiter.api.Assertions.*; import jakarta.mail.Authenticator; import jakarta.mail.PasswordAuthentication; import java.lang.reflect.InvocationTargetException; +import java.sql.SQLException; import java.util.Map; import java.util.Random; import org.junit.jupiter.api.Test; public abstract class MailConfigTest { protected abstract MailConfig mailConfig(); + protected abstract void reOpen(); @Test public void testSmtpHost() { @@ -151,4 +153,42 @@ public abstract class MailConfigTest { assertEquals(password, pwa.getPassword()); assertEquals(address, pwa.getUserName()); } + + @Test + public void testSave() throws SQLException { + var host = uuid(); + var port = new Random().nextInt(); + var address = uuid(); + var password = uuid(); + + mailConfig().senderPassword(password); + mailConfig().senderAddress(address); + mailConfig().smtpHost(host); + mailConfig().smtpPort(port); + mailConfig().startTls(true); + mailConfig().smtpAuth(false); + mailConfig().save(); + reOpen(); + + var map = mailConfig().map(); + assertEquals(map, Map.of( // + SMTP_HOST, host, // + SMTP_PORT, port, // + SMTP_AUTH, false, // + SMTP_USER, address, // + START_TLS, true)); + + mailConfig().startTls(false); + mailConfig().smtpAuth(true); + mailConfig().save(); + reOpen(); + + map = mailConfig().map(); + assertEquals(map, Map.of( // + SMTP_HOST, host, // + SMTP_PORT, port, // + SMTP_AUTH, true, // + SMTP_USER, address, // + START_TLS, false)); + } } diff --git a/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java b/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java index d5fd0ea..3c742ca 100644 --- a/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java +++ b/de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java @@ -108,7 +108,7 @@ public class Application { }; } - private static MailConfig setupMailConfig(Configuration config, Path defaultFile, FileStoreProvider fileStoreProvider) { + private static MailConfig setupMailConfig(Configuration config, Path defaultFile, FileStoreProvider fileStoreProvider) throws SQLException { var mailConfigLocation = new File(config.getOrDefault("mail_config_storage",defaultFile)); return switch (extension(mailConfigLocation)){ case "db", "sqlite", "sqlite3" -> new SqliteMailConfig(connectionProvider.get(mailConfigLocation)); diff --git a/de.srsoftware.oidc.datastore.file/src/test/java/de/srsoftware/oidc/datastore/file/FileStoreMailConfigTest.java b/de.srsoftware.oidc.datastore.file/src/test/java/de/srsoftware/oidc/datastore/file/FileStoreMailConfigTest.java index efdadab..31f170e 100644 --- a/de.srsoftware.oidc.datastore.file/src/test/java/de/srsoftware/oidc/datastore/file/FileStoreMailConfigTest.java +++ b/de.srsoftware.oidc.datastore.file/src/test/java/de/srsoftware/oidc/datastore/file/FileStoreMailConfigTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.BeforeEach; public class FileStoreMailConfigTest extends MailConfigTest { private MailConfig mailConfig; + private File storage; @Override @@ -20,9 +21,18 @@ public class FileStoreMailConfigTest extends MailConfigTest { return mailConfig; } + @Override + protected void reOpen() { + try { + mailConfig = new FileStore(storage, null); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @BeforeEach public void setup() throws IOException { - var storage = new File("/tmp/" + UUID.randomUUID()); + storage = new File("/tmp/" + UUID.randomUUID()); if (storage.exists()) storage.delete(); mailConfig = new FileStore(storage, null); } diff --git a/de.srsoftware.oidc.datastore.sqlite/src/main/java/de/srsoftware/oidc/datastore/sqlite/SqliteMailConfig.java b/de.srsoftware.oidc.datastore.sqlite/src/main/java/de/srsoftware/oidc/datastore/sqlite/SqliteMailConfig.java index 73bb417..37da680 100644 --- a/de.srsoftware.oidc.datastore.sqlite/src/main/java/de/srsoftware/oidc/datastore/sqlite/SqliteMailConfig.java +++ b/de.srsoftware.oidc.datastore.sqlite/src/main/java/de/srsoftware/oidc/datastore/sqlite/SqliteMailConfig.java @@ -1,71 +1,183 @@ /* © SRSoftware 2024 */ package de.srsoftware.oidc.datastore.sqlite; +import static de.srsoftware.oidc.api.Constants.*; + import de.srsoftware.oidc.api.MailConfig; import jakarta.mail.Authenticator; +import jakarta.mail.PasswordAuthentication; import java.sql.Connection; +import java.sql.SQLException; -public class SqliteMailConfig implements MailConfig { - public SqliteMailConfig(Connection connection) { - } +public class SqliteMailConfig extends SqliteStore implements MailConfig { + private static final String STORE_VERSION = "mail_config_store_version"; + private static final String CREATE_STORE_VERSION = "INSERT INTO metainfo (key,value) VALUES ('" + STORE_VERSION + "','0')"; + private static final String SELECT_STORE_VERSION = "SELECT * FROM metainfo WHERE key = '" + STORE_VERSION + "'"; + private static final String SET_STORE_VERSION = "UPDATE metainfo SET value = ? WHERE key = '" + STORE_VERSION + "'"; + private static final String CREATE_MAIL_CONFIG_TABLE = "CREATE TABLE mail_config (key VARCHAR(64) PRIMARY KEY, value VARCHAR(255));"; + private static final String SAVE_MAILCONFIG = "INSERT INTO mail_config (key, value) VALUES (?, ?) ON CONFLICT DO UPDATE SET value = ?"; + private static final String SELECT_MAILCONFIG = "SELECT * FROM mail_config"; + private String smtpHost, senderAddress, password; - @Override - public String smtpHost() { - return ""; - } + private int smtpPort; + private boolean smtpAuth, startTls; + private Authenticator auth; - @Override - public MailConfig smtpHost(String newValue) { - return null; + public SqliteMailConfig(Connection connection) throws SQLException { + super(connection); + smtpHost = ""; + smtpPort = 0; + senderAddress = ""; + password = ""; + smtpAuth = true; + startTls = true; + var rs = conn.prepareStatement(SELECT_MAILCONFIG).executeQuery(); + while (rs.next()) { + var key = rs.getString(1); + switch (key) { + case SMTP_PORT -> smtpPort = rs.getInt(2); + case SMTP_HOST -> smtpHost = rs.getString(2); + case START_TLS -> startTls = rs.getBoolean(2); + case SMTP_AUTH -> smtpAuth = rs.getBoolean(2); + case SMTP_PASSWORD -> password = rs.getString(2); + case SMTP_USER -> senderAddress = rs.getString(2); + } + } } - @Override - public int smtpPort() { - return 0; + private void createStoreTables() throws SQLException { + conn.prepareStatement(CREATE_MAIL_CONFIG_TABLE).execute(); } - @Override - public MailConfig smtpPort(int newValue) { - return null; - } @Override - public String senderAddress() { - return ""; - } + protected void initTables() throws SQLException { + var rs = conn.prepareStatement(SELECT_STORE_VERSION).executeQuery(); + int availableVersion = 1; + int currentVersion; + if (rs.next()) { + currentVersion = rs.getInt("value"); + rs.close(); + } else { + rs.close(); + conn.prepareStatement(CREATE_STORE_VERSION).execute(); + currentVersion = 0; + } - @Override - public MailConfig senderAddress(String newValue) { - return null; + conn.setAutoCommit(false); + var stmt = conn.prepareStatement(SET_STORE_VERSION); + while (currentVersion < availableVersion) { + try { + switch (currentVersion) { + case 0: + createStoreTables(); + break; + } + stmt.setInt(1, ++currentVersion); + stmt.execute(); + conn.commit(); + } + catch (Exception e) { + conn.rollback(); + LOG.log(System.Logger.Level.ERROR, "Failed to update at {} = {}", STORE_VERSION, currentVersion); + break; + } } + conn.setAutoCommit(true); +} - @Override - public String senderPassword() { - return ""; - } +@Override +public String smtpHost() { + return smtpHost; +} - @Override - public MailConfig senderPassword(String newValue) { - return null; - } +@Override +public MailConfig smtpHost(String newValue) { + smtpHost = newValue; + return this; +} - @Override - public MailConfig startTls(boolean newValue) { - return null; - } +@Override +public int smtpPort() { + return smtpPort; +} - @Override - public MailConfig smtpAuth(boolean newValue) { - return null; - } +@Override +public MailConfig smtpPort(int newValue) { + smtpPort = newValue; + return this; +} - @Override - public Authenticator authenticator() { - return null; +@Override +public String senderAddress() { + return senderAddress; +} + +@Override +public MailConfig senderAddress(String newValue) { + senderAddress = newValue; + return this; +} + +@Override +public String senderPassword() { + return password; +} + +@Override +public MailConfig senderPassword(String newValue) { + password = newValue; + return this; +} + +@Override +public boolean startTls() { + return startTls; +} + +@Override +public boolean smtpAuth() { + return smtpAuth; +} + +@Override +public MailConfig startTls(boolean newValue) { + startTls = newValue; + return this; +} + +@Override +public MailConfig smtpAuth(boolean newValue) { + smtpAuth = newValue; + return this; +} + +@Override +public Authenticator authenticator() { + if (auth == null) { + auth = new Authenticator() { + // override the getPasswordAuthentication method + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(senderAddress(), senderPassword()); + } + }; } + return auth; +} - @Override - public MailConfig save() { - return null; +@Override +public MailConfig save() { + try { + var stmt = conn.prepareStatement(SAVE_MAILCONFIG); + for (var entry : map().entrySet()) { + stmt.setString(1, entry.getKey()); + stmt.setObject(2, entry.getValue()); + stmt.setObject(3, entry.getValue()); + stmt.execute(); + } + return this; + } catch (SQLException e) { + throw new RuntimeException(e); } } +} diff --git a/de.srsoftware.oidc.datastore.sqlite/src/test/java/de/srsoftware/oidc/datastore/sqlite/SqliteMailConfigTest.java b/de.srsoftware.oidc.datastore.sqlite/src/test/java/de/srsoftware/oidc/datastore/sqlite/SqliteMailConfigTest.java new file mode 100644 index 0000000..cde07c3 --- /dev/null +++ b/de.srsoftware.oidc.datastore.sqlite/src/test/java/de/srsoftware/oidc/datastore/sqlite/SqliteMailConfigTest.java @@ -0,0 +1,37 @@ +/* © SRSoftware 2024 */ +package de.srsoftware.oidc.datastore.sqlite; + +import static de.srsoftware.utils.Strings.uuid; + +import de.srsoftware.oidc.api.MailConfig; +import de.srsoftware.oidc.api.MailConfigTest; +import java.io.File; +import java.sql.SQLException; +import org.junit.jupiter.api.BeforeEach; + +public class SqliteMailConfigTest extends MailConfigTest { + private SqliteMailConfig mailConfig; + private File dbFile; + + @Override + protected MailConfig mailConfig() { + return mailConfig; + } + + @Override + protected void reOpen() { + try { + var conn = new ConnectionProvider().get(dbFile); + mailConfig = new SqliteMailConfig(conn); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @BeforeEach + public void setup() throws SQLException { + dbFile = new File("/tmp/" + uuid() + ".sqlite"); + var conn = new ConnectionProvider().get(dbFile); + mailConfig = new SqliteMailConfig(conn); + } +}