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

Add PostgreSQL test user with restricted privileges #57802

Merged
merged 9 commits into from
Jun 26, 2024
10 changes: 6 additions & 4 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,18 @@ The test database must be initialized using the sql-scripts:

tests/testdata/provider/testdata_pg*.sql

They take care of activating PostGIS and creating some tables containing
test data.
They take care of creating database test users, activating PostGIS
and creating some tables containing test data. For this reason the
database role running them needs to have privileges to perform
those operations.

For convenience, a shell script is provided to create the database
and initialize it as needed:

tests/testdata/provider/testdata_pg.sh

Some tests will attempt to create database users too and expect them to
be allowed to connect using a password.
Some tests will attempt to create database users too and expect them
to be allowed to connect using a password.
Most PostgreSQL installation by default use "ident" authentication
model when connecting via unix sockets. Make sure the `qgis_test`
service (or your `QGIS_PGTEST_DB` connection string) uses a connection
Expand Down
42 changes: 23 additions & 19 deletions tests/testdata/provider/testdata_pg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ DB=${1:-qgis_test}

cd "$(dirname "$0")"/../../../ || exit 1

# IMPORTANT: order matters, don't just sort the files
SCRIPTS="
tests/testdata/provider/testdata_pg_role.sql
strk marked this conversation as resolved.
Show resolved Hide resolved
tests/testdata/provider/testdata_pg.sql
tests/testdata/provider/testdata_pg_relations.sql
tests/testdata/provider/testdata_pg_reltests.sql
tests/testdata/provider/testdata_pg_role.sql
tests/testdata/provider/testdata_pg_vectorjoin.sql
tests/testdata/provider/testdata_pg_hstore.sql
tests/testdata/provider/testdata_pg_array.sql
Expand All @@ -27,57 +28,60 @@ SCRIPTS12="
"

echo "Dropping DB $DB"
psql -q --echo-errors 'service=qgis_test dbname=postgres' -c "DROP DATABASE IF EXISTS $DB"

dropdb --if-exists "${DB}" || exit 1
echo "Creating DB $DB"
psql -q --echo-errors 'service=qgis_test dbname=postgres' -c "CREATE DATABASE $DB WITH TEMPLATE = template0 ENCODING = UTF8" || exit 1
createdb "${DB}" -E UTF8 -T template0 || exit 1

export PGDATABASE="${DB}"

for f in ${SCRIPTS}; do
echo "Loading $f"
psql -q --echo-errors 'service=qgis_test' -c "SET client_min_messages TO WARNING;" -f "${f}" -v ON_ERROR_STOP=1 || exit 1
psql -q --echo-errors -c "SET client_min_messages TO WARNING;" -f "${f}" -v ON_ERROR_STOP=1 || exit 1
done

PGSERVERVERSION=$(psql -XtA 'service=qgis_test' -c 'SHOW server_version_num')
PGSERVERVERSION=$(psql -XtA -c 'SHOW server_version_num')
if test "${PGSERVERVERSION}" -gt 120000; then
for f in ${SCRIPTS12}; do
echo "Loading $f"
psql -q --echo-errors 'service=qgis_test' -c "SET client_min_messages TO WARNING;" -f "${f}" -v ON_ERROR_STOP=1 || exit 1
psql -q --echo-errors -c "SET client_min_messages TO WARNING;" -f "${f}" -v ON_ERROR_STOP=1 || exit 1
done
fi

FINGERPRINT="${DB}-$(date +%s)"
echo "Storing fingerprint ${FINGERPRINT} in $DB"
psql -q --echo-errors 'service=qgis_test' -v ON_ERROR_STOP=1 <<EOF || exit 1
echo "Storing fingerprint '${FINGERPRINT}' in $DB"

psql -q --echo-errors -v ON_ERROR_STOP=1 <<EOF || exit 1
CREATE TABLE qgis_test.schema_info AS SELECT
'fingerprint' var, '${FINGERPRINT}' val;
EOF

# Test service=qgis_test connects to the just-created database
CHECK=$(psql -XtA 'service=qgis_test' -c "select val from qgis_test.schema_info where var='fingerprint'")
echo "Checking if we can connect to ${DB} via service=qgis_test"
CHECK=$(psql -wXtA 'service=qgis_test' -c "select val from qgis_test.schema_info where var='fingerprint'")
if test "${CHECK}" != "${FINGERPRINT}"; then
exec >&2
echo "ERROR: Could not access the just created test database ${DB} via service=qgis_test"
echo "HINT: create a section like the following in ~/.pg_service.conf"
echo "HINT: setup a section like the following in ~/.pg_service.conf"
cat <<EOF
[qgis_test]
host=localhost
port=5432
dbname=${DB}
user=USERNAME
password=PASSWORD
user=qgis_test_user
password=qgis_test_user_password
EOF
exit 1
fi

# TODO: Test service=qgis_test connects via a method which accepts
# Test service=qgis_test connects via a method which accepts
# username/password
CHECK=$(psql -XtA 'service=qgis_test user=qgis_test_user password=qgis_test_user_password' -c "select version()")
CHECK=$(psql -wXtA 'service=qgis_test user=qgis_test_unprivileged_user password=qgis_test_unprivileged_user_password' -c "select version()")
strk marked this conversation as resolved.
Show resolved Hide resolved
if test -z "${CHECK}"; then
exec >&2
echo "ERROR: Cannot service=qgis_test via username/password"
echo "HINT: make sure MD5 method is accepted in pg_hba.conf "
echo "(specifying host=localhost in the [qgis_test] section of "
echo "'~/.pg_service.conf' often does help)"
echo "ERROR: Could not access the just created test database ${DB} via service=qgis_test and overriding username/password"
echo "HINT: make sure password based methods ( scram-sha-256, md4 ) are accepted in pg_hba.conf"
echo " for the kind of connection used by the [qgis_test] section of ~/.pg_service.conf"
echo " Specifying host=localhost often helps."
exit 1
fi

Expand Down
12 changes: 6 additions & 6 deletions tests/testdata/provider/testdata_pg.sql
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ CREATE EXTENSION IF NOT EXISTS citext;
--- Create qgis_test schema
DROP SCHEMA IF EXISTS qgis_test CASCADE;
CREATE SCHEMA qgis_test;
GRANT ALL ON SCHEMA qgis_test TO public;
ALTER DEFAULT PRIVILEGES IN SCHEMA qgis_test GRANT ALL ON TABLES TO public;
ALTER DEFAULT PRIVILEGES IN SCHEMA qgis_test GRANT ALL ON SEQUENCES TO public;
GRANT ALL ON SCHEMA qgis_test TO qgis_test_group;
ALTER DEFAULT PRIVILEGES IN SCHEMA qgis_test GRANT ALL ON TABLES TO qgis_test_group;
ALTER DEFAULT PRIVILEGES IN SCHEMA qgis_test GRANT ALL ON SEQUENCES TO qgis_test_group;


--- Create "CamelCase'singlequote'Schema" schema
DROP SCHEMA IF EXISTS "CamelCase'singlequote'Schema" CASCADE;
CREATE SCHEMA "CamelCase'singlequote'Schema";
GRANT ALL ON SCHEMA "CamelCase'singlequote'Schema" TO public;
ALTER DEFAULT PRIVILEGES IN SCHEMA "CamelCase'singlequote'Schema" GRANT ALL ON TABLES TO public;
ALTER DEFAULT PRIVILEGES IN SCHEMA "CamelCase'singlequote'Schema" GRANT ALL ON SEQUENCES TO public;
GRANT ALL ON SCHEMA "CamelCase'singlequote'Schema" TO qgis_test_group;
ALTER DEFAULT PRIVILEGES IN SCHEMA "CamelCase'singlequote'Schema" GRANT ALL ON TABLES TO qgis_test_group;
ALTER DEFAULT PRIVILEGES IN SCHEMA "CamelCase'singlequote'Schema" GRANT ALL ON SEQUENCES TO qgis_test_group;


SET default_tablespace = '';
Expand Down
7 changes: 6 additions & 1 deletion tests/testdata/provider/testdata_pg_role.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
DROP GROUP IF EXISTS qgis_test_group;
CREATE USER qgis_test_group NOLOGIN;

DROP USER IF EXISTS qgis_test_user;
CREATE USER qgis_test_user PASSWORD 'qgis_test_user_password' LOGIN;
CREATE USER qgis_test_group NOLOGIN;
ALTER GROUP qgis_test_group ADD USER qgis_test_user;

DROP USER IF EXISTS qgis_test_unprivileged_user;
CREATE USER qgis_test_unprivileged_user WITH PASSWORD
'qgis_test_unprivileged_user_password' LOGIN;
Loading