Lewati ke konten

Peran database GeoServer

Peran baca-saja dan baca-tulis, bukan super user.

Berkas: alat/hari-3/Praktik 7/sql/01_peran_geoserver.sql

Praktik 7/sql/01_peran_geoserver.sql
-- =====================================================================
-- Praktik 7 - peran database untuk GeoServer
--
-- Praktik 7 meminta GeoServer menyambung ke PostgreSQL/PostGIS sebagai
-- super user (user "postgres"). Itu berarti GeoServer memegang kredensial
-- yang bisaDROP TABLE, dan satu salah konfigurasi store bisa menghapus
-- data. Jalankan skrip ini untuk membuat peran khusus baca-saja.
--
-- psql "$DATABASE_URL" -v ON_ERROR_STOP=1 \
-- -v sandi_geoserver='GANTI_SANDI_KUAT' \
-- -f 01_peran_geoserver.sql
--
-- Setelah ini, isi form data store PostGIS di GeoServer dengan:
-- host : nama service database (mis. db) atau localhost
-- port : 5432
-- database : nama database
-- schema : public
-- user : geoserver_ro
-- password : nilai sandi_geoserver di atas
-- =====================================================================
-- ---------------------------------------------------------------------
-- GANTI kata sandi di bawah sebelum menjalankan
--
-- Berkas ini memakai SQL biasa, sehingga bisa dijalankan di DBeaver,
-- pgAdmin, atau psql tanpa perbedaan. Tidak ada meta-command.
--
-- Buat kata sandi acak dengan: openssl rand -hex 16
-- ---------------------------------------------------------------------
SELECT set_config('app.sandi_geoserver', 'GANTI_SANDI_DI_SINI', false);
DO $$
BEGIN
IF current_setting('app.sandi_geoserver') = 'GANTI_SANDI_DI_SINI' THEN
RAISE EXCEPTION 'Kata sandi belum diganti. Buat dengan: openssl rand -hex 16';
END IF;
END $$;
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'geoserver_ro') THEN
-- Peran ini login, bukan superuser, dan tidak boleh membuat database
-- atau peran lain.
EXECUTE format(
'CREATE ROLE geoserver_ro LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT PASSWORD %L',
current_setting('app.sandi_geoserver')
);
ELSE
EXECUTE format('ALTER ROLE geoserver_ro PASSWORD %L', current_setting('app.sandi_geoserver'));
END IF;
END $$;
-- Hak minimum supaya GeoServer bisa membaca daftar tabel dan geometri.
GRANT CONNECT ON DATABASE :"DBNAME" TO geoserver_ro;
GRANT USAGE ON SCHEMA public TO geoserver_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO geoserver_ro;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO geoserver_ro;
-- Tanpa ini, tabel yang dibuat SETELAH perintah di atas tidak terbaca.
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO geoserver_ro;
-- PostGIS: GeoServer perlu membaca metadata geometri dan fungsi tipe.
--
-- spatial_ref_sys dan schema extensions hanya ada bila PostGIS terpasang.
-- Pada Supabase, PostGIS dipasang di schema bernama extensions, sehingga
-- perintahnya bisa gagal bila schema itu belum dibuat. Penjagaan di bawah
-- membuat berkas ini tetap berjalan pada database tanpa PostGIS.
DO $$
BEGIN
IF to_regclass('public.spatial_ref_sys') IS NOT NULL THEN
GRANT SELECT ON public.spatial_ref_sys TO geoserver_ro;
ELSIF to_regclass('spatial_ref_sys') IS NOT NULL THEN
GRANT SELECT ON spatial_ref_sys TO geoserver_ro;
ELSE
RAISE NOTICE 'spatial_ref_sys tidak ditemukan. PostGIS belum terpasang, '
'bagian ini dilewati. Pasang PostGIS lebih dahulu bila GeoServer '
'akan membaca data spasial.';
END IF;
IF EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'extensions') THEN
GRANT USAGE ON SCHEMA extensions TO geoserver_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA extensions TO geoserver_ro;
END IF;
END $$;
-- ---------------------------------------------------------------------
-- Jalur tulis terpisah. Praktik 7 meminta hak "edit hanya bisa dilakukan
-- oleh admin" — itu hak di sisi GeoServer (Security > Layers), bukan hak
-- database. Kalau nanti ada fitur edit WFS-T, pakai peran ini.
-- ---------------------------------------------------------------------
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'geoserver_rw') THEN
EXECUTE format(
'CREATE ROLE geoserver_rw LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT PASSWORD %L',
current_setting('app.sandi_geoserver')
);
END IF;
END $$;
GRANT geoserver_ro TO geoserver_rw;
GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO geoserver_rw;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO geoserver_rw;
-- Verifikasi: geoserver_ro harus muncul dengan rolsuper = false.
SELECT rolname, rolsuper, rolcreatedb, rolcanlogin
FROM pg_roles
WHERE rolname IN ('geoserver_ro', 'geoserver_rw')
ORDER BY rolname;