From 44b6f74730c7f837db3d8dda678c4834936fce91 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Tue, 18 Aug 2026 20:18:16 +0200 Subject: [PATCH 1/3] use pg-specific datasource and drop default user name Allows to use pgpass file. --- .../photon/config/HostNameValidator.java | 14 ++++++++ .../photon/config/IdentifierValidator.java | 2 +- .../photon/config/PostgresqlConfig.java | 35 +++++++++---------- .../photon/nominatim/NominatimConnector.java | 14 +------- 4 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 src/main/java/de/komoot/photon/config/HostNameValidator.java diff --git a/src/main/java/de/komoot/photon/config/HostNameValidator.java b/src/main/java/de/komoot/photon/config/HostNameValidator.java new file mode 100644 index 000000000..bfd3996ae --- /dev/null +++ b/src/main/java/de/komoot/photon/config/HostNameValidator.java @@ -0,0 +1,14 @@ +package de.komoot.photon.config; + +import com.beust.jcommander.IParameterValidator; +import com.beust.jcommander.ParameterException; + +public class HostNameValidator implements IParameterValidator { + + @Override + public void validate(String name, String value) throws ParameterException { + if (value.matches(".*[,&/\\\\].*")) { + throw new ParameterException("Parameter " + name + " must not contain &, /, \\ or commas."); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/komoot/photon/config/IdentifierValidator.java b/src/main/java/de/komoot/photon/config/IdentifierValidator.java index f6ed5500a..2f2fb8b49 100644 --- a/src/main/java/de/komoot/photon/config/IdentifierValidator.java +++ b/src/main/java/de/komoot/photon/config/IdentifierValidator.java @@ -7,7 +7,7 @@ public class IdentifierValidator implements IParameterValidator { @Override public void validate(String name, String value) throws ParameterException { - if (value.matches(".*[\\\"',.;$%&/()<>{}=?^*#].*")) { + if (value.matches(".*[\"',.;$%&/()<>{}=?^*#\\\\].*")) { throw new ParameterException("Parameter " + name + " must not contain special characters."); } } diff --git a/src/main/java/de/komoot/photon/config/PostgresqlConfig.java b/src/main/java/de/komoot/photon/config/PostgresqlConfig.java index 20a4d0b28..e545a6aa3 100644 --- a/src/main/java/de/komoot/photon/config/PostgresqlConfig.java +++ b/src/main/java/de/komoot/photon/config/PostgresqlConfig.java @@ -3,12 +3,13 @@ import com.beust.jcommander.Parameter; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; +import org.postgresql.ds.PGSimpleDataSource; @NullMarked public class PostgresqlConfig { public static final String GROUP = "PostgreSQL options"; - @Parameter(names = "-host", category = GROUP, placeholder = "HOST", description = """ + @Parameter(names = "-host", category = GROUP, placeholder = "HOST", validateWith = HostNameValidator.class, description = """ Hostname of the PostgreSQL database """) private String host = "127.0.0.1"; @@ -26,35 +27,33 @@ public class PostgresqlConfig { @Parameter(names = "-user", category = GROUP, placeholder = "NAME", description = """ User for the PostgreSQL database """) - private String user = "nominatim"; + @Nullable private String user = null; @Parameter(names = "-password", category = GROUP, placeholder = "PASSWORD", description = """ Password for the PostgreSQL user """) @Nullable private String password = null; - public String getHost() { - return this.host; - } + public PGSimpleDataSource getDataSource() { + var dataSource = new PGSimpleDataSource(); - public int getPort() { - return this.port; - } + dataSource.setDatabaseName(database); + dataSource.setServerNames(new String[]{host}); + dataSource.setPortNumbers(new int[]{port}); - public String getDatabase() { - return this.database; - } - - public String getUser() { - return this.user; - } + if (user != null) { + dataSource.setUser(user); + } + if (password != null) { + dataSource.setPassword(password); + } - @Nullable public String getPassword() { - return this.password; + return dataSource; } @Override public String toString() { - return String.format("database %s at %s:%d (user: %s)", database, host, port, user); + return String.format("database %s at %s:%d (user: %s)", + database, host, port, user == null ? "-" : user); } } diff --git a/src/main/java/de/komoot/photon/nominatim/NominatimConnector.java b/src/main/java/de/komoot/photon/nominatim/NominatimConnector.java index 57f93958e..7f0986bc4 100644 --- a/src/main/java/de/komoot/photon/nominatim/NominatimConnector.java +++ b/src/main/java/de/komoot/photon/nominatim/NominatimConnector.java @@ -5,7 +5,6 @@ import de.komoot.photon.nominatim.model.AddressRow; import de.komoot.photon.nominatim.model.AddressType; import de.komoot.photon.nominatim.model.NameMap; -import org.apache.commons.dbcp2.BasicDataSource; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import org.springframework.jdbc.core.JdbcTemplate; @@ -27,17 +26,7 @@ public class NominatimConnector { @Nullable private Boolean hasNewPostcodeLocationsTable; protected NominatimConnector(PostgresqlConfig cfg, DBDataAdapter dataAdapter, DatabaseProperties dbProperties) { - BasicDataSource dataSource = new BasicDataSource(); - - dataSource.setUrl(String.format("jdbc:postgresql://%s:%d/%s", - cfg.getHost(), cfg.getPort(), cfg.getDatabase())); - dataSource.setUsername(cfg.getUser()); - if (cfg.getPassword() != null) { - dataSource.setPassword(cfg.getPassword()); - } - - // Keep disabled or server-side cursors won't work. - dataSource.setDefaultAutoCommit(false); + var dataSource = cfg.getDataSource(); txTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource)); @@ -46,7 +35,6 @@ protected NominatimConnector(PostgresqlConfig cfg, DBDataAdapter dataAdapter, Da dbutils = dataAdapter; this.dbProperties = dbProperties; - } @Nullable From bea091a57d463aad4342c36cdfb6096dc245d110 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Tue, 18 Aug 2026 20:42:12 +0200 Subject: [PATCH 2/3] document pgpass file as recommended way to get password --- docs/usage.md | 31 ++++++++++++++++--- .../photon/config/PostgresqlConfig.java | 2 +- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index bae1cc668..a002f2c9d 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -84,23 +84,44 @@ leads to cryptic errors in OpenSearch. ### Importing from a Nominatim database -The default mode is to import the database from a Nominatim PostgreSQL data. +_Note: Support for pgpass file available for Photon>=1.4.0._ + +The default mode is to import the database from a Nominatim PostgreSQL database. To learn about Nominatim and how to set up a database refer -to the [installation documentation](https://nominatim.org/release-docs/latest/admin/Installation/). +to its [installation documentation](https://nominatim.org/release-docs/latest/admin/Installation/). _Important: make sure that updates are stopped on the Nominatim database when running the photon import or results are unpredictable._ photon will try to connect to a PostgreSQL server in the default location -(localhost at port 5432) using the user 'nominatim' and look for a database -'nominatim'. You can customize this with the parameters **-host**, **-port**, -**-user**, **-password**, and **-database**. +(localhost at port 5432) and look for a database 'nominatim'. You can +customize this with the parameters **-host**, **-port**, +**-user**, **-password**, and **-database** and/or supply a pgpass file You likely will need to enable password authentication to the PostgreSQL database. To do so, you can set a password for the database user like this: psql -d nominatim -c "ALTER USER www-data WITH ENCRYPTED PASSWORD 'mysecretpassword'" +While you can then give the password to Photon on the command line, this is +_not recommended_ for security reasons. Use a +[pgpass file](https://www.postgresql.org/docs/current/libpq-pgpass.html) +instead: in the home directory of the user running the import command +create a file `.pgpass` and add the following line: + +``` +127.0.0.1:5432:nominatim:www-data:mysecretpassword +``` + +Naturally, you need to adapt the user name and password to what you actually +use. If necessary, also change the database name `nominatim`. You can now +leave out -user and -password parameters, when running Photon. They will +be picked up from the file when omitted. + +If you need to put the pgpass file in a different location, then you may +specify the location by either setting the PGPASSFILE environment variable +or using the property `-Dorg.postgresql.pgpassfile=` on the command line. + The PostgreSQL user only needs read access to the query tables of the Nominatim database (similar to [Nominatim's web user](https://nominatim.org/release-docs/latest/customize/Settings/#nominatim_database_webuser)). diff --git a/src/main/java/de/komoot/photon/config/PostgresqlConfig.java b/src/main/java/de/komoot/photon/config/PostgresqlConfig.java index e545a6aa3..700c372a6 100644 --- a/src/main/java/de/komoot/photon/config/PostgresqlConfig.java +++ b/src/main/java/de/komoot/photon/config/PostgresqlConfig.java @@ -30,7 +30,7 @@ public class PostgresqlConfig { @Nullable private String user = null; @Parameter(names = "-password", category = GROUP, placeholder = "PASSWORD", description = """ - Password for the PostgreSQL user + Password for the PostgreSQL user (using parameter not recommended, use a pgpass file instead) """) @Nullable private String password = null; From 709a827cc2a8e10aaa6e7c5dd7043f7388b63277 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Tue, 18 Aug 2026 20:50:07 +0200 Subject: [PATCH 3/3] use Github callouts in docs --- README.md | 5 +++-- docs/usage.md | 31 ++++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c224fdd9a..c081888d5 100644 --- a/README.md +++ b/README.md @@ -99,8 +99,9 @@ database dump, then you need to swap out the databases atomically: This unfortunately means you need twice the space of the database for updates. -_WARNING: Never unpack the database in place of the old one. This will lead -to corrupted data._ +> [!CAUTION] +> Never unpack the database in place of the old one. This will lead +> to corrupted data. ## Usage diff --git a/docs/usage.md b/docs/usage.md index a002f2c9d..5f17a85cd 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -84,14 +84,16 @@ leads to cryptic errors in OpenSearch. ### Importing from a Nominatim database -_Note: Support for pgpass file available for Photon>=1.4.0._ +> [!NOTE] +> Support for pgpass file available for Photon>=1.4.0. The default mode is to import the database from a Nominatim PostgreSQL database. To learn about Nominatim and how to set up a database refer to its [installation documentation](https://nominatim.org/release-docs/latest/admin/Installation/). -_Important: make sure that updates are stopped on the Nominatim database -when running the photon import or results are unpredictable._ +> [!CAUTION] +> Make sure that updates are stopped on the Nominatim database +> when running the photon import or results are unpredictable. photon will try to connect to a PostgreSQL server in the default location (localhost at port 5432) and look for a database 'nominatim'. You can @@ -134,6 +136,7 @@ before starting the import with the following command: Adapt the database name as required. + ### Importing from a dump file To load the photon database from a dump file (for example from the @@ -170,10 +173,11 @@ When available, photon can also import full geometries instead of just a centroid and bounding box. These geometries will then be returned with the response. To enable this, use the **-full-geometries** switch. -_Hint: if these filtering options are not sufficient, it is always possible -to preprocess the json dump before feeding it to photon. Have a look at the -[dump spec](json-dump-format-0.1.0.md) to learn about the format of this -file._ +> [!TIP] +> If these filtering options are not sufficient, it is always possible +> to preprocess the json dump before feeding it to photon. Have a look at the +> [dump spec](json-dump-format-0.1.0.md) to learn about the format of this +> file. ### Reverse-only mode @@ -242,12 +246,13 @@ export NOMINATIM_DIR=/srv/nominatim/... where `NOMINATIM_DIR` is the project directory of your Nominatim installation. -_WARNING: never make the /nominatim-update endpoint available on a public -network. While the endpoint is safe to be triggered by random requests, -updates nonetheless create load on your database and running updates while -Nominatim updates are in progress may lead to inconsistencies in the photon -database. You therefore would want to be able to control when exactly an -update is run._ +> [!WARNING] +> Never make the /nominatim-update endpoint available on a public +> network. While the endpoint is safe to be triggered by random requests, +> updates nonetheless create load on your database and running updates while +> Nominatim updates are in progress may lead to inconsistencies in the photon +> database. You therefore would want to be able to control when exactly an +> update is run. ## Exporting Data to a JSON Dump