From 1daf4db16766a9c043454264c95783a2381a3e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Tr=C3=B6ger?= Date: Sat, 17 Jan 2026 21:41:46 +0100 Subject: [PATCH] fixed premission problem after making migrations executed by go --- Backend/database.go | 30 ++++++++++ Backend/main.go | 7 +++ DB/initdb/01_create_user.sh | 55 +++++++++++++++++++ DB/initdb/02_sample_data.sql | 8 --- DB/initdb/03_create_user.sh | 21 ------- Docker/docker-compose.dev.yml | 4 +- migrations/20250901201159_initial.up.sql | 12 ++++ ...20250901201710_triggers_extension.down.sql | 5 -- .../20250901201710_triggers_extension.up.sql | 2 - migrations/20251217215955_feiertage.up.sql | 2 + DB/initdb/01_schema.sql => schema.sql | 0 11 files changed, 108 insertions(+), 38 deletions(-) create mode 100755 DB/initdb/01_create_user.sh delete mode 100755 DB/initdb/02_sample_data.sql delete mode 100755 DB/initdb/03_create_user.sh rename DB/initdb/01_schema.sql => schema.sql (100%) diff --git a/Backend/database.go b/Backend/database.go index 8394d1f..041af65 100644 --- a/Backend/database.go +++ b/Backend/database.go @@ -5,7 +5,11 @@ import ( "arbeitszeitmessung/models" "database/sql" "fmt" + "log/slog" + "github.com/golang-migrate/migrate/v4" + _ "github.com/golang-migrate/migrate/v4/database/postgres" + _ "github.com/golang-migrate/migrate/v4/source/file" _ "github.com/lib/pq" ) @@ -19,3 +23,29 @@ func OpenDatabase() (models.IDatabase, error) { connStr := fmt.Sprintf("postgres://%s:%s@%s:5432/%s?sslmode=disable&TimeZone=%s", dbUser, dbPassword, dbHost, dbName, dbTz) return sql.Open("postgres", connStr) } + +func Migrate() error { + dbHost := helper.GetEnv("POSTGRES_HOST", "localhost") + dbName := helper.GetEnv("POSTGRES_DB", "arbeitszeitmessung") + // dbUser := helper.GetEnv("POSTGRES_USER", "api_nutzer") + dbPassword := helper.GetEnv("POSTGRES_PASSWORD", "password") + dbTz := helper.GetEnv("TZ", "Europe/Berlin") + + migrations := helper.GetEnv("MIGRATIONS_DIR", "../migrations") + + connStr := fmt.Sprintf("postgres://%s:%s@%s:5432/%s?sslmode=disable&TimeZone=%s", "migrate", dbPassword, dbHost, dbName, dbTz) + m, err := migrate.New(fmt.Sprintf("file://%s", migrations), connStr) + if err != nil { + return err + } + + slog.Info("Connected to database. Running migrations now.") + + // Migrate all the way up ... + if err := m.Up(); err != nil && err != migrate.ErrNoChange { + return err + } + + slog.Info("Finished migrations starting webserver.") + return nil +} diff --git a/Backend/main.go b/Backend/main.go index 731173c..e083361 100644 --- a/Backend/main.go +++ b/Backend/main.go @@ -44,6 +44,13 @@ func main() { models.DB, err = OpenDatabase() if err != nil { slog.Error("Error while opening the database", "Error", err) + return + } + + err = Migrate() + if err != nil { + slog.Error("Failed to migrate the database to newest version", "Error", err) + return } fs := http.FileServer(http.Dir("./static")) diff --git a/DB/initdb/01_create_user.sh b/DB/initdb/01_create_user.sh new file mode 100755 index 0000000..9536063 --- /dev/null +++ b/DB/initdb/01_create_user.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -e # Exit on error + +echo "Creating PostgreSQL user and setting permissions... $POSTGRES_USER for API user $POSTGRES_API_USER" + + + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE ROLE migrate LOGIN ENCRYPTED PASSWORD '$POSTGRES_PASSWORD'; + GRANT USAGE, CREATE ON SCHEMA public TO migrate; +EOSQL + +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + +# GRANT SELECT, INSERT, UPDATE ON anwesenheit, abwesenheit, user_password, wochen_report, s_feiertage TO $POSTGRES_API_USER; +# GRANT DELETE ON abwesenheit TO $POSTGRES_API_USER; +# GRANT SELECT ON s_personal_daten, s_abwesenheit_typen, s_anwesenheit_typen, s_feiertage TO $POSTGRES_API_USER; +# GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO $POSTGRES_API_USER; +# EOSQL + +echo "User creation and permissions setup complete!" + + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + +-- privilege roles +DO \$\$ +BEGIN + IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'app_base') THEN + CREATE ROLE app_base NOLOGIN; + END IF; +END +\$\$; + +-- dynamic login role +DO \$\$ +BEGIN + IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '$POSTGRES_API_USER') THEN + CREATE ROLE $POSTGRES_API_USER + LOGIN + ENCRYPTED PASSWORD '$POSTGRES_API_PASS'; + END IF; +END +\$\$; + +-- grant base privileges +GRANT app_base TO $POSTGRES_API_USER; +GRANT CONNECT ON DATABASE $POSTGRES_DB TO $POSTGRES_API_USER; +GRANT USAGE ON SCHEMA public TO $POSTGRES_API_USER; + +CREATE EXTENSION IF NOT EXISTS pgcrypto; + +EOSQL + +# psql -v ON_ERROR_STOP=1 --username root --dbname arbeitszeitmessung diff --git a/DB/initdb/02_sample_data.sql b/DB/initdb/02_sample_data.sql deleted file mode 100755 index ea7fcf7..0000000 --- a/DB/initdb/02_sample_data.sql +++ /dev/null @@ -1,8 +0,0 @@ -INSERT INTO "s_personal_daten" ("personal_nummer", "aktiv_beschaeftigt", "vorname", "nachname", "geburtsdatum", "plz", "adresse", "geschlecht", "card_uid", "hauptbeschaeftigungs_ort", "arbeitszeit_per_tag", "arbeitszeit_per_woche", "arbeitszeit_min_start", "arbeitszeit_max_ende", "vorgesetzter_pers_nr") VALUES -(123, 't', 'Kim', 'Mustermensch', '2003-02-01', '08963', 'Altenburger Str. 44A', 1, 'aaaa-aaaa', 1, 8, 40, '07:00:00', '20:00:00', 0); - -INSERT INTO "user_password" ("personal_nummer", "pass_hash") VALUES -(123, crypt('max_pass', gen_salt('bf'))); - -INSERT INTO "s_anwesenheit_typen" ("anwesenheit_id", "anwesenheit_name") VALUES (1, 'Büro'); -INSERT INTO "s_abwesenheit_typen" ("abwesenheit_id", "abwesenheit_name", "arbeitszeit_equivalent") VALUES (1, 'Urlaub', 100), (2, 'Krank', 100), (3, 'Kurzarbeit', -1), (4, 'Urlaub untertags', 50); diff --git a/DB/initdb/03_create_user.sh b/DB/initdb/03_create_user.sh deleted file mode 100755 index 42be086..0000000 --- a/DB/initdb/03_create_user.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -set -e # Exit on error - -echo "Creating PostgreSQL user and setting permissions... $POSTGRES_USER for API user $POSTGRES_API_USER" - -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE USER $POSTGRES_API_USER WITH ENCRYPTED PASSWORD '$POSTGRES_API_PASS'; -EOSQL - -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - GRANT CONNECT ON DATABASE $POSTGRES_DB TO $POSTGRES_API_USER; - GRANT USAGE ON SCHEMA public TO $POSTGRES_API_USER; - GRANT SELECT, INSERT, UPDATE ON anwesenheit, abwesenheit, user_password, wochen_report, s_feiertage TO $POSTGRES_API_USER; - GRANT DELETE ON abwesenheit TO $POSTGRES_API_USER; - GRANT SELECT ON s_personal_daten, s_abwesenheit_typen, s_anwesenheit_typen, s_feiertage TO $POSTGRES_API_USER; - GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO $POSTGRES_API_USER; -EOSQL - -echo "User creation and permissions setup complete!" - -# psql -v ON_ERROR_STOP=1 --username root --dbname arbeitszeitmessung diff --git a/Docker/docker-compose.dev.yml b/Docker/docker-compose.dev.yml index b5a413b..df1ca60 100644 --- a/Docker/docker-compose.dev.yml +++ b/Docker/docker-compose.dev.yml @@ -2,8 +2,8 @@ name: arbeitszeitmessung-dev services: db: volumes: - - ${POSTGRES_PATH}:/var/lib/postgresql/data - # - ${POSTGRES_PATH}/initdb:/docker-entrypoint-initdb.d + - ../DDB:/var/lib/postgresql/data + - ${POSTGRES_PATH}/initdb:/docker-entrypoint-initdb.d ports: - 5432:5432 diff --git a/migrations/20250901201159_initial.up.sql b/migrations/20250901201159_initial.up.sql index 5144756..23f4a3f 100644 --- a/migrations/20250901201159_initial.up.sql +++ b/migrations/20250901201159_initial.up.sql @@ -1,3 +1,11 @@ +ALTER DEFAULT PRIVILEGES FOR ROLE migrate +IN SCHEMA public +GRANT SELECT ON TABLES TO app_base; + +ALTER DEFAULT PRIVILEGES FOR ROLE migrate +IN SCHEMA public +GRANT USAGE, SELECT ON SEQUENCES TO app_base; + -- create "abwesenheit" table CREATE TABLE "abwesenheit" ( "counter_id" bigserial NOT NULL, @@ -6,6 +14,7 @@ CREATE TABLE "abwesenheit" ( "datum" timestamptz NULL DEFAULT (now())::date, PRIMARY KEY ("counter_id") ); + -- create "anwesenheit" table CREATE TABLE "anwesenheit" ( "counter_id" bigserial NOT NULL, @@ -55,3 +64,6 @@ CREATE TABLE "wochen_report" ( PRIMARY KEY ("id"), CONSTRAINT "wochen_report_personal_nummer_woche_start_key" UNIQUE ("personal_nummer", "woche_start") ); + +GRANT INSERT, UPDATE ON abwesenheit, anwesenheit, wochen_report, user_password TO app_base; +GRANT DELETE ON abwesenheit to app_base; diff --git a/migrations/20250901201710_triggers_extension.down.sql b/migrations/20250901201710_triggers_extension.down.sql index 4260320..9bca733 100644 --- a/migrations/20250901201710_triggers_extension.down.sql +++ b/migrations/20250901201710_triggers_extension.down.sql @@ -3,8 +3,3 @@ DROP FUNCTION update_zuletzt_geandert; DROP TRIGGER IF EXISTS pass_hash_update ON user_password; - - --- revert: Adds crypto extension - -DROP EXTENSION IF EXISTS pgcrypto; diff --git a/migrations/20250901201710_triggers_extension.up.sql b/migrations/20250901201710_triggers_extension.up.sql index 5e8ad1f..0c9d936 100644 --- a/migrations/20250901201710_triggers_extension.up.sql +++ b/migrations/20250901201710_triggers_extension.up.sql @@ -17,5 +17,3 @@ FOR EACH ROW EXECUTE FUNCTION update_zuletzt_geandert(); -- Adds crypto extension - -CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/migrations/20251217215955_feiertage.up.sql b/migrations/20251217215955_feiertage.up.sql index 69072a0..735d7f1 100644 --- a/migrations/20251217215955_feiertage.up.sql +++ b/migrations/20251217215955_feiertage.up.sql @@ -11,3 +11,5 @@ CREATE TABLE "s_feiertage" ( ); -- create index "feiertage_unique_pro_jahr" to table: "s_feiertage" CREATE UNIQUE INDEX "feiertage_unique_pro_jahr" ON "s_feiertage" ((EXTRACT(year FROM datum)), "name"); + +GRANT INSERT, UPDATE ON s_feiertage TO app_base; diff --git a/DB/initdb/01_schema.sql b/schema.sql similarity index 100% rename from DB/initdb/01_schema.sql rename to schema.sql