mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-14 01:47:57 +00:00
Merge pull request #3949 from Itz-Agasta/try
Feat: Add admin function for granting access to read-only user
This commit is contained in:
47
lib-sql/grants.sql
Normal file
47
lib-sql/grants.sql
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
-- SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
--
|
||||||
|
-- This file is part of Nominatim. (https://nominatim.org)
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2026 by the Nominatim developer community.
|
||||||
|
-- For a full list of authors see the git log.
|
||||||
|
--
|
||||||
|
-- Grant read-only access to the web user for all Nominatim tables.
|
||||||
|
|
||||||
|
-- Core tables
|
||||||
|
GRANT SELECT ON import_status TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
GRANT SELECT ON country_name TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
GRANT SELECT ON nominatim_properties TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
|
||||||
|
-- Location tables
|
||||||
|
GRANT SELECT ON location_property_tiger TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
GRANT SELECT ON location_property_osmline TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
GRANT SELECT ON location_postcodes TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
|
||||||
|
-- Search tables
|
||||||
|
{% if not db.reverse_only %}
|
||||||
|
GRANT SELECT ON search_name TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
-- Main place tables
|
||||||
|
GRANT SELECT ON placex TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
GRANT SELECT ON place_addressline TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
GRANT SELECT ON placex_entrance TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
|
||||||
|
-- Error/delete tracking tables
|
||||||
|
GRANT SELECT ON import_polygon_error TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
GRANT SELECT ON import_polygon_delete TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
|
||||||
|
-- Country grid
|
||||||
|
GRANT SELECT ON country_osm_grid TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
|
||||||
|
-- Tokenizer tables (word table)
|
||||||
|
{% if 'word' in db.tables %}
|
||||||
|
GRANT SELECT ON word TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
-- Special phrase tables
|
||||||
|
{% for table in db.tables %}
|
||||||
|
{% if table.startswith('place_classtype_') %}
|
||||||
|
GRANT SELECT ON {{ table }} TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
@@ -11,7 +11,6 @@ CREATE TABLE import_status (
|
|||||||
sequence_id integer,
|
sequence_id integer,
|
||||||
indexed boolean
|
indexed boolean
|
||||||
);
|
);
|
||||||
GRANT SELECT ON import_status TO "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
|
|
||||||
drop table if exists import_osmosis_log;
|
drop table if exists import_osmosis_log;
|
||||||
CREATE TABLE import_osmosis_log (
|
CREATE TABLE import_osmosis_log (
|
||||||
@@ -23,14 +22,11 @@ CREATE TABLE import_osmosis_log (
|
|||||||
event text
|
event text
|
||||||
);
|
);
|
||||||
|
|
||||||
GRANT SELECT ON TABLE country_name TO "{{config.DATABASE_WEBUSER}}";
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS nominatim_properties;
|
DROP TABLE IF EXISTS nominatim_properties;
|
||||||
CREATE TABLE nominatim_properties (
|
CREATE TABLE nominatim_properties (
|
||||||
property TEXT NOT NULL,
|
property TEXT NOT NULL,
|
||||||
value TEXT
|
value TEXT
|
||||||
);
|
);
|
||||||
GRANT SELECT ON TABLE nominatim_properties TO "{{config.DATABASE_WEBUSER}}";
|
|
||||||
|
|
||||||
drop table IF EXISTS location_area CASCADE;
|
drop table IF EXISTS location_area CASCADE;
|
||||||
CREATE TABLE location_area (
|
CREATE TABLE location_area (
|
||||||
@@ -66,7 +62,6 @@ CREATE TABLE location_property_tiger (
|
|||||||
partition SMALLINT NOT NULL,
|
partition SMALLINT NOT NULL,
|
||||||
linegeo GEOMETRY NOT NULL,
|
linegeo GEOMETRY NOT NULL,
|
||||||
postcode TEXT);
|
postcode TEXT);
|
||||||
GRANT SELECT ON location_property_tiger TO "{{config.DATABASE_WEBUSER}}";
|
|
||||||
|
|
||||||
drop table if exists location_property_osmline;
|
drop table if exists location_property_osmline;
|
||||||
CREATE TABLE location_property_osmline (
|
CREATE TABLE location_property_osmline (
|
||||||
@@ -90,7 +85,6 @@ CREATE UNIQUE INDEX idx_osmline_place_id ON location_property_osmline USING BTRE
|
|||||||
CREATE INDEX idx_osmline_geometry_sector ON location_property_osmline USING BTREE (geometry_sector) {{db.tablespace.address_index}};
|
CREATE INDEX idx_osmline_geometry_sector ON location_property_osmline USING BTREE (geometry_sector) {{db.tablespace.address_index}};
|
||||||
CREATE INDEX idx_osmline_linegeo ON location_property_osmline USING GIST (linegeo) {{db.tablespace.search_index}}
|
CREATE INDEX idx_osmline_linegeo ON location_property_osmline USING GIST (linegeo) {{db.tablespace.search_index}}
|
||||||
WHERE startnumber is not null;
|
WHERE startnumber is not null;
|
||||||
GRANT SELECT ON location_property_osmline TO "{{config.DATABASE_WEBUSER}}";
|
|
||||||
|
|
||||||
drop table IF EXISTS search_name;
|
drop table IF EXISTS search_name;
|
||||||
{% if not db.reverse_only %}
|
{% if not db.reverse_only %}
|
||||||
@@ -106,7 +100,6 @@ CREATE TABLE search_name (
|
|||||||
) {{db.tablespace.search_data}};
|
) {{db.tablespace.search_data}};
|
||||||
CREATE UNIQUE INDEX idx_search_name_place_id
|
CREATE UNIQUE INDEX idx_search_name_place_id
|
||||||
ON search_name USING BTREE (place_id) {{db.tablespace.search_index}};
|
ON search_name USING BTREE (place_id) {{db.tablespace.search_index}};
|
||||||
GRANT SELECT ON search_name to "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
drop table IF EXISTS place_addressline;
|
drop table IF EXISTS place_addressline;
|
||||||
@@ -203,11 +196,6 @@ CREATE INDEX idx_placex_rank_boundaries_sector ON placex
|
|||||||
|
|
||||||
DROP SEQUENCE IF EXISTS seq_place;
|
DROP SEQUENCE IF EXISTS seq_place;
|
||||||
CREATE SEQUENCE seq_place start 1;
|
CREATE SEQUENCE seq_place start 1;
|
||||||
GRANT SELECT on placex to "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
GRANT SELECT on place_addressline to "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
GRANT SELECT ON planet_osm_ways to "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
GRANT SELECT ON planet_osm_rels to "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
GRANT SELECT on location_area to "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
|
|
||||||
-- Table for synthetic postcodes.
|
-- Table for synthetic postcodes.
|
||||||
DROP TABLE IF EXISTS location_postcodes;
|
DROP TABLE IF EXISTS location_postcodes;
|
||||||
@@ -232,7 +220,6 @@ CREATE INDEX IF NOT EXISTS idx_location_postcodes_postcode
|
|||||||
{{db.tablespace.search_index}};
|
{{db.tablespace.search_index}};
|
||||||
CREATE INDEX IF NOT EXISTS idx_location_postcodes_osmid
|
CREATE INDEX IF NOT EXISTS idx_location_postcodes_osmid
|
||||||
ON location_postcodes USING BTREE (osm_id) {{db.tablespace.search_index}};
|
ON location_postcodes USING BTREE (osm_id) {{db.tablespace.search_index}};
|
||||||
GRANT SELECT ON location_postcodes TO "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
|
|
||||||
-- Table to store location of entrance nodes
|
-- Table to store location of entrance nodes
|
||||||
DROP TABLE IF EXISTS placex_entrance;
|
DROP TABLE IF EXISTS placex_entrance;
|
||||||
@@ -245,7 +232,6 @@ CREATE TABLE placex_entrance (
|
|||||||
);
|
);
|
||||||
CREATE UNIQUE INDEX idx_placex_entrance_place_id_osm_id ON placex_entrance
|
CREATE UNIQUE INDEX idx_placex_entrance_place_id_osm_id ON placex_entrance
|
||||||
USING BTREE (place_id, osm_id) {{db.tablespace.search_index}};
|
USING BTREE (place_id, osm_id) {{db.tablespace.search_index}};
|
||||||
GRANT SELECT ON placex_entrance TO "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
|
|
||||||
-- Create an index on the place table for lookups to populate the entrance
|
-- Create an index on the place table for lookups to populate the entrance
|
||||||
-- table
|
-- table
|
||||||
@@ -267,7 +253,6 @@ CREATE TABLE import_polygon_error (
|
|||||||
newgeometry GEOMETRY(Geometry, 4326)
|
newgeometry GEOMETRY(Geometry, 4326)
|
||||||
);
|
);
|
||||||
CREATE INDEX idx_import_polygon_error_osmid ON import_polygon_error USING BTREE (osm_type, osm_id);
|
CREATE INDEX idx_import_polygon_error_osmid ON import_polygon_error USING BTREE (osm_type, osm_id);
|
||||||
GRANT SELECT ON import_polygon_error TO "{{config.DATABASE_WEBUSER}}";
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS import_polygon_delete;
|
DROP TABLE IF EXISTS import_polygon_delete;
|
||||||
CREATE TABLE import_polygon_delete (
|
CREATE TABLE import_polygon_delete (
|
||||||
@@ -277,7 +262,6 @@ CREATE TABLE import_polygon_delete (
|
|||||||
type TEXT NOT NULL
|
type TEXT NOT NULL
|
||||||
);
|
);
|
||||||
CREATE INDEX idx_import_polygon_delete_osmid ON import_polygon_delete USING BTREE (osm_type, osm_id);
|
CREATE INDEX idx_import_polygon_delete_osmid ON import_polygon_delete USING BTREE (osm_type, osm_id);
|
||||||
GRANT SELECT ON import_polygon_delete TO "{{config.DATABASE_WEBUSER}}";
|
|
||||||
|
|
||||||
DROP SEQUENCE IF EXISTS file;
|
DROP SEQUENCE IF EXISTS file;
|
||||||
CREATE SEQUENCE file start 1;
|
CREATE SEQUENCE file start 1;
|
||||||
@@ -308,5 +292,3 @@ CREATE INDEX planet_osm_rels_relation_members_idx ON planet_osm_rels USING gin(p
|
|||||||
CREATE INDEX IF NOT EXISTS idx_place_interpolations
|
CREATE INDEX IF NOT EXISTS idx_place_interpolations
|
||||||
ON place USING gist(geometry) {{db.tablespace.address_index}}
|
ON place USING gist(geometry) {{db.tablespace.address_index}}
|
||||||
WHERE osm_type = 'W' and address ? 'interpolation';
|
WHERE osm_type = 'W' and address ? 'interpolation';
|
||||||
|
|
||||||
GRANT SELECT ON table country_osm_grid to "{{config.DATABASE_WEBUSER}}";
|
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ class NominatimArgs:
|
|||||||
enable_debug_statements: bool
|
enable_debug_statements: bool
|
||||||
data_object: Sequence[Tuple[str, int]]
|
data_object: Sequence[Tuple[str, int]]
|
||||||
data_area: Sequence[Tuple[str, int]]
|
data_area: Sequence[Tuple[str, int]]
|
||||||
|
ro_access: bool
|
||||||
|
|
||||||
# Arguments to 'replication'
|
# Arguments to 'replication'
|
||||||
init: bool
|
init: bool
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ class UpdateRefresh:
|
|||||||
help='Update secondary importance raster data')
|
help='Update secondary importance raster data')
|
||||||
group.add_argument('--importance', action='store_true',
|
group.add_argument('--importance', action='store_true',
|
||||||
help='Recompute place importances (expensive!)')
|
help='Recompute place importances (expensive!)')
|
||||||
|
group.add_argument('--ro-access', action='store_true',
|
||||||
|
help='Grant read-only access to web user for all tables')
|
||||||
group.add_argument('--website', action='store_true',
|
group.add_argument('--website', action='store_true',
|
||||||
help='DEPRECATED. This function has no function anymore'
|
help='DEPRECATED. This function has no function anymore'
|
||||||
' and will be removed in a future version.')
|
' and will be removed in a future version.')
|
||||||
@@ -159,6 +161,11 @@ class UpdateRefresh:
|
|||||||
LOG.error('WARNING: Website setup is no longer required. '
|
LOG.error('WARNING: Website setup is no longer required. '
|
||||||
'This function will be removed in future version of Nominatim.')
|
'This function will be removed in future version of Nominatim.')
|
||||||
|
|
||||||
|
if args.ro_access:
|
||||||
|
from ..tools import admin
|
||||||
|
LOG.warning('Grant read-only access to web user')
|
||||||
|
admin.grant_ro_access(args.config.get_libpq_dsn(), args.config)
|
||||||
|
|
||||||
if args.data_object or args.data_area:
|
if args.data_object or args.data_area:
|
||||||
with connect(args.config.get_libpq_dsn()) as conn:
|
with connect(args.config.get_libpq_dsn()) as conn:
|
||||||
for obj in args.data_object or []:
|
for obj in args.data_object or []:
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from psycopg.types.json import Json
|
|||||||
from ..typing import DictCursorResult
|
from ..typing import DictCursorResult
|
||||||
from ..config import Configuration
|
from ..config import Configuration
|
||||||
from ..db.connection import connect, Cursor, register_hstore
|
from ..db.connection import connect, Cursor, register_hstore
|
||||||
|
from ..db.sql_preprocessor import SQLPreprocessor
|
||||||
from ..errors import UsageError
|
from ..errors import UsageError
|
||||||
from ..tokenizer import factory as tokenizer_factory
|
from ..tokenizer import factory as tokenizer_factory
|
||||||
from ..data.place_info import PlaceInfo
|
from ..data.place_info import PlaceInfo
|
||||||
@@ -105,3 +106,12 @@ def clean_deleted_relations(config: Configuration, age: str) -> None:
|
|||||||
except psycopg.DataError as exc:
|
except psycopg.DataError as exc:
|
||||||
raise UsageError('Invalid PostgreSQL time interval format') from exc
|
raise UsageError('Invalid PostgreSQL time interval format') from exc
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def grant_ro_access(dsn: str, config: Configuration) -> None:
|
||||||
|
""" Grant read-only access to the web user for all Nominatim tables.
|
||||||
|
This can be used to grant access to a different user after import.
|
||||||
|
"""
|
||||||
|
with connect(dsn) as conn:
|
||||||
|
sql = SQLPreprocessor(conn, config)
|
||||||
|
sql.run_sql_file(conn, 'grants.sql')
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ def create_tables(conn: Connection, config: Configuration, reverse_only: bool =
|
|||||||
|
|
||||||
sql.run_sql_file(conn, 'tables.sql')
|
sql.run_sql_file(conn, 'tables.sql')
|
||||||
|
|
||||||
|
sql.run_sql_file(conn, 'grants.sql')
|
||||||
|
|
||||||
|
|
||||||
def create_table_triggers(conn: Connection, config: Configuration) -> None:
|
def create_table_triggers(conn: Connection, config: Configuration) -> None:
|
||||||
""" Create the triggers for the tables. The trigger functions must already
|
""" Create the triggers for the tables. The trigger functions must already
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ UPDATE_TABLES = [
|
|||||||
'address_levels',
|
'address_levels',
|
||||||
'gb_postcode',
|
'gb_postcode',
|
||||||
'import_osmosis_log',
|
'import_osmosis_log',
|
||||||
'import_polygon_%',
|
|
||||||
'location_area%',
|
'location_area%',
|
||||||
'location_road%',
|
'location_road%',
|
||||||
'place',
|
'place',
|
||||||
|
|||||||
@@ -201,6 +201,8 @@ class TestSetupSQL:
|
|||||||
"""CREATE FUNCTION test() RETURNS bool
|
"""CREATE FUNCTION test() RETURNS bool
|
||||||
AS $$ SELECT {{db.reverse_only}} $$ LANGUAGE SQL""")
|
AS $$ SELECT {{db.reverse_only}} $$ LANGUAGE SQL""")
|
||||||
|
|
||||||
|
self.write_sql('grants.sql', "-- Mock grants file for testing\n")
|
||||||
|
|
||||||
database_import.create_tables(temp_db_conn, self.config, reverse)
|
database_import.create_tables(temp_db_conn, self.config, reverse)
|
||||||
|
|
||||||
temp_db_cursor.scalar('SELECT test()') == reverse
|
temp_db_cursor.scalar('SELECT test()') == reverse
|
||||||
|
|||||||
Reference in New Issue
Block a user