From ce8a9c95f9e0dbf91d4f5df424650b1541e61461 Mon Sep 17 00:00:00 2001 From: sthelemann Date: Thu, 10 Apr 2025 05:10:25 +0200 Subject: [PATCH 01/23] feat(account)!: add imprint and description (#188) * feat(account): add imprint and description Two columns were added to table `vibetype.account`: `imprint` and `description`. * feat(account): check text lengths --------- Co-authored-by: Jonas Thelemann --- src/deploy/table_account_public.sql | 8 ++++++-- src/verify/table_account_public.sql | 2 ++ test/schema/schema.definition.sql | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/deploy/table_account_public.sql b/src/deploy/table_account_public.sql index b14f4b0d..12a4049c 100644 --- a/src/deploy/table_account_public.sql +++ b/src/deploy/table_account_public.sql @@ -1,13 +1,17 @@ BEGIN; CREATE TABLE vibetype.account ( - id UUID PRIMARY KEY REFERENCES vibetype_private.account(id) ON DELETE CASCADE, + id UUID PRIMARY KEY REFERENCES vibetype_private.account(id) ON DELETE CASCADE, - username TEXT NOT NULL CHECK (char_length(username) < 100 AND username ~ '^[-A-Za-z0-9]+$') UNIQUE + description TEXT CHECK (char_length(description) < 1000), + imprint TEXT CHECK (char_length(imprint) < 10000), + username TEXT NOT NULL CHECK (char_length(username) < 100 AND username ~ '^[-A-Za-z0-9]+$') UNIQUE ); COMMENT ON TABLE vibetype.account IS 'Public account data.'; COMMENT ON COLUMN vibetype.account.id IS 'The account''s internal id.'; +COMMENT ON COLUMN vibetype.account.description IS 'The account''s description.'; +COMMENT ON COLUMN vibetype.account.imprint IS 'The account''s imprint.'; COMMENT ON COLUMN vibetype.account.username IS 'The account''s username.'; GRANT SELECT ON TABLE vibetype.account TO vibetype_account, vibetype_anonymous; diff --git a/src/verify/table_account_public.sql b/src/verify/table_account_public.sql index 78998847..188dbd67 100644 --- a/src/verify/table_account_public.sql +++ b/src/verify/table_account_public.sql @@ -1,6 +1,8 @@ BEGIN; SELECT id, + description, + imprint, username FROM vibetype.account WHERE FALSE; diff --git a/test/schema/schema.definition.sql b/test/schema/schema.definition.sql index ddec95ec..527ef622 100644 --- a/test/schema/schema.definition.sql +++ b/test/schema/schema.definition.sql @@ -4041,7 +4041,11 @@ COMMENT ON COLUMN sqitch.tags.planner_email IS 'Email address of the user who pl CREATE TABLE vibetype.account ( id uuid NOT NULL, + description text, + imprint text, username text NOT NULL, + CONSTRAINT account_description_check CHECK ((char_length(description) < 1000)), + CONSTRAINT account_imprint_check CHECK ((char_length(imprint) < 10000)), CONSTRAINT account_username_check CHECK (((char_length(username) < 100) AND (username ~ '^[-A-Za-z0-9]+$'::text))) ); @@ -4062,6 +4066,20 @@ COMMENT ON TABLE vibetype.account IS 'Public account data.'; COMMENT ON COLUMN vibetype.account.id IS 'The account''s internal id.'; +-- +-- Name: COLUMN account.description; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.account.description IS 'The account''s description.'; + + +-- +-- Name: COLUMN account.imprint; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.account.imprint IS 'The account''s imprint.'; + + -- -- Name: COLUMN account.username; Type: COMMENT; Schema: vibetype; Owner: ci -- From b81b3c9018474e9ce0219880d09d183a2f192a41 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 10 Apr 2025 03:12:29 +0000 Subject: [PATCH 02/23] chore(release): 8.0.0-beta.1 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [8.0.0-beta.1](https://github.com/maevsi/sqitch/compare/7.0.0...8.0.0-beta.1) (2025-04-10) ### ⚠ BREAKING CHANGES * **account:** add imprint and description (#188) ### Features * **account:** add imprint and description ([#188](https://github.com/maevsi/sqitch/issues/188)) ([ce8a9c9](https://github.com/maevsi/sqitch/commit/ce8a9c95f9e0dbf91d4f5df424650b1541e61461)) --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a84ad34..8322dc1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [8.0.0-beta.1](https://github.com/maevsi/sqitch/compare/7.0.0...8.0.0-beta.1) (2025-04-10) + +### ⚠ BREAKING CHANGES + +* **account:** add imprint and description (#188) + +### Features + +* **account:** add imprint and description ([#188](https://github.com/maevsi/sqitch/issues/188)) ([ce8a9c9](https://github.com/maevsi/sqitch/commit/ce8a9c95f9e0dbf91d4f5df424650b1541e61461)) + ## [7.0.0](https://github.com/maevsi/sqitch/compare/6.2.0...7.0.0) (2025-04-07) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index 76352107..e7c26373 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@maevsi/sqitch", - "version": "7.0.0", + "version": "8.0.0-beta.1", "private": true, "engines": { "node": "22" From 4abfcaf0d5a12ab93b9270d3b92d1ec44df33f60 Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Thu, 17 Apr 2025 05:25:32 +0200 Subject: [PATCH 03/23] feat(event)!: remove existence validation function (#191) Should not be possible to query unlisted events by slug for privacy reasons. --- src/deploy/function_event_is_existing.sql | 20 ------------- src/revert/function_event_is_existing.sql | 5 ---- src/sqitch.plan | 1 - src/verify/function_event_is_existing.sql | 9 ------ test/schema/schema.definition.sql | 35 ----------------------- 5 files changed, 70 deletions(-) delete mode 100644 src/deploy/function_event_is_existing.sql delete mode 100644 src/revert/function_event_is_existing.sql delete mode 100644 src/verify/function_event_is_existing.sql diff --git a/src/deploy/function_event_is_existing.sql b/src/deploy/function_event_is_existing.sql deleted file mode 100644 index 438ece45..00000000 --- a/src/deploy/function_event_is_existing.sql +++ /dev/null @@ -1,20 +0,0 @@ -BEGIN; - -CREATE FUNCTION vibetype.event_is_existing( - created_by UUID, - slug TEXT -) RETURNS BOOLEAN AS $$ -BEGIN - IF (EXISTS (SELECT 1 FROM vibetype.event WHERE "event".created_by = event_is_existing.created_by AND "event".slug = event_is_existing.slug)) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype.event_is_existing(UUID, TEXT) IS 'Shows if an event exists.'; - -GRANT EXECUTE ON FUNCTION vibetype.event_is_existing(UUID, TEXT) TO vibetype_account, vibetype_anonymous; - -COMMIT; diff --git a/src/revert/function_event_is_existing.sql b/src/revert/function_event_is_existing.sql deleted file mode 100644 index 48d34443..00000000 --- a/src/revert/function_event_is_existing.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP FUNCTION vibetype.event_is_existing(UUID, TEXT); - -COMMIT; diff --git a/src/sqitch.plan b/src/sqitch.plan index 835f0d4f..56daa1a8 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -61,7 +61,6 @@ function_event_delete [privilege_execute_revoke schema_public role_account table function_account_delete [privilege_execute_revoke schema_public role_account table_account_private table_event extension_pgcrypto] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that allows to delete an account. function_account_password_reset_request [privilege_execute_revoke schema_public schema_private table_account_private table_notification role_anonymous role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Sets a new password reset verification code for an account. function_account_password_reset [privilege_execute_revoke schema_private schema_public table_account_private extension_pgcrypto role_anonymous role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Sets a new password for an account if there was a request to do so before that's still up to date. -function_event_is_existing [privilege_execute_revoke schema_public table_event role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Shows if an event exists. function_invite [privilege_execute_revoke schema_public table_guest function_events_organized table_event table_contact schema_private table_account_private table_profile_picture table_notification role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Adds a notification for the invitation channel. function_account_registration_refresh [privilege_execute_revoke schema_public schema_private table_account_private table_notification role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Refreshes an account's email address verification validity period. function_notification_acknowledge [privilege_execute_revoke schema_public schema_private table_notification role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Allows to set the acknowledgement state of a notification. diff --git a/src/verify/function_event_is_existing.sql b/src/verify/function_event_is_existing.sql deleted file mode 100644 index 388088f9..00000000 --- a/src/verify/function_event_is_existing.sql +++ /dev/null @@ -1,9 +0,0 @@ -BEGIN; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.event_is_existing(UUID, TEXT)', 'EXECUTE')); - ASSERT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.event_is_existing(UUID, TEXT)', 'EXECUTE')); -END $$; - -ROLLBACK; diff --git a/test/schema/schema.definition.sql b/test/schema/schema.definition.sql index 527ef622..d6f73ba3 100644 --- a/test/schema/schema.definition.sql +++ b/test/schema/schema.definition.sql @@ -1197,32 +1197,6 @@ ALTER FUNCTION vibetype.event_guest_count_maximum(event_id uuid) OWNER TO ci; COMMENT ON FUNCTION vibetype.event_guest_count_maximum(event_id uuid) IS 'Add a function that returns the maximum guest count of an accessible event.'; --- --- Name: event_is_existing(uuid, text); Type: FUNCTION; Schema: vibetype; Owner: ci --- - -CREATE FUNCTION vibetype.event_is_existing(created_by uuid, slug text) RETURNS boolean - LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER - AS $$ -BEGIN - IF (EXISTS (SELECT 1 FROM vibetype.event WHERE "event".created_by = event_is_existing.created_by AND "event".slug = event_is_existing.slug)) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$; - - -ALTER FUNCTION vibetype.event_is_existing(created_by uuid, slug text) OWNER TO ci; - --- --- Name: FUNCTION event_is_existing(created_by uuid, slug text); Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON FUNCTION vibetype.event_is_existing(created_by uuid, slug text) IS 'Shows if an event exists.'; - - -- -- Name: event_search(text, vibetype.language); Type: FUNCTION; Schema: vibetype; Owner: ci -- @@ -8122,15 +8096,6 @@ GRANT ALL ON FUNCTION vibetype.event_guest_count_maximum(event_id uuid) TO vibet GRANT ALL ON FUNCTION vibetype.event_guest_count_maximum(event_id uuid) TO vibetype_anonymous; --- --- Name: FUNCTION event_is_existing(created_by uuid, slug text); Type: ACL; Schema: vibetype; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype.event_is_existing(created_by uuid, slug text) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype.event_is_existing(created_by uuid, slug text) TO vibetype_account; -GRANT ALL ON FUNCTION vibetype.event_is_existing(created_by uuid, slug text) TO vibetype_anonymous; - - -- -- Name: FUNCTION event_search(query text, language vibetype.language); Type: ACL; Schema: vibetype; Owner: ci -- From 6eadec5b3999465351d2718d83368c215c0bc003 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 17 Apr 2025 03:27:47 +0000 Subject: [PATCH 04/23] chore(release): 8.0.0-beta.2 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [8.0.0-beta.2](https://github.com/maevsi/sqitch/compare/8.0.0-beta.1...8.0.0-beta.2) (2025-04-17) ### ⚠ BREAKING CHANGES * **event:** remove existence validation function (#191) ### Features * **event:** remove existence validation function ([#191](https://github.com/maevsi/sqitch/issues/191)) ([4abfcaf](https://github.com/maevsi/sqitch/commit/4abfcaf0d5a12ab93b9270d3b92d1ec44df33f60)) --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8322dc1d..8e8b44f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [8.0.0-beta.2](https://github.com/maevsi/sqitch/compare/8.0.0-beta.1...8.0.0-beta.2) (2025-04-17) + +### ⚠ BREAKING CHANGES + +* **event:** remove existence validation function (#191) + +### Features + +* **event:** remove existence validation function ([#191](https://github.com/maevsi/sqitch/issues/191)) ([4abfcaf](https://github.com/maevsi/sqitch/commit/4abfcaf0d5a12ab93b9270d3b92d1ec44df33f60)) + ## [8.0.0-beta.1](https://github.com/maevsi/sqitch/compare/7.0.0...8.0.0-beta.1) (2025-04-10) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index e7c26373..894281f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@maevsi/sqitch", - "version": "8.0.0-beta.1", + "version": "8.0.0-beta.2", "private": true, "engines": { "node": "22" From ef987b26c615cd64c3f66d7f2947ca0347a430a4 Mon Sep 17 00:00:00 2001 From: sthelemann Date: Fri, 2 May 2025 10:51:24 +0200 Subject: [PATCH 05/23] test!: run separately from `sqitch` (#187) Until now application-specific test were included in "verify" scripts and executed by the `sqitch` command being logged in as the `ci` user (see `Dockerfile`). However most tests should run for the user `postgraphile`. All tests have been moved to scripts in directory `./test/logic` and are executed by calling the PostgreSQL command shell `psql` running the sql script `main.sql` which in turn executes the actual test scripts. Some tests are now executed being logged in as user `ci` or `postgraphile` depending on which user is required. See https://github.com/maevsi/sqitch/issues/142. --------- Co-authored-by: Jonas Thelemann --- CONTRIBUTING.md | 2 +- Dockerfile | 14 +- README.md | 4 +- ...ion_account_email_address_verification.sql | 26 - src/deploy/schema_test.sql | 9 - src/deploy/table_legal_term.sql | 16 - src/deploy/test_account_block.sql | 367 ----- src/deploy/test_location.sql | 176 --- src/deploy/test_postgres.sql | 26 - ...ion_account_email_address_verification.sql | 1 - src/revert/schema_test.sql | 5 - src/revert/table_legal_term.sql | 1 - src/revert/test_account_block.sql | 22 - src/revert/test_friendship.sql | 10 - src/revert/test_location.sql | 12 - src/revert/test_postgres.sql | 5 - src/sqitch.plan | 17 +- src/verify/function_account_registration.sql | 105 +- src/verify/function_audit_log.sql | 161 +- src/verify/function_authenticate.sql | 123 +- ...function_language_iso_full_text_search.sql | 58 +- src/verify/schema_test.sql | 14 - src/verify/table_account_block.sql | 4 - src/verify/table_account_private.sql | 4 - .../table_account_social_network_policy.sql | 98 +- src/verify/table_address.sql | 4 - src/verify/table_device.sql | 3 - src/verify/table_event.sql | 3 - src/verify/table_event_group.sql | 4 - src/verify/table_event_grouping.sql | 3 - src/verify/table_friendship.sql | 4 - src/verify/table_guest.sql | 4 - src/verify/test_location.sql | 71 - test/{ => development}/data.patch | 0 .../{schema => fixture}/schema.definition.sql | 1334 +---------------- test/logic/main.sql | 64 + test/logic/scenario/database/audit_log.sql | 166 ++ .../logic/scenario/database/index.sql | 47 + .../scenario/database/index_missing.sql} | 0 test/logic/scenario/model/account.sql | 59 + .../logic/scenario/model/account_block.sql | 33 +- .../scenario/model/account_registration.sql | 122 ++ .../scenario/model/account_social_network.sql | 135 ++ test/logic/scenario/model/authenticate.sql | 128 ++ test/logic/scenario/model/event.sql | 65 + .../logic/scenario/model/friendship.sql | 2 + test/logic/scenario/model/guest.sql | 40 + test/logic/scenario/model/invite.sql | 40 + .../model/language_iso_full_text_search.sql | 63 + test/logic/utility/database/index.sql | 61 + test/logic/utility/database/invoker.sql | 30 + test/logic/utility/database/uuid.sql | 17 + test/logic/utility/model/account.sql | 123 ++ test/logic/utility/model/account_block.sql | 34 + .../utility/model/account_registration.sql | 26 + test/logic/utility/model/contact.sql | 81 + test/logic/utility/model/event.sql | 139 ++ test/logic/utility/model/event_category.sql | 8 + .../utility/model/event_category_mapping.sql | 44 + .../logic/utility/model/friendship.sql | 34 +- test/logic/utility/model/guest.sql | 128 ++ test/logic/utility/model/legal_term.sql | 17 + test/logic/utility/test/cleanup.sql | 25 + test/schema/schema-update.sh | 10 - test/test.sh | 15 + 65 files changed, 1808 insertions(+), 2658 deletions(-) delete mode 100644 src/deploy/schema_test.sql delete mode 100644 src/deploy/test_account_block.sql delete mode 100644 src/deploy/test_location.sql delete mode 100644 src/deploy/test_postgres.sql delete mode 100644 src/revert/schema_test.sql delete mode 100644 src/revert/test_account_block.sql delete mode 100644 src/revert/test_friendship.sql delete mode 100644 src/revert/test_location.sql delete mode 100644 src/revert/test_postgres.sql delete mode 100644 src/verify/schema_test.sql delete mode 100644 src/verify/test_location.sql rename test/{ => development}/data.patch (100%) rename test/{schema => fixture}/schema.definition.sql (85%) create mode 100644 test/logic/main.sql create mode 100644 test/logic/scenario/database/audit_log.sql rename src/verify/test_postgres.sql => test/logic/scenario/database/index.sql (69%) rename test/{index-missing.sql => logic/scenario/database/index_missing.sql} (100%) create mode 100644 test/logic/scenario/model/account.sql rename src/verify/test_account_block.sql => test/logic/scenario/model/account_block.sql (90%) create mode 100644 test/logic/scenario/model/account_registration.sql create mode 100644 test/logic/scenario/model/account_social_network.sql create mode 100644 test/logic/scenario/model/authenticate.sql create mode 100644 test/logic/scenario/model/event.sql rename src/verify/test_friendship.sql => test/logic/scenario/model/friendship.sql (99%) create mode 100644 test/logic/scenario/model/guest.sql create mode 100644 test/logic/scenario/model/invite.sql create mode 100644 test/logic/scenario/model/language_iso_full_text_search.sql create mode 100644 test/logic/utility/database/index.sql create mode 100644 test/logic/utility/database/invoker.sql create mode 100644 test/logic/utility/database/uuid.sql create mode 100644 test/logic/utility/model/account.sql create mode 100644 test/logic/utility/model/account_block.sql create mode 100644 test/logic/utility/model/account_registration.sql create mode 100644 test/logic/utility/model/contact.sql create mode 100644 test/logic/utility/model/event.sql create mode 100644 test/logic/utility/model/event_category.sql create mode 100644 test/logic/utility/model/event_category_mapping.sql rename src/deploy/test_friendship.sql => test/logic/utility/model/friendship.sql (82%) create mode 100644 test/logic/utility/model/guest.sql create mode 100644 test/logic/utility/model/legal_term.sql create mode 100644 test/logic/utility/test/cleanup.sql delete mode 100755 test/schema/schema-update.sh create mode 100755 test/test.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 43031865..2089a07c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ Now edit the source code of this project. Before submitting a pull request, it's important to update the schema artifacts to ensure consistency. We have a script to make this process easier. Run the following command: ``` -test/schema/schema-update.sh +test/test.sh --update ``` This script will regenerate the necessary schema files and update other artifacts as needed. Make sure to include these changes in your pull request. diff --git a/Dockerfile b/Dockerfile index 42ae1c40..4b7c092c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,21 +43,21 @@ RUN apt-get update \ /run/secrets/postgres_role_service_postgraphile_password \ /dev/null -COPY ./src ./ -COPY ./test/index-missing.sql ./test/ +COPY ./src ./src +COPY ./test ./test RUN docker-entrypoint.sh postgres & \ while ! pg_isready -h localhost -U ci -p 5432; do sleep 1; done \ - && sqitch deploy -t db:pg://ci:postgres@/ci_database \ - && psql -h localhost -U ci -d ci_database -f ./test/index-missing.sql -v ON_ERROR_STOP=on \ + && sqitch --chdir src deploy -t db:pg://ci:postgres@/ci_database \ && pg_dump -s -h localhost -U ci -p 5432 ci_database | sed -e '/^-- Dumped/d' > schema.sql \ - && sqitch revert -t db:pg://ci:postgres@/ci_database - + && psql -h localhost -U ci -d ci_database -q -f ./test/logic/main.sql \ + -v TEST_DIRECTORY=./test/logic -v ON_ERROR_STOP=on \ + && sqitch --chdir src revert -t db:pg://ci:postgres@/ci_database ############################## FROM test-build AS test -COPY ./test/schema/schema.definition.sql ./ +COPY ./test/fixture/schema.definition.sql ./ RUN diff schema.definition.sql schema.sql diff --git a/README.md b/README.md index 97c8e7d4..7647b571 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ For example, run `./sqitch deploy` to fill the database with structure like tabl In case you want to be able to simple call `sqitch deploy` without `./` instead, add an `alias sqitch="./sqitch"` to your shell configuration (`~/.bashrc`, `~/.zshrc`, ...). -A basic test data migration can be added to your working directory by running `git apply --3way test/data.patch` and deployed as explained above. -Changes to the test data can be persisted using `git add -AN && git diff > test/data.patch`. +A basic test data migration can be added to your working directory by running `git apply --3way test/development/data.patch` and deployed as explained above. +Changes to the test data can be persisted using `git add -AN && git diff > test/development/data.patch`. ## Database Diagram diff --git a/src/deploy/function_account_email_address_verification.sql b/src/deploy/function_account_email_address_verification.sql index b8b16e71..971e161c 100644 --- a/src/deploy/function_account_email_address_verification.sql +++ b/src/deploy/function_account_email_address_verification.sql @@ -29,30 +29,4 @@ COMMENT ON FUNCTION vibetype.account_email_address_verification(UUID) IS 'Sets t GRANT EXECUTE ON FUNCTION vibetype.account_email_address_verification(UUID) TO vibetype_account, vibetype_anonymous; - -CREATE FUNCTION vibetype_test.account_registration_verified ( - _username TEXT, - _email_address TEXT -) RETURNS UUID AS $$ -DECLARE - _account_id UUID; - _legal_term_id UUID; - _verification UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration(_email_address, 'en', _legal_term_id, 'password', _username); - - SELECT id INTO _account_id - FROM vibetype.account - WHERE username = _username; - - SELECT email_address_verification INTO _verification - FROM vibetype_private.account - WHERE id = _account_id; - - PERFORM vibetype.account_email_address_verification(_verification); - - RETURN _account_id; -END $$ LANGUAGE plpgsql; - COMMIT; diff --git a/src/deploy/schema_test.sql b/src/deploy/schema_test.sql deleted file mode 100644 index 0b14a3ec..00000000 --- a/src/deploy/schema_test.sql +++ /dev/null @@ -1,9 +0,0 @@ -BEGIN; - -CREATE SCHEMA vibetype_test; - -COMMENT ON SCHEMA vibetype_test IS 'Schema for test functions.'; - -GRANT USAGE ON SCHEMA vibetype_test TO vibetype_anonymous, vibetype_account; - -COMMIT; diff --git a/src/deploy/table_legal_term.sql b/src/deploy/table_legal_term.sql index c42bbfba..03047ffd 100644 --- a/src/deploy/table_legal_term.sql +++ b/src/deploy/table_legal_term.sql @@ -62,20 +62,4 @@ CREATE POLICY legal_term_select ON vibetype.legal_term FOR SELECT USING ( TRUE ); - -CREATE FUNCTION vibetype_test.legal_term_singleton () RETURNS UUID AS $$ -DECLARE - _id UUID; - _verification UUID; -BEGIN - SELECT id INTO _id FROM vibetype.legal_term LIMIT 1; - - IF (_id IS NULL) THEN - INSERT INTO vibetype.legal_term (term, version) VALUES ('Be excellent to each other', '0.0.0') - RETURNING id INTO _id; - END IF; - - RETURN _id; -END $$ LANGUAGE plpgsql; - COMMIT; diff --git a/src/deploy/test_account_block.sql b/src/deploy/test_account_block.sql deleted file mode 100644 index feca7957..00000000 --- a/src/deploy/test_account_block.sql +++ /dev/null @@ -1,367 +0,0 @@ -BEGIN; - -CREATE PROCEDURE vibetype_test.set_local_superuser() -AS $$ -DECLARE - _superuser_name TEXT; -BEGIN - SELECT usename INTO _superuser_name - FROM pg_user - WHERE usesuper = true - ORDER BY usename - LIMIT 1; - - IF _superuser_name IS NOT NULL THEN - EXECUTE format('SET LOCAL role = %I', _superuser_name); - ELSE - RAISE NOTICE 'No superuser found!'; - END IF; -END $$ LANGUAGE plpgsql; - -GRANT EXECUTE ON PROCEDURE vibetype_test.set_local_superuser() TO vibetype_anonymous, vibetype_account; - - -CREATE FUNCTION vibetype_test.account_remove ( - _username TEXT -) RETURNS VOID AS $$ -DECLARE - _id UUID; -BEGIN - SELECT id INTO _id FROM vibetype.account WHERE username = _username; - - IF _id IS NOT NULL THEN - - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _id || ''''; - - DELETE FROM vibetype.event WHERE created_by = _id; - - PERFORM vibetype.account_delete('password'); - - CALL vibetype_test.set_local_superuser(); - END IF; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.contact_select_by_account_id ( - _account_id UUID -) RETURNS UUID AS $$ -DECLARE - _id UUID; -BEGIN - SELECT id INTO _id - FROM vibetype.contact - WHERE created_by = _account_id AND account_id = _account_id; - - RETURN _id; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.contact_create ( - _created_by UUID, - _email_address TEXT -) RETURNS UUID AS $$ -DECLARE - _id UUID; - _account_id UUID; -BEGIN - SELECT id FROM vibetype_private.account WHERE email_address = _email_address INTO _account_id; - - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.contact(created_by, email_address) - VALUES (_created_by, _email_address) - RETURNING id INTO _id; - - IF (_account_id IS NOT NULL) THEN - UPDATE vibetype.contact SET account_id = _account_id WHERE id = _id; - END IF; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.event_create ( - _created_by UUID, - _name TEXT, - _slug TEXT, - _start TEXT, - _visibility TEXT -) RETURNS UUID AS $$ -DECLARE - _id UUID; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.event(created_by, name, slug, start, visibility) - VALUES (_created_by, _name, _slug, _start::TIMESTAMP WITH TIME ZONE, _visibility::vibetype.event_visibility) - RETURNING id INTO _id; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.guest_create ( - _created_by UUID, - _event_id UUID, - _contact_id UUID -) RETURNS UUID AS $$ -DECLARE - _id UUID; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.guest(contact_id, event_id) - VALUES (_contact_id, _event_id) - RETURNING id INTO _id; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.event_category_create ( - _category TEXT -) RETURNS VOID AS $$ -BEGIN - INSERT INTO vibetype.event_category(name) VALUES (_category); -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.event_category_mapping_create ( - _created_by UUID, - _event_id UUID, - _category TEXT -) RETURNS VOID AS $$ -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.event_category_mapping(event_id, category_id) - VALUES (_event_id, (SELECT id FROM vibetype.event_category WHERE name = _category)); - - CALL vibetype_test.set_local_superuser(); -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.account_block_create ( - _created_by UUID, - _blocked_account_id UUID -) RETURNS UUID AS $$ -DECLARE - _id UUID; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.account_block(created_by, blocked_account_id) - VALUES (_created_by, _blocked_Account_id) - RETURNING id INTO _id; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.account_block_remove ( - _created_by UUID, - _blocked_account_id UUID -) RETURNS VOID AS $$ -DECLARE - _id UUID; -BEGIN - DELETE FROM vibetype.account_block - WHERE created_by = _created_by and blocked_account_id = _blocked_account_id; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.event_test ( - _test_case TEXT, - _account_id UUID, - _expected_result UUID[] -) RETURNS VOID AS $$ -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT id FROM vibetype.event EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some event should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.event) THEN - RAISE EXCEPTION 'some event is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.event_category_mapping_test ( - _test_case TEXT, - _account_id UUID, - _expected_result UUID[] -) RETURNS VOID AS $$ -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT event_id FROM vibetype.event_category_mapping EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some event_category_mappings should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT event_id FROM vibetype.event_category_mapping) THEN - RAISE EXCEPTION 'some event_category_mappings is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.contact_test ( - _test_case TEXT, - _account_id UUID, - _expected_result UUID[] -) RETURNS VOID AS $$ -DECLARE - rec RECORD; -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT id FROM vibetype.contact EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some contact should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.contact) THEN - RAISE EXCEPTION 'some contact is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.guest_test ( - _test_case TEXT, - _account_id UUID, - _expected_result UUID[] -) RETURNS VOID AS $$ -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT id FROM vibetype.guest EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some guest should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.guest) THEN - RAISE EXCEPTION 'some guest is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.guest_claim_from_account_guest ( - _account_id UUID -) -RETURNS UUID[] AS $$ -DECLARE - _guest vibetype.guest; - _result UUID[] := ARRAY[]::UUID[]; - _text TEXT := ''; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - - -- reads all guests where _account_id is invited, - -- sets jwt.claims.guests to a string representation of these guests - -- and returns an array of these guests. - - FOR _guest IN - SELECT g.id - FROM vibetype.guest g JOIN vibetype.contact c - ON g.contact_id = c.id - WHERE c.account_id = _account_id - LOOP - _text := _text || ',"' || _guest.id || '"'; - _result := array_append(_result, _guest.id); - END LOOP; - - IF LENGTH(_text) > 0 THEN - _text := SUBSTR(_text, 2); - END IF; - - EXECUTE 'SET LOCAL jwt.claims.guests = ''[' || _text || ']'''; - - CALL vibetype_test.set_local_superuser(); - - RETURN _result; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.invoker_set ( - _invoker_id UUID -) -RETURNS VOID AS $$ -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_id || ''''; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.invoker_unset () -RETURNS VOID AS $$ -BEGIN - CALL vibetype_test.set_local_superuser(); - EXECUTE 'SET LOCAL jwt.claims.account_id = '''''; -END $$ LANGUAGE plpgsql; - -CREATE FUNCTION vibetype_test.uuid_array_test ( - _test_case TEXT, - _array UUID[], - _expected_array UUID[] -) -RETURNS VOID AS $$ -BEGIN - IF EXISTS (SELECT * FROM unnest(_array) EXCEPT SELECT * FROM unnest(_expected_array)) THEN - RAISE EXCEPTION 'some uuid should not appear in the array'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_array) EXCEPT SELECT * FROM unnest(_array)) THEN - RAISE EXCEPTION 'some expected uuid is missing in the array'; - END IF; -END $$ LANGUAGE plpgsql; - -GRANT EXECUTE ON FUNCTION vibetype_test.account_block_create(UUID, UUID) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.account_block_remove(UUID, UUID) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.account_remove(TEXT) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.contact_create(UUID, TEXT) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.contact_select_by_account_id(UUID) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.contact_test(TEXT, UUID, UUID[]) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.event_category_create(TEXT) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.event_category_mapping_create(UUID, UUID, TEXT) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.event_category_mapping_test(TEXT, UUID, UUID[]) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.event_create(UUID, TEXT, TEXT, TEXT, TEXT) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.event_test(TEXT, UUID, UUID[]) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.guest_create(UUID, UUID, UUID) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.guest_test(TEXT, UUID, UUID[]) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.guest_claim_from_account_guest(UUID) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.invoker_set(UUID) TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.invoker_unset() TO vibetype_account; -GRANT EXECUTE ON FUNCTION vibetype_test.uuid_array_test(TEXT, UUID[], UUID[]) TO vibetype_account; - -COMMIT; diff --git a/src/deploy/test_location.sql b/src/deploy/test_location.sql deleted file mode 100644 index 2e0d5536..00000000 --- a/src/deploy/test_location.sql +++ /dev/null @@ -1,176 +0,0 @@ -BEGIN; - - -CREATE FUNCTION vibetype_test.account_filter_radius_event( - _event_id UUID, - _distance_max DOUBLE PRECISION -) -RETURNS TABLE ( - account_id UUID, - distance DOUBLE PRECISION -) AS $$ -BEGIN - RETURN QUERY - WITH event AS ( - SELECT address_id - FROM vibetype.event - WHERE id = _event_id - ), - event_address AS ( - SELECT location - FROM vibetype.address - WHERE id = (SELECT address_id FROM event) - ) - SELECT - a.id AS account_id, - ST_Distance(e.location, a.location) AS distance - FROM - event_address e, - vibetype_private.account a - WHERE - ST_DWithin(e.location, a.location, _distance_max * 1000); -END; -$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype_test.account_filter_radius_event(UUID, DOUBLE PRECISION) IS 'Returns account locations within a given radius around the location of an event.'; - -GRANT EXECUTE ON FUNCTION vibetype_test.account_filter_radius_event(UUID, DOUBLE PRECISION) TO vibetype_account; - - -CREATE FUNCTION vibetype_test.event_filter_radius_account( - _account_id UUID, - _distance_max DOUBLE PRECISION -) -RETURNS TABLE ( - event_id UUID, - distance DOUBLE PRECISION -) AS $$ -BEGIN - RETURN QUERY - WITH account AS ( - SELECT location - FROM vibetype_private.account - WHERE id = _account_id - ) - SELECT - e.id AS event_id, - ST_Distance(a.location, addr.location) AS distance - FROM - account a, - vibetype.event e - JOIN - vibetype.address addr ON e.address_id = addr.id - WHERE - ST_DWithin(a.location, addr.location, _distance_max * 1000); -END; -$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype_test.event_filter_radius_account(UUID, DOUBLE PRECISION) IS 'Returns event locations within a given radius around the location of an account.'; - -GRANT EXECUTE ON FUNCTION vibetype_test.event_filter_radius_account(UUID, DOUBLE PRECISION) TO vibetype_account; - - -CREATE FUNCTION vibetype_test.account_location_update( - _account_id UUID, - _latitude DOUBLE PRECISION, - _longitude DOUBLE PRECISION -) -RETURNS VOID AS $$ -BEGIN - UPDATE vibetype_private.account - SET - location = ST_Point(_longitude, _latitude, 4326) - WHERE - id = _account_id; -END; -$$ LANGUAGE PLPGSQL STRICT SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype_test.account_location_update(UUID, DOUBLE PRECISION, DOUBLE PRECISION) IS 'Updates an account''s location based on latitude and longitude (GPS coordinates).'; - -GRANT EXECUTE ON FUNCTION vibetype_test.account_location_update(UUID, DOUBLE PRECISION, DOUBLE PRECISION) TO vibetype_account; - - -CREATE FUNCTION vibetype_test.event_location_update( - _event_id UUID, - _latitude DOUBLE PRECISION, - _longitude DOUBLE PRECISION -) -RETURNS VOID AS $$ -BEGIN - WITH event AS ( - SELECT address_id - FROM vibetype.event - WHERE id = _event_id - ) - UPDATE vibetype.address - SET - location = ST_Point(_longitude, _latitude, 4326) - WHERE - id = (SELECT address_id FROM event); -END; -$$ LANGUAGE PLPGSQL STRICT SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype_test.event_location_update(UUID, DOUBLE PRECISION, DOUBLE PRECISION) IS 'Updates an event''s location based on latitude and longitude (GPS coordinates).'; - -GRANT EXECUTE ON FUNCTION vibetype_test.event_location_update(UUID, DOUBLE PRECISION, DOUBLE PRECISION) TO vibetype_account; - - -CREATE FUNCTION vibetype_test.account_location_coordinates( - _account_id UUID -) -RETURNS DOUBLE PRECISION[] AS $$ -DECLARE - _latitude DOUBLE PRECISION; - _longitude DOUBLE PRECISION; -BEGIN - SELECT - ST_Y(location::geometry), - ST_X(location::geometry) - INTO - _latitude, - _longitude - FROM - vibetype_private.account - WHERE - id = _account_id; - - RETURN ARRAY[_latitude, _longitude]; -END; -$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype_test.account_location_coordinates(UUID) IS 'Returns an array with latitude and longitude of the account''s current location data'; - -GRANT EXECUTE ON FUNCTION vibetype_test.account_location_coordinates(UUID) TO vibetype_account; - - -CREATE FUNCTION vibetype_test.event_location_coordinates( - _event_id UUID -) -RETURNS DOUBLE PRECISION[] AS $$ -DECLARE - _latitude DOUBLE PRECISION; - _longitude DOUBLE PRECISION; -BEGIN - SELECT - ST_Y(a.location::geometry), - ST_X(a.location::geometry) - INTO - _latitude, - _longitude - FROM - vibetype.event e - JOIN - vibetype.address a ON e.address_id = a.id - WHERE - e.id = _event_id; - - RETURN ARRAY[_latitude, _longitude]; -END; -$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype_test.event_location_coordinates(UUID) IS 'Returns an array with latitude and longitude of the event''s current location data.'; - -GRANT EXECUTE ON FUNCTION vibetype_test.event_location_coordinates(UUID) TO vibetype_account; - - -COMMIT; diff --git a/src/deploy/test_postgres.sql b/src/deploy/test_postgres.sql deleted file mode 100644 index da07d472..00000000 --- a/src/deploy/test_postgres.sql +++ /dev/null @@ -1,26 +0,0 @@ -BEGIN; - -CREATE FUNCTION vibetype_test.index_existence( - indexes TEXT[], - schema TEXT DEFAULT 'vibetype' -) RETURNS VOID AS $$ -DECLARE - _existing_count INTEGER; - _expected_count INTEGER; -BEGIN - SELECT COUNT(*) INTO _existing_count - FROM pg_indexes - WHERE schemaname = index_existence.schema - AND indexname = ANY(index_existence.indexes); - - _expected_count := array_length(index_existence.indexes, 1); - - IF _existing_count <> _expected_count THEN - RAISE EXCEPTION 'Index mismatch in schema "%". Expected: %, Found: %', schema, _expected_count, _existing_count; - END IF; -END; -$$ LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype_test.index_existence(TEXT[], TEXT) IS 'Checks whether the given indexes exist in the specified schema. Returns 1 if all exist, fails otherwise.';; - -COMMIT; diff --git a/src/revert/function_account_email_address_verification.sql b/src/revert/function_account_email_address_verification.sql index ec5c76c0..51b598dd 100644 --- a/src/revert/function_account_email_address_verification.sql +++ b/src/revert/function_account_email_address_verification.sql @@ -1,6 +1,5 @@ BEGIN; -DROP FUNCTION vibetype_test.account_registration_verified(TEXT, TEXT); DROP FUNCTION vibetype.account_email_address_verification(UUID); COMMIT; diff --git a/src/revert/schema_test.sql b/src/revert/schema_test.sql deleted file mode 100644 index 672ec2e4..00000000 --- a/src/revert/schema_test.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP SCHEMA vibetype_test; - -COMMIT; diff --git a/src/revert/table_legal_term.sql b/src/revert/table_legal_term.sql index ffe97c5a..9a446d0c 100644 --- a/src/revert/table_legal_term.sql +++ b/src/revert/table_legal_term.sql @@ -1,6 +1,5 @@ BEGIN; -DROP FUNCTION vibetype_test.legal_term_singleton; DROP POLICY legal_term_select ON vibetype.legal_term; DROP TRIGGER vibetype_legal_term_delete ON vibetype.legal_term; DROP TRIGGER vibetype_legal_term_update ON vibetype.legal_term; diff --git a/src/revert/test_account_block.sql b/src/revert/test_account_block.sql deleted file mode 100644 index 29abf142..00000000 --- a/src/revert/test_account_block.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -DROP FUNCTION vibetype_test.account_block_create(UUID, UUID); -DROP FUNCTION vibetype_test.account_block_remove(UUID, UUID); -DROP FUNCTION vibetype_test.account_remove(TEXT); -DROP FUNCTION vibetype_test.contact_create(UUID, TEXT); -DROP FUNCTION vibetype_test.contact_select_by_account_id(UUID); -DROP FUNCTION vibetype_test.contact_test(TEXT, UUID, UUID[]); -DROP FUNCTION vibetype_test.event_category_create(TEXT); -DROP FUNCTION vibetype_test.event_category_mapping_create(UUID, UUID, TEXT); -DROP FUNCTION vibetype_test.event_category_mapping_test(TEXT, UUID, UUID[]); -DROP FUNCTION vibetype_test.event_create(UUID, TEXT, TEXT, TEXT, TEXT); -DROP FUNCTION vibetype_test.event_test(TEXT, UUID, UUID[]); -DROP FUNCTION vibetype_test.guest_create(UUID, UUID, UUID); -DROP FUNCTION vibetype_test.guest_test(TEXT, UUID, UUID[]); -DROP FUNCTION vibetype_test.guest_claim_from_account_guest(UUID); -DROP FUNCTION vibetype_test.invoker_set(UUID); -DROP FUNCTION vibetype_test.invoker_unset(); -DROP FUNCTION vibetype_test.uuid_array_test(TEXT, UUID[], UUID[]); -DROP PROCEDURE vibetype_test.set_local_superuser(); - -COMMIT; diff --git a/src/revert/test_friendship.sql b/src/revert/test_friendship.sql deleted file mode 100644 index bec80840..00000000 --- a/src/revert/test_friendship.sql +++ /dev/null @@ -1,10 +0,0 @@ -BEGIN; - -DROP FUNCTION vibetype_test.friendship_accept(UUID, UUID); -DROP FUNCTION vibetype_test.friendship_reject(UUID, UUID); -DROP FUNCTION vibetype_test.friendship_request(UUID, UUID); - -DROP FUNCTION vibetype_test.friendship_test(TEXT, UUID, TEXT, UUID[]); -DROP FUNCTION vibetype_test.friendship_account_ids_test(TEXT, UUID, UUID[]); - -END; diff --git a/src/revert/test_location.sql b/src/revert/test_location.sql deleted file mode 100644 index f1a4de6a..00000000 --- a/src/revert/test_location.sql +++ /dev/null @@ -1,12 +0,0 @@ -BEGIN; - -DROP FUNCTION vibetype_test.account_filter_radius_event(UUID, DOUBLE PRECISION); -DROP FUNCTION vibetype_test.event_filter_radius_account(UUID, DOUBLE PRECISION); - -DROP FUNCTION vibetype_test.account_location_update(UUID, DOUBLE PRECISION, DOUBLE PRECISION); -DROP FUNCTION vibetype_test.event_location_update(UUID, DOUBLE PRECISION, DOUBLE PRECISION); - -DROP FUNCTION vibetype_test.account_location_coordinates(UUID); -DROP FUNCTION vibetype_test.event_location_coordinates(UUID); - -COMMIT; diff --git a/src/revert/test_postgres.sql b/src/revert/test_postgres.sql deleted file mode 100644 index a2b35ae5..00000000 --- a/src/revert/test_postgres.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP FUNCTION vibetype_test.index_existence(TEXT[], TEXT); - -COMMIT; diff --git a/src/sqitch.plan b/src/sqitch.plan index 56daa1a8..d948cfc9 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -9,29 +9,27 @@ role_account [role_postgraphile] 1970-01-01T00:00:00Z Jonas Thelemann # Add role vibetype. schema_public [role_anonymous role_account role_vibetype] 1970-01-01T00:00:00Z Jonas Thelemann # Add public schema. schema_private 1970-01-01T00:00:00Z Jonas Thelemann # Add private schema. -schema_test 1970-01-01T00:00:00Z Sven Thelemann # Add test schema. extension_pgcrypto [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Add extension pgcrypto. function_invoker_account_id [privilege_execute_revoke schema_public role_account role_anonymous role_vibetype] 1970-01-01T00:00:00Z Jonas Thelemann # Returns the session's account id. enum_invitation_feedback [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Possible answers to an invitation: accepted, canceled. enum_event_visibility [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Possible visibilities of events and event groups: public, private and unlisted. function_trigger_metadata_update [privilege_execute_revoke schema_public function_invoker_account_id role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Trigger function to automatically update metadata fields `updated_at` and `updated_by` when a row is modified. Sets `updated_at` to the current timestamp and `updated_by` to the account ID of the invoker. table_notification [schema_private] 1970-01-01T00:00:00Z Jonas Thelemann # Notifications that are sent via pg_notify. -test_postgres [schema_test] 1970-01-01T00:00:00Z Jonas Thelemann # Checks whether the given indexes exist in the specified schema. -table_account_private [schema_private test_postgres] 1970-01-01T00:00:00Z Jonas Thelemann # Add private table account. +table_account_private [schema_private] 1970-01-01T00:00:00Z Jonas Thelemann # Add private table account. table_account_public [schema_public schema_private table_account_private] 1970-01-01T00:00:00Z Jonas Thelemann # Add public table account. -table_account_block [schema_public table_account_public test_postgres] 1970-01-01T00:00:00Z Sven Thelemann # Blocking of an account by another account. +table_account_block [schema_public table_account_public] 1970-01-01T00:00:00Z Sven Thelemann # Blocking of an account by another account. table_account_block_policy [schema_public table_account_block role_account role_anonymous function_invoker_account_id] 1970-01-01T00:00:00Z Sven Thelemann # Policy for table account block. function_account_block_ids [schema_public table_account_block role_account role_anonymous function_invoker_account_id] 1970-01-01T00:00:00Z Sven Thelemann # Function returning all account id's involved in blocking. -table_event_group [schema_public role_account role_anonymous table_account_public enum_event_visibility test_postgres] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event_group. +table_event_group [schema_public role_account role_anonymous table_account_public enum_event_visibility] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event_group. enum_language [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Supported ISO 639 language codes. function_language_iso_full_text_search [privilege_execute_revoke schema_public enum_language] 1970-01-01T00:00:00Z Jonas Thelemann # ISO language code to full text search language conversion. table_address [schema_public table_account_public function_trigger_metadata_update] 1970-01-01T00:00:00Z Jonas Thelemann # Stores detailed address information, including lines, city, state, country, and metadata. table_address_policy [schema_public table_address role_account role_anonymous function_invoker_account_id function_account_block_ids] 1970-01-01T00:00:00Z Jonas Thelemann # Policy for table address. -table_event [schema_public table_address table_account_public enum_language enum_event_visibility function_language_iso_full_text_search role_account role_anonymous test_postgres] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event. +table_event [schema_public table_address table_account_public enum_language enum_event_visibility function_language_iso_full_text_search role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event. function_events_organized [privilege_execute_revoke schema_public function_invoker_account_id table_event role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns all event ids for which the invoker is the creator. enum_invitation_feedback_paper 1970-01-01T00:00:00Z Jonas Thelemann # Possible choices on how to receive a paper invitation: paper, digital. table_contact [schema_public table_account_public table_address enum_language role_account function_invoker_account_id] 1970-01-01T00:00:00Z Jonas Thelemann # Add table contact. -table_guest [schema_public table_event table_contact test_postgres] 1970-01-01T00:00:00Z Jonas Thelemann # Add table guest. +table_guest [schema_public table_event table_contact] 1970-01-01T00:00:00Z Jonas Thelemann # Add table guest. function_events_invited [privilege_execute_revoke schema_private schema_public table_guest table_contact function_invoker_account_id function_account_block_ids role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns all event ids for which the invoker is invited. function_guest_claim_array [privilege_execute_revoke schema_public table_guest function_invoker_account_id function_account_block_ids role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns the current guest claims as UUID array. function_guest_contact_ids [privilege_execute_revoke schema_public table_guest function_guest_claim_array function_events_organized function_account_block_ids role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns all event ids for which the invoker is invited. @@ -40,7 +38,7 @@ function_guest_count [privilege_execute_revoke schema_public table_guest role_ac table_event_policy [schema_public table_event role_account role_anonymous function_guest_count function_account_block_ids function_invoker_account_id schema_private function_events_invited] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table event. function_event_guest_count_maximum [privilege_execute_revoke schema_public table_event function_guest_count function_invoker_account_id schema_private function_events_invited role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns the maximum guest count of an accessible event. table_guest_policy [schema_public table_guest role_account role_anonymous function_guest_claim_array function_invoker_account_id function_events_organized function_account_block_ids function_event_guest_count_maximum] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table contact. -table_event_grouping [schema_public role_account role_anonymous table_event table_event_group test_postgres] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event grouping. +table_event_grouping [schema_public role_account role_anonymous table_event table_event_group] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event grouping. type_jwt [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Add type jwt. table_legal_term [schema_public role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Legal terms like privacy policies or terms of service. table_legal_term_acceptance [schema_public table_account_public table_legal_term role_account function_invoker_account_id] 1970-01-01T00:00:00Z Jonas Thelemann # Tracks each user account's acceptance of legal terms and conditions. @@ -91,15 +89,12 @@ table_event_recommendation_policy [schema_public table_event_recommendation role table_event_favorite [schema_public table_account_public table_event] 1970-01-01T00:00:00Z Sven Thelemann # A table for the user accounts' favorite events. table_event_favorite_policy [schema_public table_account_public table_event role_account] 1970-01-01T00:00:00Z Sven Thelemann # Security policies for event favorites. function_guest_create_multiple [schema_public table_guest role_account] 1970-01-01T00:00:00Z Sven Thelemann # Function for inserting multiple guest records. -test_account_block [schema_test] 1970-01-01T00:00:00Z Sven Thelemann # Test cases for account blocking. function_event_search [privilege_execute_revoke schema_public enum_language schema_private function_language_iso_full_text_search table_event role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Full-text search on events. -test_location [schema_public schema_private table_account_private table_event role_anonymous role_account] 1970-01-01T00:00:00Z Sven Thelemann # A collection of location related functions. table_device [schema_public table_account_public function_trigger_metadata_update] 1970-01-01T00:00:00Z Jonas Thelemann # A device that's assigned to an account. table_device_policy [schema_public table_device role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Policies for devices. enum_friendship_status [schema_public] 1970-01-01T00:00:00Z Sven Thelemann # Possible status values of a friend relation. table_friendship [schema_public enum_friendship_status table_account_public function_trigger_metadata_update] 1970-01-01T00:00:00Z Sven Thelemann # A friend relation together with its status. table_friendship_policy [schema_public table_friendship role_account] 1970-01-01T00:00:00Z Sven Thelemann # Policy for table friend. -test_friendship [schema_test function_account_email_address_verification] 1970-01-01T00:00:00Z Sven Thelemann # Test cases for friendship. table_event_format [schema_public role_anonymous role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Table for storing event formats. table_event_format_mapping [schema_public table_event table_event_format role_anonymous role_account function_invoker_account_id] 1970-01-01T00:00:00Z Jonas Thelemann # Table for storing event to category (M:N) relationships. table_audit_log [schema_private] 1970-01-01T00:00:00Z Sven Thelemann # Table for storing audit log records. diff --git a/src/verify/function_account_registration.sql b/src/verify/function_account_registration.sql index 086c577e..29a237c3 100644 --- a/src/verify/function_account_registration.sql +++ b/src/verify/function_account_registration.sql @@ -1,108 +1,5 @@ BEGIN; -SAVEPOINT function_privileges_for_roles; -DO $$ -BEGIN - IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.account_registration(TEXT, TEXT, UUID, TEXT, TEXT)', 'EXECUTE')) THEN - RAISE EXCEPTION 'Test function_privileges_for_roles failed: vibetype_account does not have EXECUTE privilege'; - END IF; - - IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.account_registration(TEXT, TEXT, UUID, TEXT, TEXT)', 'EXECUTE')) THEN - RAISE EXCEPTION 'Test function_privileges_for_roles failed: vibetype_anonymous does not have EXECUTE privilege'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT function_privileges_for_roles; - -SAVEPOINT account_registration; -DO $$ -DECLARE - _legal_term_id UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', 'username'); -END $$; -ROLLBACK TO SAVEPOINT account_registration; - -SAVEPOINT password_length; -DO $$ -DECLARE - _legal_term_id UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'short', 'username'); - RAISE EXCEPTION 'Test failed: Password length not enforced'; -EXCEPTION WHEN invalid_parameter_value THEN - NULL; -END $$; -ROLLBACK TO SAVEPOINT password_length; - -SAVEPOINT username_uniqueness; -DO $$ -DECLARE - _legal_term_id UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration('diff@example.com', 'en', _legal_term_id, 'password', 'username-duplicate'); - PERFORM vibetype.account_registration('erent@example.com', 'en', _legal_term_id, 'password', 'username-duplicate'); - RAISE EXCEPTION 'Test failed: Duplicate username not enforced'; -EXCEPTION WHEN unique_violation THEN - NULL; -END $$; -ROLLBACK TO SAVEPOINT username_uniqueness; - -SAVEPOINT email_uniqueness; -DO $$ -DECLARE - _legal_term_id UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration('duplicate@example.com', 'en', _legal_term_id, 'password', 'username-diff'); - PERFORM vibetype.account_registration('duplicate@example.com', 'en', _legal_term_id, 'password', 'username-erent'); -END $$; -ROLLBACK TO SAVEPOINT email_uniqueness; - -SAVEPOINT username_null; -DO $$ -DECLARE - _legal_term_id UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', NULL); - RAISE EXCEPTION 'Test failed: NULL username allowed'; -EXCEPTION WHEN OTHERS THEN - NULL; -END $$; -ROLLBACK TO SAVEPOINT username_null; - -SAVEPOINT username_length; -DO $$ -DECLARE - _legal_term_id UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', ''); - RAISE EXCEPTION 'Test failed: Empty username allowed'; -EXCEPTION WHEN OTHERS THEN - NULL; -END $$; -ROLLBACK TO SAVEPOINT username_length; - -SAVEPOINT notification; -DO $$ -DECLARE - _legal_term_id UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', 'username-8b973f'); - - IF NOT EXISTS ( - SELECT 1 FROM vibetype_private.notification - WHERE channel = 'account_registration' - AND payload::jsonb -> 'account' ->> 'username' = 'username-8b973f' - ) THEN - RAISE EXCEPTION 'Test failed: Notification not generated'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT notification; +-- in /test/logic/scenario/model/account_registration.sql ROLLBACK; diff --git a/src/verify/function_audit_log.sql b/src/verify/function_audit_log.sql index df8a64ba..b6cfbacf 100644 --- a/src/verify/function_audit_log.sql +++ b/src/verify/function_audit_log.sql @@ -1,164 +1,5 @@ BEGIN; -DO $$ -DECLARE - _record Record; - _count INTEGER; -BEGIN - --------------------------------------------------------- - -- drop all audit log triggers - - PERFORM vibetype_private.trigger_audit_log_drop_multiple(); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger; - - IF _count != 0 THEN - RAISE EXCEPTION 'There are still audit log triggers'; - END IF; - - --------------------------------------------------------- - -- create all audit log triggers - - PERFORM vibetype_private.trigger_audit_log_create_multiple(); - - -- check that no audit log triggers were created for vibetype_private.audit_log and vibetype_private.jwt - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger - WHERE schema_name = 'vibetype_private' AND table_name in ('audit_log', 'jwt'); - - IF _count != 0 THEN - RAISE EXCEPTION 'There must not be audit log triggers for vibetype_private.audit_log and vibetype_private.jwt'; - END IF; - - -- check that for all other tables with id column there is an audit log trigger - - _count := 0; - - FOR _record IN - SELECT schemaname, tablename - FROM pg_tables - WHERE schemaname IN ('vibetype', 'vibetype_private') - - EXCEPT - SELECT 'vibetype_private', 'audit_log' -- no audit log trigger for this table - EXCEPT - SELECT 'vibetype_private', 'jwt' -- no audit log trigger for this table - EXCEPT - SELECT schema_name, table_name - FROM vibetype_private.audit_log_trigger - LOOP - IF EXISTS ( - -- if current table has an id column there should have been an audti log trigger - SELECT 1 - FROM pg_catalog.pg_class c - JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid - JOIN pg_catalog.pg_attribute a ON c.oid = a.attrelid - WHERE c.relname = _record.tablename AND c.relkind = 'r' - AND n.nspname = _record.schemaname AND a.attname = 'id' - ) THEN - _count := _count + 1; - RAISE NOTICE 'Table % misses an audit log trigger', _record.schema_name || '.' || _record.table_name; - END IF; - END LOOP; - - IF _count != 0 THEN - RAISE EXCEPTION 'There are tables that should have an audit log trigger but have not.'; - END IF; - - --------------------------------------------------------- - -- disable all audit log triggers - - PERFORM vibetype_private.trigger_audit_log_disable_multiple(); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger - WHERE trigger_enabled != 'D'; - - IF _count != 0 THEN - RAISE EXCEPTION 'There is still an enabled audit log trigger.'; - END IF; - - --------------------------------------------------------- - -- enable all audit log triggers - - PERFORM vibetype_private.trigger_audit_log_enable_multiple(); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger - WHERE trigger_enabled = 'D'; - - IF _count != 0 THEN - RAISE EXCEPTION 'There is still a disabled audit log trigger.'; - END IF; - - --------------------------------------------------------- - -- disable the audit log trigger for a single table - - PERFORM vibetype_private.trigger_audit_log_disable ('vibetype', 'event'); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger - WHERE trigger_enabled != 'D' - AND schema_name = 'vibetype' AND table_name = 'event'; - - IF _count != 0 THEN - RAISE EXCEPTION 'The audit log trigger on table vibetype.event is still enabled.'; - END IF; - - --------------------------------------------------------- - -- enable the audit log trigger for a single table - - PERFORM vibetype_private.trigger_audit_log_enable ('vibetype', 'event'); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger - WHERE trigger_enabled = 'D' - AND schema_name = 'vibetype' AND table_name = 'event'; - - IF _count != 0 THEN - RAISE EXCEPTION 'The audit log trigger on table vibetype.event is still disabled.'; - END IF; - - --------------------------------------------------------- - -- drop all audit log triggers - - PERFORM vibetype_private.trigger_audit_log_drop_multiple(); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger; - - IF _count != 0 THEN - RAISE EXCEPTION 'There are still audit log triggers.'; - END IF; - - --------------------------------------------------------- - -- create an audit log trigger for a single table - - PERFORM vibetype_private.trigger_audit_log_create('vibetype', 'event'); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger - WHERE schema_name = 'vibetype' AND table_name = 'event'; - - IF _count != 1 THEN - RAISE EXCEPTION 'The audit log trigger for table vibetype.event has not been created.'; - END IF; - - --------------------------------------------------------- - -- drop the audit log trigger on a single table - - PERFORM vibetype_private.trigger_audit_log_drop('vibetype', 'event'); - - SELECT COUNT(*) INTO _count - FROM vibetype_private.audit_log_trigger - WHERE schema_name = 'vibetype' AND table_name = 'event'; - - IF _count != 0 THEN - RAISE EXCEPTION 'The audit log trigger for table vibetype.event was not dropped.'; - END IF; -END; -$$ LANGUAGE plpgsql; +-- in /test/logic/scenario/database/audit_log.sql ROLLBACK; diff --git a/src/verify/function_authenticate.sql b/src/verify/function_authenticate.sql index d1fd5359..54ee4340 100644 --- a/src/verify/function_authenticate.sql +++ b/src/verify/function_authenticate.sql @@ -1,126 +1,5 @@ BEGIN; -SAVEPOINT privileges; -DO $$ -BEGIN - IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.authenticate(TEXT, TEXT)', 'EXECUTE')) THEN - RAISE EXCEPTION 'Test privileges failed: vibetype_account does not have EXECUTE privilege'; - END IF; - - IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.authenticate(TEXT, TEXT)', 'EXECUTE')) THEN - RAISE EXCEPTION 'Test privileges failed: vibetype_anonymous does not have EXECUTE privilege'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT privileges; - -SAVEPOINT username_success; -DO $$ -DECLARE - _jwt vibetype.jwt; -BEGIN - PERFORM vibetype_test.account_registration_verified('username', 'email@example.com'); - - _jwt := vibetype.authenticate('username', 'password'); - - IF _jwt IS NULL THEN - RAISE EXCEPTION 'Test failed: Authentication should have returned a JWT'; - END IF; - - IF _jwt.account_username <> 'username' THEN - RAISE EXCEPTION 'Test failed: JWT contains an incorrect username'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT username_success; - -SAVEPOINT username_incorrect; -DO $$ -DECLARE - _jwt vibetype.jwt; -BEGIN - PERFORM vibetype_test.account_registration_verified('username', 'email@example.com'); - - BEGIN - _jwt := vibetype.authenticate('username_incorrect', 'password'); - EXCEPTION WHEN no_data_found THEN - NULL; - END; -END $$; -ROLLBACK TO SAVEPOINT username_incorrect; - -SAVEPOINT username_password_incorrect; -DO $$ -DECLARE - _jwt vibetype.jwt; -BEGIN - PERFORM vibetype_test.account_registration_verified('username', 'email@example.com'); - - BEGIN - _jwt := vibetype.authenticate('username', 'password_incorrect'); - EXCEPTION WHEN no_data_found THEN - NULL; - END; - - IF _jwt IS NOT NULL THEN - RAISE EXCEPTION 'Test failed: Authentication should not have returned a JWT'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT username_password_incorrect; - -SAVEPOINT email_success; -DO $$ -DECLARE - _jwt vibetype.jwt; -BEGIN - PERFORM vibetype_test.account_registration_verified('username', 'email@example.com'); - - _jwt := vibetype.authenticate('email@example.com', 'password'); - - IF _jwt IS NULL THEN - RAISE EXCEPTION 'Test failed: Authentication should have returned a JWT'; - END IF; - - IF _jwt.account_username <> 'username' THEN - RAISE EXCEPTION 'Test failed: JWT contains an incorrect user name'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT email_success; - -SAVEPOINT email_incorrect; -DO $$ -DECLARE - _jwt vibetype.jwt; -BEGIN - PERFORM vibetype_test.account_registration_verified('username', 'email@example.com'); - - BEGIN - _jwt := vibetype.authenticate('email_incorrect@example.com', 'password'); - EXCEPTION WHEN no_data_found THEN - NULL; - END; - - IF _jwt IS NOT NULL THEN - RAISE EXCEPTION 'Test failed: Authentication should not have returned a JWT'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT email_incorrect; - -SAVEPOINT email_password_incorrect; -DO $$ -DECLARE - _jwt vibetype.jwt; -BEGIN - PERFORM vibetype_test.account_registration_verified('username', 'email@example.com'); - - BEGIN - _jwt := vibetype.authenticate('email@example.com', 'password_incorrect'); - EXCEPTION WHEN no_data_found THEN - NULL; - END; - - IF _jwt IS NOT NULL THEN - RAISE EXCEPTION 'Test failed: Authentication should not have returned a JWT'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT email_password_incorrect; +-- in /test/logic/scenario/model/authenticate.sql ROLLBACK; diff --git a/src/verify/function_language_iso_full_text_search.sql b/src/verify/function_language_iso_full_text_search.sql index 572da747..1d2d55e2 100644 --- a/src/verify/function_language_iso_full_text_search.sql +++ b/src/verify/function_language_iso_full_text_search.sql @@ -1,61 +1,5 @@ BEGIN; -SAVEPOINT privileges; -DO $$ -BEGIN - IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.language_iso_full_text_search(vibetype.language)', 'EXECUTE')) THEN - RAISE EXCEPTION 'Test privileges failed: vibetype_account does not have EXECUTE privilege'; - END IF; - - IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.language_iso_full_text_search(vibetype.language)', 'EXECUTE')) THEN - RAISE EXCEPTION 'Test privileges failed: vibetype_anonymous does not have EXECUTE privilege'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT privileges; - -SAVEPOINT success; -DO $$ -DECLARE - _language vibetype.language; - _result regconfig; -BEGIN - FOREACH _language IN ARRAY - ARRAY['de', 'en', NULL] - LOOP - CASE _language - WHEN 'de' THEN _result := 'pg_catalog.german'; - WHEN 'en' THEN _result := 'pg_catalog.english'; - ELSE _result := 'pg_catalog.simple'; - END CASE; - - IF vibetype.language_iso_full_text_search(_language) != _result THEN - RAISE EXCEPTION 'Test failed for input %: Expected % but got %', _language, _result, vibetype.language_iso_full_text_search(lang_code); - END IF; - END LOOP; -END $$; -ROLLBACK TO SAVEPOINT success; - -SAVEPOINT strict; -DO $$ -BEGIN - IF vibetype.language_iso_full_text_search(NULL::vibetype.language) IS NULL THEN - RAISE EXCEPTION 'Test failed for NULL input. Did not expect to get NULL.'; - END IF; -END $$; -ROLLBACK TO SAVEPOINT strict; - -SAVEPOINT invalid; -DO $$ -BEGIN - BEGIN - PERFORM vibetype.language_iso_full_text_search('invalid'::vibetype.language); - EXCEPTION - WHEN OTHERS THEN - RETURN; - END; - - RAISE EXCEPTION 'Test failed: Invalid language ''invalid'' should have raised an exception but did not.'; -END $$; -ROLLBACK TO SAVEPOINT invalid; +-- in /test/logic/scenario/model/language_iso_full_text_search.sql ROLLBACK; diff --git a/src/verify/schema_test.sql b/src/verify/schema_test.sql deleted file mode 100644 index fa7554b5..00000000 --- a/src/verify/schema_test.sql +++ /dev/null @@ -1,14 +0,0 @@ -BEGIN; - -DO $$ -BEGIN - ASSERT EXISTS(SELECT * FROM pg_catalog.pg_namespace WHERE nspname = 'vibetype_test'); -END $$; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_schema_privilege('vibetype_account', 'vibetype_test', 'USAGE')); - ASSERT (SELECT pg_catalog.has_schema_privilege('vibetype_anonymous', 'vibetype_test', 'USAGE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_account_block.sql b/src/verify/table_account_block.sql index 0c639649..b84fd212 100644 --- a/src/verify/table_account_block.sql +++ b/src/verify/table_account_block.sql @@ -6,8 +6,4 @@ SELECT id, created_by FROM vibetype.account_block WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['account_block_created_by_blocked_account_id_key'] -); - ROLLBACK; diff --git a/src/verify/table_account_private.sql b/src/verify/table_account_private.sql index 48139c1d..9399cf3e 100644 --- a/src/verify/table_account_private.sql +++ b/src/verify/table_account_private.sql @@ -14,10 +14,6 @@ SELECT id, last_activity FROM vibetype_private.account WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['idx_account_private_location'], - 'vibetype_private' -); \set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` SET local role.vibetype_username TO :'role_service_vibetype_username'; diff --git a/src/verify/table_account_social_network_policy.sql b/src/verify/table_account_social_network_policy.sql index 04699f76..e06f24e3 100644 --- a/src/verify/table_account_social_network_policy.sql +++ b/src/verify/table_account_social_network_policy.sql @@ -1,101 +1,5 @@ BEGIN; -SAVEPOINT select_account; -DO $$ -BEGIN - SET LOCAL role TO vibetype_account; - PERFORM * FROM vibetype.account_social_network; -END $$; -ROLLBACK TO SAVEPOINT select_account; - -SAVEPOINT select_anonymous; -DO $$ -BEGIN - SET LOCAL role TO vibetype_anonymous; - PERFORM * FROM vibetype.account_social_network; -END $$; -ROLLBACK TO SAVEPOINT select_anonymous; - -SAVEPOINT insert_account; -DO $$ -BEGIN - INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); - INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); - - SET LOCAL role TO vibetype_account; - SET LOCAL jwt.claims.account_id TO '00000000-0000-0000-0000-000000000000'; - INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) - VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); -END $$; -ROLLBACK TO SAVEPOINT insert_account; - -SAVEPOINT insert_anonymous; -DO $$ -BEGIN - INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); - INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); - - SET LOCAL role TO vibetype_anonymous; - INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) - VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); - RAISE EXCEPTION 'Test insert_anonymous failed: Anonymous users should not be able to insert'; -EXCEPTION WHEN others THEN - NULL; -END $$; -ROLLBACK TO SAVEPOINT insert_anonymous; - -SAVEPOINT update_account; -DO $$ -BEGIN - INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); - INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); - INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); - - SET LOCAL role TO vibetype_account; - UPDATE vibetype.account_social_network SET social_network_username = 'username-updated'; -END $$; -ROLLBACK TO SAVEPOINT update_account; - -SAVEPOINT update_anonymous; -DO $$ -BEGIN - INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); - INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); - INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); - - SET LOCAL role TO vibetype_anonymous; - UPDATE vibetype.account_social_network SET social_network_username = 'username-updated'; - RAISE EXCEPTION 'Test update_anonymous failed: Anonymous users should not be able to update'; -EXCEPTION WHEN others THEN - NULL; -END $$; -ROLLBACK TO SAVEPOINT update_anonymous; - -SAVEPOINT delete_account; -DO $$ -BEGIN - INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); - INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); - INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); - - SET LOCAL role TO vibetype_account; - DELETE FROM vibetype.account_social_network; -END $$; -ROLLBACK TO SAVEPOINT delete_account; - -SAVEPOINT delete_anonymous; -DO $$ -BEGIN - INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); - INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); - INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); - - SET LOCAL role TO vibetype_anonymous; - DELETE FROM vibetype.account_social_network; - RAISE EXCEPTION 'Test delete_anonymous failed: Anonymous users should not be able to delete'; -EXCEPTION WHEN others THEN - NULL; -END $$; -ROLLBACK TO SAVEPOINT delete_anonymous; +-- in /test/logic/scenario/model/account_social_network.sql ROLLBACK; diff --git a/src/verify/table_address.sql b/src/verify/table_address.sql index 8cc3f9cc..5c6411ad 100644 --- a/src/verify/table_address.sql +++ b/src/verify/table_address.sql @@ -17,8 +17,4 @@ SELECT id, updated_by FROM vibetype.address WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['idx_address_location', 'idx_address_created_by', 'idx_address_updated_by'] -); - ROLLBACK; diff --git a/src/verify/table_device.sql b/src/verify/table_device.sql index 188649aa..9158547d 100644 --- a/src/verify/table_device.sql +++ b/src/verify/table_device.sql @@ -8,8 +8,5 @@ SELECT id, updated_by FROM vibetype.device WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['idx_device_updated_by', 'device_created_by_fcm_token_key'] -); ROLLBACK; diff --git a/src/verify/table_event.sql b/src/verify/table_event.sql index 90fd49e3..eb3164ff 100644 --- a/src/verify/table_event.sql +++ b/src/verify/table_event.sql @@ -18,8 +18,5 @@ SELECT id, search_vector FROM vibetype.event WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['event_created_by_slug_key', 'idx_event_search_vector'] -); ROLLBACK; diff --git a/src/verify/table_event_group.sql b/src/verify/table_event_group.sql index 3a7975f9..9d292a34 100644 --- a/src/verify/table_event_group.sql +++ b/src/verify/table_event_group.sql @@ -9,10 +9,6 @@ SELECT id, created_by FROM vibetype.event_group WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['event_group_created_by_slug_key'] -); - \set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` SET local role.vibetype_username TO :'role_service_vibetype_username'; diff --git a/src/verify/table_event_grouping.sql b/src/verify/table_event_grouping.sql index dd74bb19..56b8fd00 100644 --- a/src/verify/table_event_grouping.sql +++ b/src/verify/table_event_grouping.sql @@ -5,9 +5,6 @@ SELECT id, event_id FROM vibetype.event_grouping WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['event_grouping_event_id_event_group_id_key'] -); \set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` SET local role.vibetype_username TO :'role_service_vibetype_username'; diff --git a/src/verify/table_friendship.sql b/src/verify/table_friendship.sql index 07ecd853..7c97ce57 100644 --- a/src/verify/table_friendship.sql +++ b/src/verify/table_friendship.sql @@ -12,8 +12,4 @@ SELECT FROM vibetype.friendship WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['idx_friendship_created_by', 'idx_friendship_updated_by'] -); - ROLLBACK; diff --git a/src/verify/table_guest.sql b/src/verify/table_guest.sql index 23d670a4..a5442d89 100644 --- a/src/verify/table_guest.sql +++ b/src/verify/table_guest.sql @@ -9,8 +9,4 @@ SELECT id, updated_by FROM vibetype.guest WHERE FALSE; -SELECT vibetype_test.index_existence( - ARRAY ['guest_event_id_contact_id_key', 'idx_guest_updated_by'] -); - ROLLBACK; diff --git a/src/verify/test_location.sql b/src/verify/test_location.sql deleted file mode 100644 index a257e16e..00000000 --- a/src/verify/test_location.sql +++ /dev/null @@ -1,71 +0,0 @@ -BEGIN; - -DO $$ -DECLARE - _account_id UUID; - _coordinates DOUBLE PRECISION[]; - _event_id UUID; - _event_id_result UUID; - _legal_term_id UUID; -BEGIN - -- Register account - _account_id := vibetype_test.account_registration_verified('username', 'email@example.com'); - - -- Set account-specific context - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - - -- Create event - INSERT INTO vibetype.event(created_by, name, slug, start, visibility) - VALUES (_account_id, 'event', 'event', CURRENT_TIMESTAMP, 'public'::vibetype.event_visibility) - RETURNING id INTO _event_id; - - -- Update and validate account location - PERFORM vibetype_test.account_location_update(_account_id, 51.304, 9.476); -- Somewhere in Kassel - _coordinates := vibetype_test.account_location_coordinates(_account_id); - - IF NOT (round(_coordinates[1]::numeric, 3) = 51.304 AND round(_coordinates[2]::numeric, 3) = 9.476) THEN - RAISE EXCEPTION 'Wrong account coordinates'; - END IF; - - -- Update and validate event location - PERFORM vibetype_test.event_location_update(_event_id, 50.113, 8.650); -- Somewhere in Frankfurt - _coordinates := vibetype_test.event_location_coordinates(_event_id); - - IF NOT (round(_coordinates[1]::numeric, 3) = 50.113 AND round(_coordinates[2]::numeric, 3) = 8.650) THEN - RAISE EXCEPTION 'Wrong event coordinates'; - END IF; - - -- Test event filtering by radius from account - SELECT event_id INTO _event_id_result - FROM vibetype_test.event_filter_radius_account(_account_id, 100); - - IF _event_id_result IS NOT NULL THEN - RAISE EXCEPTION 'Function `event_filter_radius_account` with radius 100 km should have returned an empty result'; - END IF; - - SELECT event_id INTO _event_id_result - FROM vibetype_test.event_filter_radius_account(_account_id, 250); - - IF _event_id_result != _event_id THEN - RAISE EXCEPTION 'Function `event_filter_radius_account` with radius 250 km should have returned `_event_id`'; - END IF; - - -- Test account filtering by radius from event - SELECT account_id INTO _event_id_result - FROM vibetype_test.account_filter_radius_event(_event_id, 100); - - IF _event_id_result IS NOT NULL THEN - RAISE EXCEPTION 'Function `account_filter_radius_event` with radius 100 km should have returned an empty result'; - END IF; - - SELECT account_id INTO _event_id_result - FROM vibetype_test.account_filter_radius_event(_event_id, 250); - - IF _event_id_result != _account_id THEN - RAISE EXCEPTION 'Function `account_filter_radius_event` with radius 250 km should have returned `_account_id`'; - END IF; -END; -$$ LANGUAGE plpgsql; - -ROLLBACK; diff --git a/test/data.patch b/test/development/data.patch similarity index 100% rename from test/data.patch rename to test/development/data.patch diff --git a/test/schema/schema.definition.sql b/test/fixture/schema.definition.sql similarity index 85% rename from test/schema/schema.definition.sql rename to test/fixture/schema.definition.sql index d6f73ba3..27b32be6 100644 --- a/test/schema/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -97,22 +97,6 @@ ALTER SCHEMA vibetype_private OWNER TO ci; COMMENT ON SCHEMA vibetype_private IS 'Contains account information and is not used by PostGraphile.'; --- --- Name: vibetype_test; Type: SCHEMA; Schema: -; Owner: ci --- - -CREATE SCHEMA vibetype_test; - - -ALTER SCHEMA vibetype_test OWNER TO ci; - --- --- Name: SCHEMA vibetype_test; Type: COMMENT; Schema: -; Owner: ci --- - -COMMENT ON SCHEMA vibetype_test IS 'Schema for test functions.'; - - -- -- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: - -- @@ -2469,1049 +2453,124 @@ BEGIN _i := _i + 1; EXECUTE 'DROP TRIGGER ' || _record.trigger_name || ' ON ' || - _record.schema_name || '.' || _record.table_name; - END LOOP; - - IF _i = 0 THEN - RAISE NOTICE 'WARNING: Table %.% had no audit log trigger', - trigger_audit_log_drop.schema_name, trigger_audit_log_drop.table_name; - END IF; -END; -$$; - - -ALTER FUNCTION vibetype_private.trigger_audit_log_drop(schema_name text, table_name text) OWNER TO ci; - --- --- Name: FUNCTION trigger_audit_log_drop(schema_name text, table_name text); Type: COMMENT; Schema: vibetype_private; Owner: ci --- - -COMMENT ON FUNCTION vibetype_private.trigger_audit_log_drop(schema_name text, table_name text) IS 'Function dropping all audit log triggers for a single table.'; - - --- --- Name: trigger_audit_log_drop_multiple(); Type: FUNCTION; Schema: vibetype_private; Owner: ci --- - -CREATE FUNCTION vibetype_private.trigger_audit_log_drop_multiple() RETURNS void - LANGUAGE plpgsql SECURITY DEFINER - AS $$ -DECLARE - _record RECORD; -BEGIN - FOR _record IN - SELECT trigger_name, schema_name, table_name - FROM vibetype_private.audit_log_trigger - LOOP - EXECUTE 'DROP TRIGGER ' || _record.trigger_name || ' ON ' || _record.schema_name || '.' || _record.table_name; - END LOOP; -END; -$$; - - -ALTER FUNCTION vibetype_private.trigger_audit_log_drop_multiple() OWNER TO ci; - --- --- Name: FUNCTION trigger_audit_log_drop_multiple(); Type: COMMENT; Schema: vibetype_private; Owner: ci --- - -COMMENT ON FUNCTION vibetype_private.trigger_audit_log_drop_multiple() IS 'Function dropping all audit log triggers for all tables that are currently audited.'; - - --- --- Name: trigger_audit_log_enable(text, text); Type: FUNCTION; Schema: vibetype_private; Owner: ci --- - -CREATE FUNCTION vibetype_private.trigger_audit_log_enable(schema_name text, table_name text) RETURNS void - LANGUAGE plpgsql SECURITY DEFINER - AS $$ -DECLARE - _record RECORD; - _i INTEGER := 0; -BEGIN - FOR _record IN - SELECT t.trigger_name, t.schema_name, t.table_name, t.trigger_enabled - FROM vibetype_private.audit_log_trigger t - WHERE t.schema_name = trigger_audit_log_enable.schema_name - AND t.table_name = trigger_audit_log_enable.table_name - LOOP - _i := _i + 1; - - IF _record.trigger_enabled = 'D' THEN - EXECUTE 'ALTER TABLE ' || _record.schema_name || '.' || _record.table_name || ' ENABLE TRIGGER ' || _record.trigger_name; - END IF; - END LOOP; - - IF _i = 0 THEN - RAISE NOTICE 'WARNING: Table %.% has no audit log trigger', trigger_audit_log_enable.schema_name, trigger_audit_log_enable.table_name; - END IF; -END; -$$; - - -ALTER FUNCTION vibetype_private.trigger_audit_log_enable(schema_name text, table_name text) OWNER TO ci; - --- --- Name: FUNCTION trigger_audit_log_enable(schema_name text, table_name text); Type: COMMENT; Schema: vibetype_private; Owner: ci --- - -COMMENT ON FUNCTION vibetype_private.trigger_audit_log_enable(schema_name text, table_name text) IS 'Function enabling audit log triggers for a single table.'; - - --- --- Name: trigger_audit_log_enable_multiple(); Type: FUNCTION; Schema: vibetype_private; Owner: ci --- - -CREATE FUNCTION vibetype_private.trigger_audit_log_enable_multiple() RETURNS void - LANGUAGE plpgsql SECURITY DEFINER - AS $$ -DECLARE - _record RECORD; -BEGIN - FOR _record IN - SELECT trigger_name, schema_name, table_name - FROM vibetype_private.audit_log_trigger - WHERE trigger_enabled = 'D' - LOOP - EXECUTE 'ALTER TABLE ' || _record.schema_name || '.' || _record.table_name || ' ENABLE TRIGGER ' || _record.trigger_name; - END LOOP; -END; -$$; - - -ALTER FUNCTION vibetype_private.trigger_audit_log_enable_multiple() OWNER TO ci; - --- --- Name: FUNCTION trigger_audit_log_enable_multiple(); Type: COMMENT; Schema: vibetype_private; Owner: ci --- - -COMMENT ON FUNCTION vibetype_private.trigger_audit_log_enable_multiple() IS 'Function enabling all audit log triggers that are currently disabled.'; - - --- --- Name: account_block_create(uuid, uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.account_block_create(_created_by uuid, _blocked_account_id uuid) RETURNS uuid - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.account_block(created_by, blocked_account_id) - VALUES (_created_by, _blocked_Account_id) - RETURNING id INTO _id; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$; - - -ALTER FUNCTION vibetype_test.account_block_create(_created_by uuid, _blocked_account_id uuid) OWNER TO ci; - --- --- Name: account_block_remove(uuid, uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.account_block_remove(_created_by uuid, _blocked_account_id uuid) RETURNS void - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; -BEGIN - DELETE FROM vibetype.account_block - WHERE created_by = _created_by and blocked_account_id = _blocked_account_id; -END $$; - - -ALTER FUNCTION vibetype_test.account_block_remove(_created_by uuid, _blocked_account_id uuid) OWNER TO ci; - --- --- Name: account_filter_radius_event(uuid, double precision); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.account_filter_radius_event(_event_id uuid, _distance_max double precision) RETURNS TABLE(account_id uuid, distance double precision) - LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER - AS $$ -BEGIN - RETURN QUERY - WITH event AS ( - SELECT address_id - FROM vibetype.event - WHERE id = _event_id - ), - event_address AS ( - SELECT location - FROM vibetype.address - WHERE id = (SELECT address_id FROM event) - ) - SELECT - a.id AS account_id, - ST_Distance(e.location, a.location) AS distance - FROM - event_address e, - vibetype_private.account a - WHERE - ST_DWithin(e.location, a.location, _distance_max * 1000); -END; -$$; - - -ALTER FUNCTION vibetype_test.account_filter_radius_event(_event_id uuid, _distance_max double precision) OWNER TO ci; - --- --- Name: FUNCTION account_filter_radius_event(_event_id uuid, _distance_max double precision); Type: COMMENT; Schema: vibetype_test; Owner: ci --- - -COMMENT ON FUNCTION vibetype_test.account_filter_radius_event(_event_id uuid, _distance_max double precision) IS 'Returns account locations within a given radius around the location of an event.'; - - --- --- Name: account_location_coordinates(uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.account_location_coordinates(_account_id uuid) RETURNS double precision[] - LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER - AS $$ -DECLARE - _latitude DOUBLE PRECISION; - _longitude DOUBLE PRECISION; -BEGIN - SELECT - ST_Y(location::geometry), - ST_X(location::geometry) - INTO - _latitude, - _longitude - FROM - vibetype_private.account - WHERE - id = _account_id; - - RETURN ARRAY[_latitude, _longitude]; -END; -$$; - - -ALTER FUNCTION vibetype_test.account_location_coordinates(_account_id uuid) OWNER TO ci; - --- --- Name: FUNCTION account_location_coordinates(_account_id uuid); Type: COMMENT; Schema: vibetype_test; Owner: ci --- - -COMMENT ON FUNCTION vibetype_test.account_location_coordinates(_account_id uuid) IS 'Returns an array with latitude and longitude of the account''s current location data'; - - --- --- Name: account_location_update(uuid, double precision, double precision); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.account_location_update(_account_id uuid, _latitude double precision, _longitude double precision) RETURNS void - LANGUAGE plpgsql STRICT SECURITY DEFINER - AS $$ -BEGIN - UPDATE vibetype_private.account - SET - location = ST_Point(_longitude, _latitude, 4326) - WHERE - id = _account_id; -END; -$$; - - -ALTER FUNCTION vibetype_test.account_location_update(_account_id uuid, _latitude double precision, _longitude double precision) OWNER TO ci; - --- --- Name: FUNCTION account_location_update(_account_id uuid, _latitude double precision, _longitude double precision); Type: COMMENT; Schema: vibetype_test; Owner: ci --- - -COMMENT ON FUNCTION vibetype_test.account_location_update(_account_id uuid, _latitude double precision, _longitude double precision) IS 'Updates an account''s location based on latitude and longitude (GPS coordinates).'; - - --- --- Name: account_registration_verified(text, text); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.account_registration_verified(_username text, _email_address text) RETURNS uuid - LANGUAGE plpgsql - AS $$ -DECLARE - _account_id UUID; - _legal_term_id UUID; - _verification UUID; -BEGIN - _legal_term_id := vibetype_test.legal_term_singleton(); - PERFORM vibetype.account_registration(_email_address, 'en', _legal_term_id, 'password', _username); - - SELECT id INTO _account_id - FROM vibetype.account - WHERE username = _username; - - SELECT email_address_verification INTO _verification - FROM vibetype_private.account - WHERE id = _account_id; - - PERFORM vibetype.account_email_address_verification(_verification); - - RETURN _account_id; -END $$; - - -ALTER FUNCTION vibetype_test.account_registration_verified(_username text, _email_address text) OWNER TO ci; - --- --- Name: account_remove(text); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.account_remove(_username text) RETURNS void - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; -BEGIN - SELECT id INTO _id FROM vibetype.account WHERE username = _username; - - IF _id IS NOT NULL THEN - - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _id || ''''; - - DELETE FROM vibetype.event WHERE created_by = _id; - - PERFORM vibetype.account_delete('password'); - - CALL vibetype_test.set_local_superuser(); - END IF; -END $$; - - -ALTER FUNCTION vibetype_test.account_remove(_username text) OWNER TO ci; - --- --- Name: contact_create(uuid, text); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.contact_create(_created_by uuid, _email_address text) RETURNS uuid - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; - _account_id UUID; -BEGIN - SELECT id FROM vibetype_private.account WHERE email_address = _email_address INTO _account_id; - - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.contact(created_by, email_address) - VALUES (_created_by, _email_address) - RETURNING id INTO _id; - - IF (_account_id IS NOT NULL) THEN - UPDATE vibetype.contact SET account_id = _account_id WHERE id = _id; - END IF; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$; - - -ALTER FUNCTION vibetype_test.contact_create(_created_by uuid, _email_address text) OWNER TO ci; - --- --- Name: contact_select_by_account_id(uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.contact_select_by_account_id(_account_id uuid) RETURNS uuid - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; -BEGIN - SELECT id INTO _id - FROM vibetype.contact - WHERE created_by = _account_id AND account_id = _account_id; - - RETURN _id; -END $$; - - -ALTER FUNCTION vibetype_test.contact_select_by_account_id(_account_id uuid) OWNER TO ci; - --- --- Name: contact_test(text, uuid, uuid[]); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.contact_test(_test_case text, _account_id uuid, _expected_result uuid[]) RETURNS void - LANGUAGE plpgsql - AS $$ -DECLARE - rec RECORD; -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT id FROM vibetype.contact EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some contact should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.contact) THEN - RAISE EXCEPTION 'some contact is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.contact_test(_test_case text, _account_id uuid, _expected_result uuid[]) OWNER TO ci; - --- --- Name: event_category_create(text); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_category_create(_category text) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - INSERT INTO vibetype.event_category(name) VALUES (_category); -END $$; - - -ALTER FUNCTION vibetype_test.event_category_create(_category text) OWNER TO ci; - --- --- Name: event_category_mapping_create(uuid, uuid, text); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_category_mapping_create(_created_by uuid, _event_id uuid, _category text) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.event_category_mapping(event_id, category_id) - VALUES (_event_id, (SELECT id FROM vibetype.event_category WHERE name = _category)); - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.event_category_mapping_create(_created_by uuid, _event_id uuid, _category text) OWNER TO ci; - --- --- Name: event_category_mapping_test(text, uuid, uuid[]); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_category_mapping_test(_test_case text, _account_id uuid, _expected_result uuid[]) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT event_id FROM vibetype.event_category_mapping EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some event_category_mappings should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT event_id FROM vibetype.event_category_mapping) THEN - RAISE EXCEPTION 'some event_category_mappings is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.event_category_mapping_test(_test_case text, _account_id uuid, _expected_result uuid[]) OWNER TO ci; - --- --- Name: event_create(uuid, text, text, text, text); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_create(_created_by uuid, _name text, _slug text, _start text, _visibility text) RETURNS uuid - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.event(created_by, name, slug, start, visibility) - VALUES (_created_by, _name, _slug, _start::TIMESTAMP WITH TIME ZONE, _visibility::vibetype.event_visibility) - RETURNING id INTO _id; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$; - - -ALTER FUNCTION vibetype_test.event_create(_created_by uuid, _name text, _slug text, _start text, _visibility text) OWNER TO ci; - --- --- Name: event_filter_radius_account(uuid, double precision); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_filter_radius_account(_account_id uuid, _distance_max double precision) RETURNS TABLE(event_id uuid, distance double precision) - LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER - AS $$ -BEGIN - RETURN QUERY - WITH account AS ( - SELECT location - FROM vibetype_private.account - WHERE id = _account_id - ) - SELECT - e.id AS event_id, - ST_Distance(a.location, addr.location) AS distance - FROM - account a, - vibetype.event e - JOIN - vibetype.address addr ON e.address_id = addr.id - WHERE - ST_DWithin(a.location, addr.location, _distance_max * 1000); -END; -$$; - - -ALTER FUNCTION vibetype_test.event_filter_radius_account(_account_id uuid, _distance_max double precision) OWNER TO ci; - --- --- Name: FUNCTION event_filter_radius_account(_account_id uuid, _distance_max double precision); Type: COMMENT; Schema: vibetype_test; Owner: ci --- - -COMMENT ON FUNCTION vibetype_test.event_filter_radius_account(_account_id uuid, _distance_max double precision) IS 'Returns event locations within a given radius around the location of an account.'; - - --- --- Name: event_location_coordinates(uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_location_coordinates(_event_id uuid) RETURNS double precision[] - LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER - AS $$ -DECLARE - _latitude DOUBLE PRECISION; - _longitude DOUBLE PRECISION; -BEGIN - SELECT - ST_Y(a.location::geometry), - ST_X(a.location::geometry) - INTO - _latitude, - _longitude - FROM - vibetype.event e - JOIN - vibetype.address a ON e.address_id = a.id - WHERE - e.id = _event_id; - - RETURN ARRAY[_latitude, _longitude]; -END; -$$; - - -ALTER FUNCTION vibetype_test.event_location_coordinates(_event_id uuid) OWNER TO ci; - --- --- Name: FUNCTION event_location_coordinates(_event_id uuid); Type: COMMENT; Schema: vibetype_test; Owner: ci --- - -COMMENT ON FUNCTION vibetype_test.event_location_coordinates(_event_id uuid) IS 'Returns an array with latitude and longitude of the event''s current location data.'; - - --- --- Name: event_location_update(uuid, double precision, double precision); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_location_update(_event_id uuid, _latitude double precision, _longitude double precision) RETURNS void - LANGUAGE plpgsql STRICT SECURITY DEFINER - AS $$ -BEGIN - WITH event AS ( - SELECT address_id - FROM vibetype.event - WHERE id = _event_id - ) - UPDATE vibetype.address - SET - location = ST_Point(_longitude, _latitude, 4326) - WHERE - id = (SELECT address_id FROM event); -END; -$$; - - -ALTER FUNCTION vibetype_test.event_location_update(_event_id uuid, _latitude double precision, _longitude double precision) OWNER TO ci; - --- --- Name: FUNCTION event_location_update(_event_id uuid, _latitude double precision, _longitude double precision); Type: COMMENT; Schema: vibetype_test; Owner: ci --- - -COMMENT ON FUNCTION vibetype_test.event_location_update(_event_id uuid, _latitude double precision, _longitude double precision) IS 'Updates an event''s location based on latitude and longitude (GPS coordinates).'; - - --- --- Name: event_test(text, uuid, uuid[]); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.event_test(_test_case text, _account_id uuid, _expected_result uuid[]) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT id FROM vibetype.event EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some event should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.event) THEN - RAISE EXCEPTION 'some event is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.event_test(_test_case text, _account_id uuid, _expected_result uuid[]) OWNER TO ci; - --- --- Name: friendship_accept(uuid, uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.friendship_accept(_invoker_account_id uuid, _id uuid) RETURNS void - LANGUAGE plpgsql - AS $$ -DECLARE - rec RECORD; - _count INTEGER; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_account_id || ''''; - - UPDATE vibetype.friendship - SET "status" = 'accepted'::vibetype.friendship_status - WHERE id = _id; - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.friendship_accept(_invoker_account_id uuid, _id uuid) OWNER TO ci; - --- --- Name: friendship_account_ids_test(text, uuid, uuid[]); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.friendship_account_ids_test(_test_case text, _invoker_account_id uuid, _expected_result uuid[]) RETURNS void - LANGUAGE plpgsql SECURITY DEFINER - AS $$ -DECLARE - rec RECORD; -BEGIN - IF _invoker_account_id IS NULL THEN - SET LOCAL jwt.claims.account_id = ''; - ELSE - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_account_id || ''''; - END IF; - - IF EXISTS ( - WITH friendship_account_ids_test AS ( - SELECT b_account_id as account_id - FROM vibetype.friendship - WHERE a_account_id = _invoker_account_id - and status = 'accepted'::vibetype.friendship_status - UNION ALL - SELECT a_account_id as account_id - FROM vibetype.friendship - WHERE b_account_id = _invoker_account_id - and status = 'accepted'::vibetype.friendship_status - ) - SELECT account_id as id - FROM friendship_account_ids_test - WHERE account_id NOT IN (SELECT b.id FROM vibetype_private.account_block_ids() b) - EXCEPT - SELECT * FROM unnest(_expected_result) - ) THEN - RAISE EXCEPTION 'some accounts should not appear in the list of friends'; - END IF; - - IF EXISTS ( - WITH friendship_account_ids_test AS ( - SELECT b_account_id as account_id - FROM vibetype.friendship - WHERE a_account_id = vibetype.invoker_account_id() - and status = 'accepted'::vibetype.friendship_status - UNION ALL - SELECT a_account_id as account_id - FROM vibetype.friendship - WHERE b_account_id = vibetype.invoker_account_id() - and status = 'accepted'::vibetype.friendship_status - ) - SELECT * FROM unnest(_expected_result) - EXCEPT - SELECT account_id as id - FROM friendship_account_ids_test - WHERE account_id NOT IN (SELECT b.id FROM vibetype_private.account_block_ids() b) - ) THEN - RAISE EXCEPTION 'some account is missing in the list of friends'; - END IF; -END $$; - - -ALTER FUNCTION vibetype_test.friendship_account_ids_test(_test_case text, _invoker_account_id uuid, _expected_result uuid[]) OWNER TO ci; - --- --- Name: friendship_reject(uuid, uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.friendship_reject(_invoker_account_id uuid, _id uuid) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_account_id || ''''; - - DELETE FROM vibetype.friendship - WHERE id = _id; - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.friendship_reject(_invoker_account_id uuid, _id uuid) OWNER TO ci; - --- --- Name: friendship_request(uuid, uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.friendship_request(_invoker_account_id uuid, _friend_account_id uuid) RETURNS uuid - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; - _a_account_id UUID; - _b_account_id UUID; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_account_id || ''''; - - IF _invoker_account_id < _friend_account_id THEN - _a_account_id := _invoker_account_id; - _b_account_id := _friend_account_id; - ELSE - _a_account_id := _friend_account_id; - _b_account_id := _invoker_account_id; - END IF; - - INSERT INTO vibetype.friendship(a_account_id, b_account_id, created_by) - VALUES (_a_account_id, _b_account_id, _invoker_account_id) - RETURNING id INTO _id; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$; - - -ALTER FUNCTION vibetype_test.friendship_request(_invoker_account_id uuid, _friend_account_id uuid) OWNER TO ci; - --- --- Name: friendship_test(text, uuid, text, uuid[]); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.friendship_test(_test_case text, _invoker_account_id uuid, _status text, _expected_result uuid[]) RETURNS void - LANGUAGE plpgsql - AS $$ -DECLARE - rec RECORD; -BEGIN - IF _invoker_account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_account_id || ''''; - END IF; - - IF EXISTS ( - SELECT id FROM vibetype.friendship WHERE _status IS NULL OR status = _status::vibetype.friendship_status - EXCEPT - SELECT * FROM unnest(_expected_result) - ) THEN - RAISE EXCEPTION 'some accounts should not appear in the query result'; - END IF; - - IF EXISTS ( - SELECT * FROM unnest(_expected_result) - EXCEPT - SELECT id FROM vibetype.friendship WHERE _status IS NULL OR status = _status::vibetype.friendship_status - ) THEN - RAISE EXCEPTION 'some account is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.friendship_test(_test_case text, _invoker_account_id uuid, _status text, _expected_result uuid[]) OWNER TO ci; - --- --- Name: guest_claim_from_account_guest(uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.guest_claim_from_account_guest(_account_id uuid) RETURNS uuid[] - LANGUAGE plpgsql - AS $$ -DECLARE - _guest vibetype.guest; - _result UUID[] := ARRAY[]::UUID[]; - _text TEXT := ''; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - - -- reads all guests where _account_id is invited, - -- sets jwt.claims.guests to a string representation of these guests - -- and returns an array of these guests. - - FOR _guest IN - SELECT g.id - FROM vibetype.guest g JOIN vibetype.contact c - ON g.contact_id = c.id - WHERE c.account_id = _account_id - LOOP - _text := _text || ',"' || _guest.id || '"'; - _result := array_append(_result, _guest.id); - END LOOP; - - IF LENGTH(_text) > 0 THEN - _text := SUBSTR(_text, 2); - END IF; - - EXECUTE 'SET LOCAL jwt.claims.guests = ''[' || _text || ']'''; - - CALL vibetype_test.set_local_superuser(); - - RETURN _result; -END $$; - - -ALTER FUNCTION vibetype_test.guest_claim_from_account_guest(_account_id uuid) OWNER TO ci; - --- --- Name: guest_create(uuid, uuid, uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.guest_create(_created_by uuid, _event_id uuid, _contact_id uuid) RETURNS uuid - LANGUAGE plpgsql - AS $$ -DECLARE - _id UUID; -BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; - - INSERT INTO vibetype.guest(contact_id, event_id) - VALUES (_contact_id, _event_id) - RETURNING id INTO _id; - - CALL vibetype_test.set_local_superuser(); - - RETURN _id; -END $$; - - -ALTER FUNCTION vibetype_test.guest_create(_created_by uuid, _event_id uuid, _contact_id uuid) OWNER TO ci; - --- --- Name: guest_test(text, uuid, uuid[]); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.guest_test(_test_case text, _account_id uuid, _expected_result uuid[]) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - IF _account_id IS NULL THEN - SET LOCAL role = 'vibetype_anonymous'; - SET LOCAL jwt.claims.account_id = ''; - ELSE - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; - END IF; - - IF EXISTS (SELECT id FROM vibetype.guest EXCEPT SELECT * FROM unnest(_expected_result)) THEN - RAISE EXCEPTION 'some guest should not appear in the query result'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.guest) THEN - RAISE EXCEPTION 'some guest is missing in the query result'; - END IF; - - CALL vibetype_test.set_local_superuser(); -END $$; - - -ALTER FUNCTION vibetype_test.guest_test(_test_case text, _account_id uuid, _expected_result uuid[]) OWNER TO ci; - --- --- Name: index_existence(text[], text); Type: FUNCTION; Schema: vibetype_test; Owner: ci --- - -CREATE FUNCTION vibetype_test.index_existence(indexes text[], schema text DEFAULT 'vibetype'::text) RETURNS void - LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER - AS $$ -DECLARE - _existing_count INTEGER; - _expected_count INTEGER; -BEGIN - SELECT COUNT(*) INTO _existing_count - FROM pg_indexes - WHERE schemaname = index_existence.schema - AND indexname = ANY(index_existence.indexes); - - _expected_count := array_length(index_existence.indexes, 1); + _record.schema_name || '.' || _record.table_name; + END LOOP; - IF _existing_count <> _expected_count THEN - RAISE EXCEPTION 'Index mismatch in schema "%". Expected: %, Found: %', schema, _expected_count, _existing_count; + IF _i = 0 THEN + RAISE NOTICE 'WARNING: Table %.% had no audit log trigger', + trigger_audit_log_drop.schema_name, trigger_audit_log_drop.table_name; END IF; END; $$; -ALTER FUNCTION vibetype_test.index_existence(indexes text[], schema text) OWNER TO ci; +ALTER FUNCTION vibetype_private.trigger_audit_log_drop(schema_name text, table_name text) OWNER TO ci; -- --- Name: FUNCTION index_existence(indexes text[], schema text); Type: COMMENT; Schema: vibetype_test; Owner: ci +-- Name: FUNCTION trigger_audit_log_drop(schema_name text, table_name text); Type: COMMENT; Schema: vibetype_private; Owner: ci -- -COMMENT ON FUNCTION vibetype_test.index_existence(indexes text[], schema text) IS 'Checks whether the given indexes exist in the specified schema. Returns 1 if all exist, fails otherwise.'; +COMMENT ON FUNCTION vibetype_private.trigger_audit_log_drop(schema_name text, table_name text) IS 'Function dropping all audit log triggers for a single table.'; -- --- Name: invoker_set(uuid); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: trigger_audit_log_drop_multiple(); Type: FUNCTION; Schema: vibetype_private; Owner: ci -- -CREATE FUNCTION vibetype_test.invoker_set(_invoker_id uuid) RETURNS void - LANGUAGE plpgsql +CREATE FUNCTION vibetype_private.trigger_audit_log_drop_multiple() RETURNS void + LANGUAGE plpgsql SECURITY DEFINER AS $$ +DECLARE + _record RECORD; BEGIN - SET LOCAL role = 'vibetype_account'; - EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_id || ''''; -END $$; + FOR _record IN + SELECT trigger_name, schema_name, table_name + FROM vibetype_private.audit_log_trigger + LOOP + EXECUTE 'DROP TRIGGER ' || _record.trigger_name || ' ON ' || _record.schema_name || '.' || _record.table_name; + END LOOP; +END; +$$; -ALTER FUNCTION vibetype_test.invoker_set(_invoker_id uuid) OWNER TO ci; +ALTER FUNCTION vibetype_private.trigger_audit_log_drop_multiple() OWNER TO ci; -- --- Name: invoker_unset(); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: FUNCTION trigger_audit_log_drop_multiple(); Type: COMMENT; Schema: vibetype_private; Owner: ci -- -CREATE FUNCTION vibetype_test.invoker_unset() RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - CALL vibetype_test.set_local_superuser(); - EXECUTE 'SET LOCAL jwt.claims.account_id = '''''; -END $$; - +COMMENT ON FUNCTION vibetype_private.trigger_audit_log_drop_multiple() IS 'Function dropping all audit log triggers for all tables that are currently audited.'; -ALTER FUNCTION vibetype_test.invoker_unset() OWNER TO ci; -- --- Name: legal_term_singleton(); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: trigger_audit_log_enable(text, text); Type: FUNCTION; Schema: vibetype_private; Owner: ci -- -CREATE FUNCTION vibetype_test.legal_term_singleton() RETURNS uuid - LANGUAGE plpgsql +CREATE FUNCTION vibetype_private.trigger_audit_log_enable(schema_name text, table_name text) RETURNS void + LANGUAGE plpgsql SECURITY DEFINER AS $$ DECLARE - _id UUID; - _verification UUID; + _record RECORD; + _i INTEGER := 0; BEGIN - SELECT id INTO _id FROM vibetype.legal_term LIMIT 1; + FOR _record IN + SELECT t.trigger_name, t.schema_name, t.table_name, t.trigger_enabled + FROM vibetype_private.audit_log_trigger t + WHERE t.schema_name = trigger_audit_log_enable.schema_name + AND t.table_name = trigger_audit_log_enable.table_name + LOOP + _i := _i + 1; - IF (_id IS NULL) THEN - INSERT INTO vibetype.legal_term (term, version) VALUES ('Be excellent to each other', '0.0.0') - RETURNING id INTO _id; + IF _record.trigger_enabled = 'D' THEN + EXECUTE 'ALTER TABLE ' || _record.schema_name || '.' || _record.table_name || ' ENABLE TRIGGER ' || _record.trigger_name; + END IF; + END LOOP; + + IF _i = 0 THEN + RAISE NOTICE 'WARNING: Table %.% has no audit log trigger', trigger_audit_log_enable.schema_name, trigger_audit_log_enable.table_name; END IF; +END; +$$; - RETURN _id; -END $$; +ALTER FUNCTION vibetype_private.trigger_audit_log_enable(schema_name text, table_name text) OWNER TO ci; + +-- +-- Name: FUNCTION trigger_audit_log_enable(schema_name text, table_name text); Type: COMMENT; Schema: vibetype_private; Owner: ci +-- + +COMMENT ON FUNCTION vibetype_private.trigger_audit_log_enable(schema_name text, table_name text) IS 'Function enabling audit log triggers for a single table.'; -ALTER FUNCTION vibetype_test.legal_term_singleton() OWNER TO ci; -- --- Name: set_local_superuser(); Type: PROCEDURE; Schema: vibetype_test; Owner: ci +-- Name: trigger_audit_log_enable_multiple(); Type: FUNCTION; Schema: vibetype_private; Owner: ci -- -CREATE PROCEDURE vibetype_test.set_local_superuser() - LANGUAGE plpgsql +CREATE FUNCTION vibetype_private.trigger_audit_log_enable_multiple() RETURNS void + LANGUAGE plpgsql SECURITY DEFINER AS $$ DECLARE - _superuser_name TEXT; + _record RECORD; BEGIN - SELECT usename INTO _superuser_name - FROM pg_user - WHERE usesuper = true - ORDER BY usename - LIMIT 1; - - IF _superuser_name IS NOT NULL THEN - EXECUTE format('SET LOCAL role = %I', _superuser_name); - ELSE - RAISE NOTICE 'No superuser found!'; - END IF; -END $$; + FOR _record IN + SELECT trigger_name, schema_name, table_name + FROM vibetype_private.audit_log_trigger + WHERE trigger_enabled = 'D' + LOOP + EXECUTE 'ALTER TABLE ' || _record.schema_name || '.' || _record.table_name || ' ENABLE TRIGGER ' || _record.trigger_name; + END LOOP; +END; +$$; -ALTER PROCEDURE vibetype_test.set_local_superuser() OWNER TO ci; +ALTER FUNCTION vibetype_private.trigger_audit_log_enable_multiple() OWNER TO ci; -- --- Name: uuid_array_test(text, uuid[], uuid[]); Type: FUNCTION; Schema: vibetype_test; Owner: ci +-- Name: FUNCTION trigger_audit_log_enable_multiple(); Type: COMMENT; Schema: vibetype_private; Owner: ci -- -CREATE FUNCTION vibetype_test.uuid_array_test(_test_case text, _array uuid[], _expected_array uuid[]) RETURNS void - LANGUAGE plpgsql - AS $$ -BEGIN - IF EXISTS (SELECT * FROM unnest(_array) EXCEPT SELECT * FROM unnest(_expected_array)) THEN - RAISE EXCEPTION 'some uuid should not appear in the array'; - END IF; - - IF EXISTS (SELECT * FROM unnest(_expected_array) EXCEPT SELECT * FROM unnest(_array)) THEN - RAISE EXCEPTION 'some expected uuid is missing in the array'; - END IF; -END $$; - +COMMENT ON FUNCTION vibetype_private.trigger_audit_log_enable_multiple() IS 'Function enabling all audit log triggers that are currently disabled.'; -ALTER FUNCTION vibetype_test.uuid_array_test(_test_case text, _array uuid[], _expected_array uuid[]) OWNER TO ci; -- -- Name: changes; Type: TABLE; Schema: sqitch; Owner: ci @@ -7710,14 +6769,6 @@ GRANT USAGE ON SCHEMA vibetype TO vibetype_account; GRANT USAGE ON SCHEMA vibetype TO vibetype; --- --- Name: SCHEMA vibetype_test; Type: ACL; Schema: -; Owner: ci --- - -GRANT USAGE ON SCHEMA vibetype_test TO vibetype_anonymous; -GRANT USAGE ON SCHEMA vibetype_test TO vibetype_account; - - -- -- Name: FUNCTION armor(bytea); Type: ACL; Schema: public; Owner: ci -- @@ -8371,255 +7422,6 @@ REVOKE ALL ON FUNCTION vibetype_private.trigger_audit_log_enable(schema_name tex REVOKE ALL ON FUNCTION vibetype_private.trigger_audit_log_enable_multiple() FROM PUBLIC; --- --- Name: FUNCTION account_block_create(_created_by uuid, _blocked_account_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.account_block_create(_created_by uuid, _blocked_account_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.account_block_create(_created_by uuid, _blocked_account_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION account_block_remove(_created_by uuid, _blocked_account_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.account_block_remove(_created_by uuid, _blocked_account_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.account_block_remove(_created_by uuid, _blocked_account_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION account_filter_radius_event(_event_id uuid, _distance_max double precision); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.account_filter_radius_event(_event_id uuid, _distance_max double precision) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.account_filter_radius_event(_event_id uuid, _distance_max double precision) TO vibetype_account; - - --- --- Name: FUNCTION account_location_coordinates(_account_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.account_location_coordinates(_account_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.account_location_coordinates(_account_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION account_location_update(_account_id uuid, _latitude double precision, _longitude double precision); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.account_location_update(_account_id uuid, _latitude double precision, _longitude double precision) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.account_location_update(_account_id uuid, _latitude double precision, _longitude double precision) TO vibetype_account; - - --- --- Name: FUNCTION account_registration_verified(_username text, _email_address text); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.account_registration_verified(_username text, _email_address text) FROM PUBLIC; - - --- --- Name: FUNCTION account_remove(_username text); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.account_remove(_username text) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.account_remove(_username text) TO vibetype_account; - - --- --- Name: FUNCTION contact_create(_created_by uuid, _email_address text); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.contact_create(_created_by uuid, _email_address text) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.contact_create(_created_by uuid, _email_address text) TO vibetype_account; - - --- --- Name: FUNCTION contact_select_by_account_id(_account_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.contact_select_by_account_id(_account_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.contact_select_by_account_id(_account_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION contact_test(_test_case text, _account_id uuid, _expected_result uuid[]); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.contact_test(_test_case text, _account_id uuid, _expected_result uuid[]) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.contact_test(_test_case text, _account_id uuid, _expected_result uuid[]) TO vibetype_account; - - --- --- Name: FUNCTION event_category_create(_category text); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_category_create(_category text) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_category_create(_category text) TO vibetype_account; - - --- --- Name: FUNCTION event_category_mapping_create(_created_by uuid, _event_id uuid, _category text); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_category_mapping_create(_created_by uuid, _event_id uuid, _category text) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_category_mapping_create(_created_by uuid, _event_id uuid, _category text) TO vibetype_account; - - --- --- Name: FUNCTION event_category_mapping_test(_test_case text, _account_id uuid, _expected_result uuid[]); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_category_mapping_test(_test_case text, _account_id uuid, _expected_result uuid[]) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_category_mapping_test(_test_case text, _account_id uuid, _expected_result uuid[]) TO vibetype_account; - - --- --- Name: FUNCTION event_create(_created_by uuid, _name text, _slug text, _start text, _visibility text); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_create(_created_by uuid, _name text, _slug text, _start text, _visibility text) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_create(_created_by uuid, _name text, _slug text, _start text, _visibility text) TO vibetype_account; - - --- --- Name: FUNCTION event_filter_radius_account(_account_id uuid, _distance_max double precision); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_filter_radius_account(_account_id uuid, _distance_max double precision) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_filter_radius_account(_account_id uuid, _distance_max double precision) TO vibetype_account; - - --- --- Name: FUNCTION event_location_coordinates(_event_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_location_coordinates(_event_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_location_coordinates(_event_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION event_location_update(_event_id uuid, _latitude double precision, _longitude double precision); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_location_update(_event_id uuid, _latitude double precision, _longitude double precision) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_location_update(_event_id uuid, _latitude double precision, _longitude double precision) TO vibetype_account; - - --- --- Name: FUNCTION event_test(_test_case text, _account_id uuid, _expected_result uuid[]); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.event_test(_test_case text, _account_id uuid, _expected_result uuid[]) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.event_test(_test_case text, _account_id uuid, _expected_result uuid[]) TO vibetype_account; - - --- --- Name: FUNCTION friendship_accept(_invoker_account_id uuid, _id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.friendship_accept(_invoker_account_id uuid, _id uuid) FROM PUBLIC; - - --- --- Name: FUNCTION friendship_account_ids_test(_test_case text, _invoker_account_id uuid, _expected_result uuid[]); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.friendship_account_ids_test(_test_case text, _invoker_account_id uuid, _expected_result uuid[]) FROM PUBLIC; - - --- --- Name: FUNCTION friendship_reject(_invoker_account_id uuid, _id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.friendship_reject(_invoker_account_id uuid, _id uuid) FROM PUBLIC; - - --- --- Name: FUNCTION friendship_request(_invoker_account_id uuid, _friend_account_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.friendship_request(_invoker_account_id uuid, _friend_account_id uuid) FROM PUBLIC; - - --- --- Name: FUNCTION friendship_test(_test_case text, _invoker_account_id uuid, _status text, _expected_result uuid[]); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.friendship_test(_test_case text, _invoker_account_id uuid, _status text, _expected_result uuid[]) FROM PUBLIC; - - --- --- Name: FUNCTION guest_claim_from_account_guest(_account_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.guest_claim_from_account_guest(_account_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.guest_claim_from_account_guest(_account_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION guest_create(_created_by uuid, _event_id uuid, _contact_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.guest_create(_created_by uuid, _event_id uuid, _contact_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.guest_create(_created_by uuid, _event_id uuid, _contact_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION guest_test(_test_case text, _account_id uuid, _expected_result uuid[]); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.guest_test(_test_case text, _account_id uuid, _expected_result uuid[]) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.guest_test(_test_case text, _account_id uuid, _expected_result uuid[]) TO vibetype_account; - - --- --- Name: FUNCTION index_existence(indexes text[], schema text); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.index_existence(indexes text[], schema text) FROM PUBLIC; - - --- --- Name: FUNCTION invoker_set(_invoker_id uuid); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.invoker_set(_invoker_id uuid) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.invoker_set(_invoker_id uuid) TO vibetype_account; - - --- --- Name: FUNCTION invoker_unset(); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.invoker_unset() FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.invoker_unset() TO vibetype_account; - - --- --- Name: FUNCTION legal_term_singleton(); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.legal_term_singleton() FROM PUBLIC; - - --- --- Name: PROCEDURE set_local_superuser(); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON PROCEDURE vibetype_test.set_local_superuser() FROM PUBLIC; -GRANT ALL ON PROCEDURE vibetype_test.set_local_superuser() TO vibetype_anonymous; -GRANT ALL ON PROCEDURE vibetype_test.set_local_superuser() TO vibetype_account; - - --- --- Name: FUNCTION uuid_array_test(_test_case text, _array uuid[], _expected_array uuid[]); Type: ACL; Schema: vibetype_test; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype_test.uuid_array_test(_test_case text, _array uuid[], _expected_array uuid[]) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype_test.uuid_array_test(_test_case text, _array uuid[], _expected_array uuid[]) TO vibetype_account; - - -- -- Name: TABLE account; Type: ACL; Schema: vibetype; Owner: ci -- diff --git a/test/logic/main.sql b/test/logic/main.sql new file mode 100644 index 00000000..be97bbca --- /dev/null +++ b/test/logic/main.sql @@ -0,0 +1,64 @@ +\echo TEST_DIRECTORY = :TEST_DIRECTORY +\cd :TEST_DIRECTORY +\! pwd +\set USER_INITIAL :USER + +\echo ========================================================== +\echo connected as :USER +\echo create schema vibetype_test, test functions and run tests +\echo ========================================================== + +DROP SCHEMA IF EXISTS vibetype_test CASCADE; + +CREATE SCHEMA vibetype_test; +GRANT USAGE ON SCHEMA vibetype_test TO vibetype_anonymous, vibetype_account; + +\i utility/database/index.sql +\i utility/database/invoker.sql +\i utility/database/uuid.sql +\i utility/model/account_block.sql +\i utility/model/account_registration.sql +\i utility/model/account.sql +\i utility/model/contact.sql +\i utility/model/event_category_mapping.sql +\i utility/model/event_category.sql +\i utility/model/event.sql +\i utility/model/friendship.sql +\i utility/model/guest.sql +\i utility/model/legal_term.sql + +\i scenario/database/audit_log.sql +\i scenario/database/index_missing.sql +\i scenario/database/index.sql + +\echo ========================================================== +\echo connect as user postgraphile and run tests +\echo ========================================================== + +\c - postgraphile + +\i scenario/model/account_block.sql +\i scenario/model/account_registration.sql +\i scenario/model/account_social_network.sql +\i scenario/model/account.sql +\i scenario/model/authenticate.sql +\i scenario/model/event.sql +\i scenario/model/friendship.sql +\i scenario/model/guest.sql +-- \i scenario/model/invite.sql -- TODO: remove comment when PR "feat(notification)!: inherit invitations" has been merged +\i scenario/model/language_iso_full_text_search.sql + +\echo all tests completed sucessfully. + +\c - :USER_INITIAL + +\echo ========================================================== +\echo connect as :USER and drop schema vibetype_test +\echo ========================================================== + +\i utility/test/cleanup.sql + +DROP SCHEMA vibetype_test CASCADE; + +\echo schema vibetype_test dropped. +\echo DONE! diff --git a/test/logic/scenario/database/audit_log.sql b/test/logic/scenario/database/audit_log.sql new file mode 100644 index 00000000..84203cf6 --- /dev/null +++ b/test/logic/scenario/database/audit_log.sql @@ -0,0 +1,166 @@ +\echo test_audit_log... + +BEGIN; + +DO $$ +DECLARE + _record Record; + _count INTEGER; +BEGIN + --------------------------------------------------------- + -- drop all audit log triggers + + PERFORM vibetype_private.trigger_audit_log_drop_multiple(); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger; + + IF _count != 0 THEN + RAISE EXCEPTION 'There are still audit log triggers'; + END IF; + + --------------------------------------------------------- + -- create all audit log triggers + + PERFORM vibetype_private.trigger_audit_log_create_multiple(); + + -- check that no audit log triggers were created for vibetype_private.audit_log and vibetype_private.jwt + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger + WHERE schema_name = 'vibetype_private' AND table_name in ('audit_log', 'jwt'); + + IF _count != 0 THEN + RAISE EXCEPTION 'There must not be audit log triggers for vibetype_private.audit_log and vibetype_private.jwt'; + END IF; + + -- check that for all other tables with id column there is an audit log trigger + + _count := 0; + + FOR _record IN + SELECT schemaname, tablename + FROM pg_tables + WHERE schemaname IN ('vibetype', 'vibetype_private') + + EXCEPT + SELECT 'vibetype_private', 'audit_log' -- no audit log trigger for this table + EXCEPT + SELECT 'vibetype_private', 'jwt' -- no audit log trigger for this table + EXCEPT + SELECT schema_name, table_name + FROM vibetype_private.audit_log_trigger + LOOP + IF EXISTS ( + -- if current table has an id column there should have been an audti log trigger + SELECT 1 + FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid + JOIN pg_catalog.pg_attribute a ON c.oid = a.attrelid + WHERE c.relname = _record.tablename AND c.relkind = 'r' + AND n.nspname = _record.schemaname AND a.attname = 'id' + ) THEN + _count := _count + 1; + RAISE NOTICE 'Table % misses an audit log trigger', _record.schema_name || '.' || _record.table_name; + END IF; + END LOOP; + + IF _count != 0 THEN + RAISE EXCEPTION 'There are tables that should have an audit log trigger but have not.'; + END IF; + + --------------------------------------------------------- + -- disable all audit log triggers + + PERFORM vibetype_private.trigger_audit_log_disable_multiple(); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger + WHERE trigger_enabled != 'D'; + + IF _count != 0 THEN + RAISE EXCEPTION 'There is still an enabled audit log trigger.'; + END IF; + + --------------------------------------------------------- + -- enable all audit log triggers + + PERFORM vibetype_private.trigger_audit_log_enable_multiple(); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger + WHERE trigger_enabled = 'D'; + + IF _count != 0 THEN + RAISE EXCEPTION 'There is still a disabled audit log trigger.'; + END IF; + + --------------------------------------------------------- + -- disable the audit log trigger for a single table + + PERFORM vibetype_private.trigger_audit_log_disable ('vibetype', 'event'); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger + WHERE trigger_enabled != 'D' + AND schema_name = 'vibetype' AND table_name = 'event'; + + IF _count != 0 THEN + RAISE EXCEPTION 'The audit log trigger on table vibetype.event is still enabled.'; + END IF; + + --------------------------------------------------------- + -- enable the audit log trigger for a single table + + PERFORM vibetype_private.trigger_audit_log_enable ('vibetype', 'event'); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger + WHERE trigger_enabled = 'D' + AND schema_name = 'vibetype' AND table_name = 'event'; + + IF _count != 0 THEN + RAISE EXCEPTION 'The audit log trigger on table vibetype.event is still disabled.'; + END IF; + + --------------------------------------------------------- + -- drop all audit log triggers + + PERFORM vibetype_private.trigger_audit_log_drop_multiple(); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger; + + IF _count != 0 THEN + RAISE EXCEPTION 'There are still audit log triggers.'; + END IF; + + --------------------------------------------------------- + -- create an audit log trigger for a single table + + PERFORM vibetype_private.trigger_audit_log_create('vibetype', 'event'); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger + WHERE schema_name = 'vibetype' AND table_name = 'event'; + + IF _count != 1 THEN + RAISE EXCEPTION 'The audit log trigger for table vibetype.event has not been created.'; + END IF; + + --------------------------------------------------------- + -- drop the audit log trigger on a single table + + PERFORM vibetype_private.trigger_audit_log_drop('vibetype', 'event'); + + SELECT COUNT(*) INTO _count + FROM vibetype_private.audit_log_trigger + WHERE schema_name = 'vibetype' AND table_name = 'event'; + + IF _count != 0 THEN + RAISE EXCEPTION 'The audit log trigger for table vibetype.event was not dropped.'; + END IF; +END; +$$ LANGUAGE plpgsql; + +ROLLBACK; diff --git a/src/verify/test_postgres.sql b/test/logic/scenario/database/index.sql similarity index 69% rename from src/verify/test_postgres.sql rename to test/logic/scenario/database/index.sql index 0b01e604..5ba06325 100644 --- a/src/verify/test_postgres.sql +++ b/test/logic/scenario/database/index.sql @@ -1,5 +1,13 @@ +\echo test_index... + +-- test for existance of index on foreign keys + +SELECT vibetype_test.index_on_foreign_key_check(); + BEGIN; +-- test function vibetype_test.index_existence + CREATE TABLE vibetype_test.base (id UUID PRIMARY KEY, text TEXT); CREATE INDEX idx_base_text ON vibetype_test.base USING btree (text); CREATE TABLE vibetype.dependent (base_id UUID REFERENCES vibetype_test.base(id) ON DELETE CASCADE); @@ -120,3 +128,42 @@ DROP INDEX vibetype_test.idx_base_text; DROP TABLE vibetype_test.base; COMMIT; + +-- test for the existence of individual indexes + +SELECT vibetype_test.index_existence( + ARRAY ['idx_account_private_location'], + 'vibetype_private' +); + +SELECT vibetype_test.index_existence( + ARRAY ['account_block_created_by_blocked_account_id_key'] +); + +SELECT vibetype_test.index_existence( + ARRAY ['idx_address_location', 'idx_address_created_by', 'idx_address_updated_by'] +); + +SELECT vibetype_test.index_existence( + ARRAY ['idx_device_updated_by', 'device_created_by_fcm_token_key'] +); + +SELECT vibetype_test.index_existence( + ARRAY ['event_grouping_event_id_event_group_id_key'] +); + +SELECT vibetype_test.index_existence( + ARRAY ['event_created_by_slug_key', 'idx_event_search_vector'] +); + +SELECT vibetype_test.index_existence( + ARRAY ['idx_friendship_created_by', 'idx_friendship_updated_by'] +); + +SELECT vibetype_test.index_existence( + ARRAY ['event_group_created_by_slug_key'] +); + +SELECT vibetype_test.index_existence( + ARRAY ['guest_event_id_contact_id_key', 'idx_guest_updated_by'] +); diff --git a/test/index-missing.sql b/test/logic/scenario/database/index_missing.sql similarity index 100% rename from test/index-missing.sql rename to test/logic/scenario/database/index_missing.sql diff --git a/test/logic/scenario/model/account.sql b/test/logic/scenario/model/account.sql new file mode 100644 index 00000000..9092c967 --- /dev/null +++ b/test/logic/scenario/model/account.sql @@ -0,0 +1,59 @@ +\echo test_account... + +BEGIN; + +SAVEPOINT account_location; +DO $$ +DECLARE + _account_id UUID; + _coordinates DOUBLE PRECISION[]; +BEGIN + -- prepare account + _account_id := vibetype_test.account_registration_verified ('username', 'email@example.com'); + PERFORM vibetype_test.invoker_set(_account_id); + PERFORM vibetype_test.account_update_address_coordinates(_account_id, 51.304, 9.476); -- Somewhere in Kassel + + -- test coordinates + _coordinates := vibetype_test.account_select_address_coordinates(_account_id); + IF NOT (round(_coordinates[1]::numeric, 3) = 51.304 AND round(_coordinates[2]::numeric, 3) = 9.476) THEN + RAISE EXCEPTION 'Wrong account coordinates'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT account_location; + + +SAVEPOINT account_location_select; +DO $$ +DECLARE + _account_id UUID; + _event_id UUID; + _id UUID; +BEGIN + -- prepare account + _account_id := vibetype_test.account_registration_verified ('username', 'email@example.com'); + PERFORM vibetype_test.invoker_set(_account_id); + PERFORM vibetype_test.account_update_address_coordinates(_account_id, 51.304, 9.476); -- Somewhere in Kassel + + -- prepare event + INSERT INTO vibetype.event(created_by, name, slug, start, visibility) + VALUES (_account_id, 'event', 'event', CURRENT_TIMESTAMP, 'public'::vibetype.event_visibility) + RETURNING id INTO _event_id; + PERFORM vibetype_test.event_update_address_coordinates(_event_id, 50.113, 8.650); -- Somewhere in Frankfurt + + -- test exclusion + SELECT account_id INTO _id + FROM vibetype_test.account_select_by_event_distance(_event_id, 100); + IF _id IS NOT NULL THEN + RAISE EXCEPTION 'Function `account_select_by_event_distance` with radius 100 km should have returned an empty result'; + END IF; + + -- test inclusion + SELECT account_id INTO _id + FROM vibetype_test.account_select_by_event_distance(_event_id, 250); + IF _id != _account_id THEN + RAISE EXCEPTION 'Function `account_select_by_event_distance` with radius 250 km should have returned `_account_id`'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT account_location_select; + +ROLLBACK; diff --git a/src/verify/test_account_block.sql b/test/logic/scenario/model/account_block.sql similarity index 90% rename from src/verify/test_account_block.sql rename to test/logic/scenario/model/account_block.sql index 98291e74..050640c1 100644 --- a/src/verify/test_account_block.sql +++ b/test/logic/scenario/model/account_block.sql @@ -1,3 +1,5 @@ +\echo test_account_block... + BEGIN; DO $$ @@ -37,9 +39,9 @@ BEGIN -- remove accounts (if exist) - PERFORM vibetype_test.account_remove('a'); - PERFORM vibetype_test.account_remove('b'); - PERFORM vibetype_test.account_remove('c'); + PERFORM vibetype_test.account_delete('a'); + PERFORM vibetype_test.account_delete('b'); + PERFORM vibetype_test.account_delete('c'); -- fill with test data @@ -66,7 +68,7 @@ BEGIN END; -- A unblocks B - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); contactAB := vibetype_test.contact_create(accountA, 'b@example.com'); contactAC := vibetype_test.contact_create(accountA, 'c@example.com'); @@ -99,7 +101,7 @@ BEGIN END; -- A unblocks B - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); guestAB := vibetype_test.guest_create(accountA, eventA, contactAB); guestAC := vibetype_test.guest_create(accountA, eventA, contactAC); @@ -114,7 +116,7 @@ BEGIN BEGIN PERFORM vibetype_test.invoker_set(accountC); PERFORM vibetype.create_guests(eventC, ARRAY[contactCA, contactCB]); - PERFORM vibetype_test.invoker_unset(); + PERFORM vibetype_test.invoker_set_empty(); RAISE EXCEPTION 'User should not be able to add users as guests if one of the users is blocked'; EXCEPTION WHEN insufficient_privilege THEN @@ -125,11 +127,11 @@ BEGIN END; -- C unblocks B - PERFORM vibetype_test.account_block_remove(accountC, accountB); + PERFORM vibetype_test.account_block_delete(accountC, accountB); PERFORM vibetype_test.invoker_set(accountC); - -- TODO: try to extract to other test file (https://github.com/vibetype/sqitch/issues/142) + -- TODO: try to extract to other test file (https://github.com/maevsi/sqitch/issues/142) FOR rec IN SELECT * FROM vibetype.create_guests(eventC, ARRAY[contactCA, contactCB]) @@ -141,11 +143,11 @@ BEGIN END IF; END LOOP; - PERFORM vibetype_test.invoker_unset(); + PERFORM vibetype_test.invoker_set_empty(); -- run tests - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); PERFORM vibetype_test.event_test('event: no block, perspective A', accountA, ARRAY[eventA, eventB, eventC]::UUID[]); PERFORM vibetype_test.event_test('event: no block, perspective B', accountB, ARRAY[eventA, eventB, eventC]::UUID[]); @@ -153,7 +155,7 @@ BEGIN PERFORM vibetype_test.event_test('event: A blocks B, perspective A', accountA, ARRAY[eventA, eventC]::UUID[]); PERFORM vibetype_test.event_test('event: A blocks B, perspective B', accountB, ARRAY[eventB, eventC]::UUID[]); - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); PERFORM vibetype_test.event_category_mapping_test('event_category_mapping: no block, perspective A', accountA, ARRAY[eventA, eventB, eventC]::UUID[]); PERFORM vibetype_test.event_category_mapping_test('event_category_mapping: no block, perspective B', accountB, ARRAY[eventA, eventB, eventC]::UUID[]); @@ -161,7 +163,8 @@ BEGIN PERFORM vibetype_test.event_category_mapping_test('event_category_mapping: A blocks B, perspective A', accountA, ARRAY[eventA, eventC]::UUID[]); PERFORM vibetype_test.event_category_mapping_test('event_category_mapping: A blocks B, perspective B', accountB, ARRAY[eventB, eventC]::UUID[]); - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); + PERFORM vibetype_test.contact_test('contact: no block, perspective A', accountA, ARRAY[contactAA, contactAB, contactAC, contactBA, contactCA]::UUID[]); PERFORM vibetype_test.contact_test('contact: no block, perspective B', accountB, ARRAY[contactBB, contactBA, contactBC, contactAB, contactCB]::UUID[]); @@ -169,7 +172,7 @@ BEGIN PERFORM vibetype_test.contact_test('contact: A blocks B, perspective A', accountA, ARRAY[contactAA, contactAC, contactCA]::UUID[]); PERFORM vibetype_test.contact_test('contact: A blocks B, perspective B', accountB, ARRAY[contactBB, contactBC, contactCB]::UUID[]); - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); PERFORM vibetype_test.guest_test('guest: no block, perspective A', accountA, ARRAY[guestAB, guestAC, guestBA, guestCA]::UUID[]); PERFORM vibetype_test.guest_test('guest: no block, perspective B', accountB, ARRAY[guestBA, guestBC, guestAB, guestCB]::UUID[]); @@ -177,7 +180,7 @@ BEGIN PERFORM vibetype_test.guest_test('guest: A blocks B, perspective A', accountA, ARRAY[guestAC, guestCA]::UUID[]); PERFORM vibetype_test.guest_test('guest: A blocks B, perspective B', accountB, ARRAY[guestBC, guestCB]::UUID[]); - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); PERFORM vibetype_test.event_test('anonymous login: no block, events', null, ARRAY[eventA, eventB, eventC]::UUID[]); PERFORM vibetype_test.contact_test('anonymous login: no block, contacts', null, ARRAY[]::UUID[]); PERFORM vibetype_test.guest_test('anonymous login: no block, guests', null, ARRAY[]::UUID[]); @@ -188,7 +191,7 @@ BEGIN -- tests for function `guest_claim_array()` - PERFORM vibetype_test.account_block_remove(accountA, accountB); + PERFORM vibetype_test.account_block_delete(accountA, accountB); guestClaimArray := vibetype.guest_claim_array(); PERFORM vibetype_test.uuid_array_test('no block, guest claim is unset', guestClaimArray, ARRAY[]::UUID[]); diff --git a/test/logic/scenario/model/account_registration.sql b/test/logic/scenario/model/account_registration.sql new file mode 100644 index 00000000..a122c1d5 --- /dev/null +++ b/test/logic/scenario/model/account_registration.sql @@ -0,0 +1,122 @@ +\echo test_account_registration... + +BEGIN; + +SAVEPOINT function_privileges_for_roles; +DO $$ +BEGIN + IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.account_registration(TEXT, TEXT, UUID, TEXT, TEXT)', 'EXECUTE')) THEN + RAISE EXCEPTION 'Test function_privileges_for_roles failed: vibetype_account does not have EXECUTE privilege'; + END IF; + + IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.account_registration(TEXT, TEXT, UUID, TEXT, TEXT)', 'EXECUTE')) THEN + RAISE EXCEPTION 'Test function_privileges_for_roles failed: vibetype_anonymous does not have EXECUTE privilege'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT function_privileges_for_roles; + +SAVEPOINT account_registration; +DO $$ +DECLARE + _legal_term_id UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', 'username'); +END $$; +ROLLBACK TO SAVEPOINT account_registration; + +SAVEPOINT password_length; +DO $$ +DECLARE + _legal_term_id UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'short', 'username'); + RAISE EXCEPTION 'Test failed: Password length not enforced'; +EXCEPTION WHEN invalid_parameter_value THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT password_length; + +SAVEPOINT username_uniqueness; +DO $$ +DECLARE + _legal_term_id UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration('diff@example.com', 'en', _legal_term_id, 'password', 'username-duplicate'); + PERFORM vibetype.account_registration('erent@example.com', 'en', _legal_term_id, 'password', 'username-duplicate'); + RAISE EXCEPTION 'Test failed: Duplicate username not enforced'; +EXCEPTION WHEN unique_violation THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT username_uniqueness; + +SAVEPOINT email_uniqueness; +DO $$ +DECLARE + _legal_term_id UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration('duplicate@example.com', 'en', _legal_term_id, 'password', 'username-diff'); + PERFORM vibetype.account_registration('duplicate@example.com', 'en', _legal_term_id, 'password', 'username-erent'); +END $$; +ROLLBACK TO SAVEPOINT email_uniqueness; + +SAVEPOINT username_null; +DO $$ +DECLARE + _legal_term_id UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', NULL); + RAISE EXCEPTION 'Test failed: NULL username allowed'; +EXCEPTION WHEN OTHERS THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT username_null; + +SAVEPOINT username_length; +DO $$ +DECLARE + _legal_term_id UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', ''); + RAISE EXCEPTION 'Test failed: Empty username allowed'; +EXCEPTION WHEN OTHERS THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT username_length; + +SAVEPOINT notification; +DO $$ +DECLARE + _legal_term_id UUID; + _account_id UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration('email@example.com', 'en', _legal_term_id, 'password', 'username-8b973f'); + + SELECT id INTO _account_id + FROM vibetype.account + WHERE username = 'username-8b973f'; + + PERFORM vibetype_test.invoker_set(_account_id); + +/* TODO: remove comments when PR "feat(notification)!: inherit invitations" has been merged + IF NOT EXISTS ( + SELECT 1 FROM vibetype.notification + WHERE channel = 'account_registration' + AND payload::jsonb -> 'account' ->> 'username' = 'username-8b973f' + ) THEN + RAISE EXCEPTION 'Test failed: Notification not generated'; + END IF; +*/ + + PERFORM vibetype_test.invoker_set_empty(); + +END $$; +ROLLBACK TO SAVEPOINT notification; + +ROLLBACK; diff --git a/test/logic/scenario/model/account_social_network.sql b/test/logic/scenario/model/account_social_network.sql new file mode 100644 index 00000000..af3447d7 --- /dev/null +++ b/test/logic/scenario/model/account_social_network.sql @@ -0,0 +1,135 @@ +BEGIN; + +SAVEPOINT select_account; +DO $$ +BEGIN + SET LOCAL role TO vibetype_account; + PERFORM * FROM vibetype.account_social_network; +END $$; +ROLLBACK TO SAVEPOINT select_account; + +SAVEPOINT select_anonymous; +DO $$ +BEGIN + SET LOCAL role TO vibetype_anonymous; + PERFORM * FROM vibetype.account_social_network; +END $$; +ROLLBACK TO SAVEPOINT select_anonymous; + +SAVEPOINT insert_account; +DO $$ +DECLARE + _account_id UUID; +BEGIN + _account_id := vibetype_test.account_registration_verified('username', 'email@example.com'); + + PERFORM vibetype_test.invoker_set(_account_id); + + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES (_account_id, 'instagram', 'username'); + +END $$; +ROLLBACK TO SAVEPOINT insert_account; + +SAVEPOINT insert_anonymous; +DO $$ +DECLARE + _account_id UUID; +BEGIN + _account_id := vibetype_test.account_registration_verified('username', 'email@example.com'); + + PERFORM vibetype_test.invoker_set_anonymous(); + + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES (_account_id, 'instagram', 'username'); + + RAISE EXCEPTION 'Test insert_anonymous failed: Anonymous users should not be able to insert'; + +EXCEPTION WHEN others THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT insert_anonymous; + +SAVEPOINT update_account; +DO $$ +DECLARE + _account_id UUID; +BEGIN + _account_id := vibetype_test.account_registration_verified('username', 'email@example.com'); + + PERFORM vibetype_test.invoker_set(_account_id); + + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES (_account_id, 'instagram', 'username'); + + UPDATE vibetype.account_social_network SET social_network_username = 'username-updated'; + +END $$; +ROLLBACK TO SAVEPOINT update_account; + +SAVEPOINT update_anonymous; +DO $$ +DECLARE + _account_id UUID; +BEGIN + _account_id := vibetype_test.account_registration_verified('username', 'email@example.com'); + + PERFORM vibetype_test.invoker_set(_account_id); + + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES (_account_id, 'instagram', 'username'); + + PERFORM vibetype_test.invoker_set_anonymous(); + + UPDATE vibetype.account_social_network SET social_network_username = 'username-updated'; + + RAISE EXCEPTION 'Test update_anonymous failed: Anonymous users should not be able to update'; + +EXCEPTION WHEN others THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT update_anonymous; + +SAVEPOINT delete_account; +DO $$ +DECLARE + _account_id UUID; +BEGIN + _account_id := vibetype_test.account_registration_verified('username', 'email@example.com'); + + PERFORM vibetype_test.invoker_set(_account_id); + + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES (_account_id, 'instagram', 'username'); + + PERFORM vibetype_test.invoker_set(_account_id); + + DELETE FROM vibetype.account_social_network; + +END $$; +ROLLBACK TO SAVEPOINT delete_account; + +SAVEPOINT delete_anonymous; +DO $$ +DECLARE + _account_id UUID; +BEGIN + _account_id := vibetype_test.account_registration_verified('username', 'email@example.com'); + + PERFORM vibetype_test.invoker_set(_account_id); + + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES (_account_id, 'instagram', 'username'); + + PERFORM vibetype_test.invoker_set_anonymous(); + + DELETE FROM vibetype.account_social_network; + + RAISE EXCEPTION 'Test delete_anonymous failed: Anonymous users should not be able to delete'; + +EXCEPTION WHEN others THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT delete_anonymous; + +ROLLBACK; diff --git a/test/logic/scenario/model/authenticate.sql b/test/logic/scenario/model/authenticate.sql new file mode 100644 index 00000000..62125c0e --- /dev/null +++ b/test/logic/scenario/model/authenticate.sql @@ -0,0 +1,128 @@ +\echo test_authenticate... + +BEGIN; + +SAVEPOINT privileges; +DO $$ +BEGIN + IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.authenticate(TEXT, TEXT)', 'EXECUTE')) THEN + RAISE EXCEPTION 'Test privileges failed: vibetype_account does not have EXECUTE privilege'; + END IF; + + IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.authenticate(TEXT, TEXT)', 'EXECUTE')) THEN + RAISE EXCEPTION 'Test privileges failed: vibetype_anonymous does not have EXECUTE privilege'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT privileges; + +SAVEPOINT username_success; +DO $$ +DECLARE + _jwt vibetype.jwt; +BEGIN + PERFORM vibetype_test.account_registration_verified ('username', 'email@example.com'); + + _jwt := vibetype.authenticate('username', 'password'); + + IF _jwt IS NULL THEN + RAISE EXCEPTION 'Test failed: Authentication should have returned a JWT'; + END IF; + + IF _jwt.account_username <> 'username' THEN + RAISE EXCEPTION 'Test failed: JWT contains an incorrect username'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT username_success; + +SAVEPOINT username_incorrect; +DO $$ +DECLARE + _jwt vibetype.jwt; + +BEGIN + PERFORM vibetype_test.account_registration_verified ('username', 'email@example.com'); + + BEGIN + _jwt := vibetype.authenticate('username_incorrect', 'password'); + EXCEPTION WHEN no_data_found THEN + NULL; + END; +END $$; +ROLLBACK TO SAVEPOINT username_incorrect; + +SAVEPOINT username_password_incorrect; +DO $$ +DECLARE + _jwt vibetype.jwt; +BEGIN + PERFORM vibetype_test.account_registration_verified ('username', 'email@example.com'); + + BEGIN + _jwt := vibetype.authenticate('username', 'password_incorrect'); + EXCEPTION WHEN no_data_found THEN + NULL; + END; + + IF _jwt IS NOT NULL THEN + RAISE EXCEPTION 'Test failed: Authentication should not have returned a JWT'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT username_password_incorrect; + +SAVEPOINT email_success; +DO $$ +DECLARE + _jwt vibetype.jwt; +BEGIN + PERFORM vibetype_test.account_registration_verified ('username', 'email@example.com'); + _jwt := vibetype.authenticate('email@example.com', 'password'); + + IF _jwt IS NULL THEN + RAISE EXCEPTION 'Test failed: Authentication should have returned a JWT'; + END IF; + + IF _jwt.account_username <> 'username' THEN + RAISE EXCEPTION 'Test failed: JWT contains an incorrect user name'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT email_success; + +SAVEPOINT email_incorrect; +DO $$ +DECLARE + _jwt vibetype.jwt; +BEGIN + PERFORM vibetype_test.account_registration_verified ('username', 'email@example.com'); + + BEGIN + _jwt := vibetype.authenticate('email_incorrect@example.com', 'password'); + EXCEPTION WHEN no_data_found THEN + NULL; + END; + + IF _jwt IS NOT NULL THEN + RAISE EXCEPTION 'Test failed: Authentication should not have returned a JWT'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT email_incorrect; + +SAVEPOINT email_password_incorrect; +DO $$ +DECLARE + _jwt vibetype.jwt; +BEGIN + PERFORM vibetype_test.account_registration_verified ('username', 'email@example.com'); + + BEGIN + _jwt := vibetype.authenticate('email@example.com', 'password_incorrect'); + EXCEPTION WHEN no_data_found THEN + NULL; + END; + + IF _jwt IS NOT NULL THEN + RAISE EXCEPTION 'Test failed: Authentication should not have returned a JWT'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT email_password_incorrect; + +ROLLBACK; diff --git a/test/logic/scenario/model/event.sql b/test/logic/scenario/model/event.sql new file mode 100644 index 00000000..c9cc0bc9 --- /dev/null +++ b/test/logic/scenario/model/event.sql @@ -0,0 +1,65 @@ +\echo test_event... + +BEGIN; + +SAVEPOINT event_location; +DO $$ +DECLARE + _account_id UUID; + _event_id UUID; + _coordinates DOUBLE PRECISION[]; +BEGIN + -- prepare account + _account_id := vibetype_test.account_registration_verified ('username', 'email@example.com'); + PERFORM vibetype_test.invoker_set(_account_id); + + -- prepare event + INSERT INTO vibetype.event(created_by, name, slug, start, visibility) + VALUES (_account_id, 'event', 'event', CURRENT_TIMESTAMP, 'public'::vibetype.event_visibility) + RETURNING id INTO _event_id; + PERFORM vibetype_test.event_update_address_coordinates(_event_id, 50.113, 8.650); -- Somewhere in Frankfurt + + -- test coordinates + _coordinates := vibetype_test.event_select_address_coordinates(_event_id); + IF NOT (round(_coordinates[1]::numeric, 3) = 50.113 AND round(_coordinates[2]::numeric, 3) = 8.650) THEN + RAISE EXCEPTION 'Wrong event coordinates'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT event_location; + + +SAVEPOINT event_location_select; +DO $$ +DECLARE + _account_id UUID; + _event_id UUID; + _id UUID; +BEGIN + -- prepare account + _account_id := vibetype_test.account_registration_verified ('username', 'email@example.com'); + PERFORM vibetype_test.invoker_set(_account_id); + PERFORM vibetype_test.account_update_address_coordinates(_account_id, 51.304, 9.476); -- Somewhere in Kassel + + -- prepare event + INSERT INTO vibetype.event(created_by, name, slug, start, visibility) + VALUES (_account_id, 'event', 'event', CURRENT_TIMESTAMP, 'public'::vibetype.event_visibility) + RETURNING id INTO _event_id; + PERFORM vibetype_test.event_update_address_coordinates(_event_id, 50.113, 8.650); -- Somewhere in Frankfurt + + -- test exclusion + SELECT event_id INTO _id + FROM vibetype_test.event_select_by_account_distance(_account_id, 100); + IF _id IS NOT NULL THEN + RAISE EXCEPTION 'Function `event_select_by_account_distance` with radius 100 km should have returned an empty result'; + END IF; + + -- test inclusion + SELECT event_id INTO _id + FROM vibetype_test.event_select_by_account_distance(_account_id, 250); + IF _id != _event_id THEN + RAISE EXCEPTION 'Function `event_select_by_account_distance` with radius 250 km should have returned `_event_id`'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT event_location_select; + +ROLLBACK; diff --git a/src/verify/test_friendship.sql b/test/logic/scenario/model/friendship.sql similarity index 99% rename from src/verify/test_friendship.sql rename to test/logic/scenario/model/friendship.sql index a85715b5..b6b6d358 100644 --- a/src/verify/test_friendship.sql +++ b/test/logic/scenario/model/friendship.sql @@ -1,3 +1,5 @@ +\echo test_friendship.. + BEGIN; DO $$ diff --git a/test/logic/scenario/model/guest.sql b/test/logic/scenario/model/guest.sql new file mode 100644 index 00000000..1123eca4 --- /dev/null +++ b/test/logic/scenario/model/guest.sql @@ -0,0 +1,40 @@ +\echo test_invitation... + +BEGIN; + +DO $$ +DECLARE + accountA UUID; + accountB UUID; + accountC UUID; + + contactAB UUID; + contactAC UUID; + eventA UUID; + + guest_ids UUID[]; + + rec RECORD; + +BEGIN + + accountA := vibetype_test.account_registration_verified('a', 'a@example.com'); + accountB := vibetype_test.account_registration_verified('b', 'b@example.com'); + accountC := vibetype_test.account_registration_verified('c', 'c@example.com'); + + contactAB := vibetype_test.contact_create(accountA, 'b@example.com'); + contactAC := vibetype_test.contact_create(accountA, 'c@example.com'); + + eventA := vibetype_test.event_create(accountA, 'Event by A', 'event-by-a', '2025-06-01 20:00', 'public'); + + PERFORM vibetype_test.invoker_set(accountA); + + guest_ids := ARRAY(SELECT id FROM vibetype.create_guests(eventA, ARRAY[contactAB, contactAC])); + + PERFORM vibetype_test.invoker_set_empty(); + + PERFORM vibetype_test.guest_create_multiple_test('create multiple guest records', accountA, eventA, ARRAY[contactAB, contactAC], guest_ids); + +END $$ LANGUAGE plpgsql; + +ROLLBACK; diff --git a/test/logic/scenario/model/invite.sql b/test/logic/scenario/model/invite.sql new file mode 100644 index 00000000..6f1da9b2 --- /dev/null +++ b/test/logic/scenario/model/invite.sql @@ -0,0 +1,40 @@ +\echo test_invitation... + +BEGIN; + +DO $$ +DECLARE + accountA UUID; + accountB UUID; + + contactAB UUID; + eventA UUID; + guestAB UUID; + + invitationId UUID; + + rec RECORD; + +BEGIN + + accountA := vibetype_test.account_registration_verified('a', 'a@example.com'); + accountB := vibetype_test.account_registration_verified('b', 'b@example.com'); + contactAB := vibetype_test.contact_create(accountA, 'b@example.com'); + eventA := vibetype_test.event_create(accountA, 'Event by A', 'event-by-a', '2025-06-01 20:00', 'public'); + guestAB := vibetype_test.guest_create(accountA, eventA, contactAB); + + PERFORM vibetype_test.invoker_set(accountA); + + invitationId := vibetype.invite(guestAB, 'de'); + + SELECT guest_id, created_by, channel INTO rec + FROM vibetype.notification_invitation + WHERE id = invitationId; + + IF rec.guest_id != guestAB or rec.created_by != accountA or rec.channel != 'event_invitation' THEN + RAISE EXCEPTION 'The invitation was not correctly created'; + END IF; + +END $$ LANGUAGE plpgsql; + +ROLLBACK; \ No newline at end of file diff --git a/test/logic/scenario/model/language_iso_full_text_search.sql b/test/logic/scenario/model/language_iso_full_text_search.sql new file mode 100644 index 00000000..590bebea --- /dev/null +++ b/test/logic/scenario/model/language_iso_full_text_search.sql @@ -0,0 +1,63 @@ +\echo test_full_text_search... + +BEGIN; + +SAVEPOINT privileges; +DO $$ +BEGIN + IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.language_iso_full_text_search(vibetype.language)', 'EXECUTE')) THEN + RAISE EXCEPTION 'Test privileges failed: vibetype_account does not have EXECUTE privilege'; + END IF; + + IF NOT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.language_iso_full_text_search(vibetype.language)', 'EXECUTE')) THEN + RAISE EXCEPTION 'Test privileges failed: vibetype_anonymous does not have EXECUTE privilege'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT privileges; + +SAVEPOINT success; +DO $$ +DECLARE + _language vibetype.language; + _result regconfig; +BEGIN + FOREACH _language IN ARRAY + ARRAY['de', 'en', NULL] + LOOP + CASE _language + WHEN 'de' THEN _result := 'pg_catalog.german'; + WHEN 'en' THEN _result := 'pg_catalog.english'; + ELSE _result := 'pg_catalog.simple'; + END CASE; + + IF vibetype.language_iso_full_text_search(_language) != _result THEN + RAISE EXCEPTION 'Test failed for input %: Expected % but got %', _language, _result, vibetype.language_iso_full_text_search(lang_code); + END IF; + END LOOP; +END $$; +ROLLBACK TO SAVEPOINT success; + +SAVEPOINT strict; +DO $$ +BEGIN + IF vibetype.language_iso_full_text_search(NULL::vibetype.language) IS NULL THEN + RAISE EXCEPTION 'Test failed for NULL input. Did not expect to get NULL.'; + END IF; +END $$; +ROLLBACK TO SAVEPOINT strict; + +SAVEPOINT invalid; +DO $$ +BEGIN + BEGIN + PERFORM vibetype.language_iso_full_text_search('invalid'::vibetype.language); + EXCEPTION + WHEN OTHERS THEN + RETURN; + END; + + RAISE EXCEPTION 'Test failed: Invalid language ''invalid'' should have raised an exception but did not.'; +END $$; +ROLLBACK TO SAVEPOINT invalid; + +ROLLBACK; diff --git a/test/logic/utility/database/index.sql b/test/logic/utility/database/index.sql new file mode 100644 index 00000000..000b9af3 --- /dev/null +++ b/test/logic/utility/database/index.sql @@ -0,0 +1,61 @@ +CREATE OR REPLACE FUNCTION vibetype_test.index_existence( + indexes TEXT[], + schema TEXT DEFAULT 'vibetype' +) RETURNS VOID AS $$ +DECLARE + _existing_count INTEGER; + _expected_count INTEGER; +BEGIN + SELECT COUNT(*) INTO _existing_count + FROM pg_indexes + WHERE schemaname = index_existence.schema + AND indexname = ANY(index_existence.indexes); + + _expected_count := array_length(index_existence.indexes, 1); + + IF _existing_count <> _expected_count THEN + RAISE EXCEPTION 'Index mismatch in schema "%". Expected: %, Found: %', schema, _expected_count, _existing_count; + END IF; +END; +$$ LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER; + +COMMENT ON FUNCTION vibetype_test.index_existence(TEXT[], TEXT) IS 'Checks whether the given indexes exist in the specified schema. Returns 1 if all exist, fails otherwise.';; + + +CREATE OR REPLACE FUNCTION vibetype_test.index_on_foreign_key_check() +RETURNS VOID AS $$ +DECLARE + rec RECORD; + violation_details TEXT := ''; +BEGIN + FOR rec IN + WITH index_not_found AS ( + SELECT n.nspname, t.relname, c.conname, c.conkey + FROM pg_constraint c + JOIN pg_class t ON (c.conrelid = t.oid) + JOIN pg_namespace n ON (t.relnamespace = n.oid) + WHERE c.contype = 'f' AND t.relkind = 'r' + AND n.nspname IN ('vibetype', 'vibetype_private') + AND (n.nspname, t.relname, c.conkey) NOT IN ( + SELECT n.nspname, t.relname, string_to_array(i.indkey::text, ' ')::smallint[] AS indkey + FROM pg_index i + JOIN pg_class t ON (i.indrelid = t.oid) + JOIN pg_namespace n ON (t.relnamespace = n.oid) + WHERE t.relkind = 'r' + AND n.nspname IN ('vibetype', 'vibetype_private') + ) + ) + SELECT nspname || '.' || relname || ':' || conname || ',' || conkey::TEXT AS violation_details + FROM index_not_found + ORDER BY nspname, relname, conname + LOOP + violation_details := violation_details || E'\n' || rec.violation_details; + END LOOP; + + -- If missing indexes exist, raise an exception + IF LENGTH(violation_details) > 0 THEN +-- RAISE EXCEPTION E'Foreign key constraints without indexes:\n%', violation_details; + RAISE NOTICE E'Foreign key constraints without indexes:\n%', violation_details; + END IF; +END; +$$ LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER; diff --git a/test/logic/utility/database/invoker.sql b/test/logic/utility/database/invoker.sql new file mode 100644 index 00000000..890736a8 --- /dev/null +++ b/test/logic/utility/database/invoker.sql @@ -0,0 +1,30 @@ +CREATE OR REPLACE FUNCTION vibetype_test.invoker_set ( + _invoker_id UUID +) +RETURNS VOID AS $$ +BEGIN + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _invoker_id || ''''; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.invoker_set(UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.invoker_set_anonymous () +RETURNS VOID AS $$ +BEGIN + SET LOCAL ROLE = 'vibetype_anonymous'; + EXECUTE 'SET LOCAL jwt.claims.account_id = '''''; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.invoker_set_anonymous() TO vibetype_account, vibetype_anonymous; + + +CREATE OR REPLACE FUNCTION vibetype_test.invoker_set_empty () +RETURNS VOID AS $$ +BEGIN + SET LOCAL ROLE NONE; + EXECUTE 'SET LOCAL jwt.claims.account_id = '''''; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.invoker_set_empty() TO vibetype_account; diff --git a/test/logic/utility/database/uuid.sql b/test/logic/utility/database/uuid.sql new file mode 100644 index 00000000..13b37dcc --- /dev/null +++ b/test/logic/utility/database/uuid.sql @@ -0,0 +1,17 @@ +CREATE OR REPLACE FUNCTION vibetype_test.uuid_array_test ( + _test_case TEXT, + _array UUID[], + _expected_array UUID[] +) +RETURNS VOID AS $$ +BEGIN + IF EXISTS (SELECT * FROM unnest(_array) EXCEPT SELECT * FROM unnest(_expected_array)) THEN + RAISE EXCEPTION '%: some uuid should not appear in the array', _test_case; + END IF; + + IF EXISTS (SELECT * FROM unnest(_expected_array) EXCEPT SELECT * FROM unnest(_array)) THEN + RAISE EXCEPTION '%: some expected uuid is missing in the array', _test_case; + END IF; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.uuid_array_test(TEXT, UUID[], UUID[]) TO vibetype_account; diff --git a/test/logic/utility/model/account.sql b/test/logic/utility/model/account.sql new file mode 100644 index 00000000..9a5475ae --- /dev/null +++ b/test/logic/utility/model/account.sql @@ -0,0 +1,123 @@ +CREATE OR REPLACE FUNCTION vibetype_test.account_delete ( + _username TEXT +) RETURNS VOID AS $$ +DECLARE + _id UUID; +BEGIN + SELECT id INTO _id FROM vibetype.account WHERE username = _username; + + IF _id IS NOT NULL THEN + + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _id || ''''; + + DELETE FROM vibetype.event WHERE created_by = _id; + + PERFORM vibetype.account_delete('password'); + + SET LOCAL ROLE NONE; + END IF; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_delete(TEXT) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.account_select_address_coordinates( + _account_id UUID +) +RETURNS DOUBLE PRECISION[] AS $$ +DECLARE + _latitude DOUBLE PRECISION; + _longitude DOUBLE PRECISION; +BEGIN + SELECT + ST_Y(location::geometry), + ST_X(location::geometry) + INTO + _latitude, + _longitude + FROM + vibetype_private.account + WHERE + id = _account_id; + + RETURN ARRAY[_latitude, _longitude]; +END; +$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; + +COMMENT ON FUNCTION vibetype_test.account_select_address_coordinates(UUID) IS 'Returns an array with latitude and longitude of the account''s current location data'; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_select_address_coordinates(UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.account_select_by_email_address(_email_address text) +RETURNS UUID AS $$ +DECLARE + _account_id UUID; +BEGIN + SELECT id + INTO _account_id + FROM vibetype_private.account + WHERE email_address = _email_address; + + RETURN _account_id; +END; +$$ LANGUAGE plpgsql STRICT SECURITY DEFINER; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_select_by_email_address(TEXT) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.account_select_by_event_distance( + _event_id UUID, + _distance_max DOUBLE PRECISION +) +RETURNS TABLE ( + account_id UUID, + distance DOUBLE PRECISION +) AS $$ +BEGIN + RETURN QUERY + WITH event AS ( + SELECT address_id + FROM vibetype.event + WHERE id = _event_id + ), + event_address AS ( + SELECT location + FROM vibetype.address + WHERE id = (SELECT address_id FROM event) + ) + SELECT + a.id AS account_id, + ST_Distance(e.location, a.location) AS distance + FROM + event_address e, + vibetype_private.account a + WHERE + ST_DWithin(e.location, a.location, _distance_max * 1000); +END; +$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; + +COMMENT ON FUNCTION vibetype_test.account_select_by_event_distance(UUID, DOUBLE PRECISION) IS 'Returns account locations within a given radius around the location of an event.'; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_select_by_event_distance(UUID, DOUBLE PRECISION) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.account_update_address_coordinates( + _account_id UUID, + _latitude DOUBLE PRECISION, + _longitude DOUBLE PRECISION +) +RETURNS VOID AS $$ +BEGIN + UPDATE vibetype_private.account + SET + location = ST_Point(_longitude, _latitude, 4326) + WHERE + id = _account_id; +END; +$$ LANGUAGE PLPGSQL STRICT SECURITY DEFINER; + +COMMENT ON FUNCTION vibetype_test.account_update_address_coordinates(UUID, DOUBLE PRECISION, DOUBLE PRECISION) IS 'Updates an account''s location based on latitude and longitude (GPS coordinates).'; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_update_address_coordinates(UUID, DOUBLE PRECISION, DOUBLE PRECISION) TO vibetype_account; diff --git a/test/logic/utility/model/account_block.sql b/test/logic/utility/model/account_block.sql new file mode 100644 index 00000000..eba38c18 --- /dev/null +++ b/test/logic/utility/model/account_block.sql @@ -0,0 +1,34 @@ +CREATE OR REPLACE FUNCTION vibetype_test.account_block_create ( + _created_by UUID, + _blocked_account_id UUID +) RETURNS UUID AS $$ +DECLARE + _id UUID; +BEGIN + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; + + INSERT INTO vibetype.account_block(created_by, blocked_account_id) + VALUES (_created_by, _blocked_Account_id) + RETURNING id INTO _id; + + SET LOCAL ROLE NONE; + + RETURN _id; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_block_create(UUID, UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.account_block_delete ( + _created_by UUID, + _blocked_account_id UUID +) RETURNS VOID AS $$ +DECLARE + _id UUID; +BEGIN + DELETE FROM vibetype.account_block + WHERE created_by = _created_by and blocked_account_id = _blocked_account_id; +END $$ LANGUAGE plpgsql STRICT SECURITY DEFINER; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_block_delete(UUID, UUID) TO vibetype_account; diff --git a/test/logic/utility/model/account_registration.sql b/test/logic/utility/model/account_registration.sql new file mode 100644 index 00000000..f14436b2 --- /dev/null +++ b/test/logic/utility/model/account_registration.sql @@ -0,0 +1,26 @@ +CREATE FUNCTION vibetype_test.account_registration_verified ( + _username TEXT, + _email_address TEXT +) RETURNS UUID AS $$ +DECLARE + _account_id UUID; + _legal_term_id UUID; + _verification UUID; +BEGIN + _legal_term_id := vibetype_test.legal_term_select_by_singleton(); + PERFORM vibetype.account_registration(_email_address, 'en', _legal_term_id, 'password', _username); + + SELECT id INTO _account_id + FROM vibetype.account + WHERE username = _username; + + SELECT email_address_verification INTO _verification + FROM vibetype_private.account + WHERE id = _account_id; + + PERFORM vibetype.account_email_address_verification(_verification); + + RETURN _account_id; +END $$ LANGUAGE plpgsql STRICT SECURITY DEFINER; + +GRANT EXECUTE ON FUNCTION vibetype_test.account_registration_verified(TEXT, TEXT) TO vibetype_account; diff --git a/test/logic/utility/model/contact.sql b/test/logic/utility/model/contact.sql new file mode 100644 index 00000000..588b7821 --- /dev/null +++ b/test/logic/utility/model/contact.sql @@ -0,0 +1,81 @@ +CREATE OR REPLACE FUNCTION vibetype_test.contact_select_by_account_id ( + _account_id UUID +) RETURNS UUID AS $$ +DECLARE + _id UUID; +BEGIN + + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; + + SELECT id INTO _id + FROM vibetype.contact + WHERE created_by = _account_id AND account_id = _account_id; + + SET LOCAL ROLE NONE; + + RETURN _id; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.contact_select_by_account_id(UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.contact_create ( + _created_by UUID, + _email_address TEXT +) RETURNS UUID AS $$ +DECLARE + _id UUID; + _account_id UUID; +BEGIN + + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; + + _account_id := vibetype_test.account_select_by_email_address(_email_address); + + INSERT INTO vibetype.contact(created_by, email_address) + VALUES (_created_by, _email_address) + RETURNING id INTO _id; + + IF (_account_id IS NOT NULL) THEN + UPDATE vibetype.contact SET account_id = _account_id WHERE id = _id; + END IF; + + SET LOCAL ROLE NONE; + + RETURN _id; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.contact_create(UUID, TEXT) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.contact_test ( + _test_case TEXT, + _account_id UUID, + _expected_result UUID[] +) RETURNS VOID AS $$ +DECLARE + rec RECORD; +BEGIN + IF _account_id IS NULL THEN + SET LOCAL ROLE = 'vibetype_anonymous'; + SET LOCAL jwt.claims.account_id = ''; + ELSE + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; + END IF; + + IF EXISTS (SELECT id FROM vibetype.contact EXCEPT SELECT * FROM unnest(_expected_result)) THEN + RAISE EXCEPTION '%: some contact should not appear in the query result', _test_case; + END IF; + + IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.contact) THEN + RAISE EXCEPTION '%: some contact is missing in the query result', _test_case; + END IF; + + SET LOCAL ROLE NONE; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.contact_test(TEXT, UUID, UUID[]) TO vibetype_account; + diff --git a/test/logic/utility/model/event.sql b/test/logic/utility/model/event.sql new file mode 100644 index 00000000..f9200501 --- /dev/null +++ b/test/logic/utility/model/event.sql @@ -0,0 +1,139 @@ +CREATE OR REPLACE FUNCTION vibetype_test.event_create ( + _created_by UUID, + _name TEXT, + _slug TEXT, + _start TEXT, + _visibility TEXT +) RETURNS UUID AS $$ +DECLARE + _id UUID; +BEGIN + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; + + INSERT INTO vibetype.event(created_by, name, slug, start, visibility) + VALUES (_created_by, _name, _slug, _start::TIMESTAMP WITH TIME ZONE, _visibility::vibetype.event_visibility) + RETURNING id INTO _id; + + SET LOCAL ROLE NONE; + + RETURN _id; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_create(UUID, TEXT, TEXT, TEXT, TEXT) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.event_select_address_coordinates( + _event_id UUID +) +RETURNS DOUBLE PRECISION[] AS $$ +DECLARE + _latitude DOUBLE PRECISION; + _longitude DOUBLE PRECISION; +BEGIN + SELECT + ST_Y(a.location::geometry), + ST_X(a.location::geometry) + INTO + _latitude, + _longitude + FROM + vibetype.event e + JOIN + vibetype.address a ON e.address_id = a.id + WHERE + e.id = _event_id; + + RETURN ARRAY[_latitude, _longitude]; +END; +$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; + +COMMENT ON FUNCTION vibetype_test.event_select_address_coordinates(UUID) IS 'Returns an array with latitude and longitude of the event''s current location data.'; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_select_address_coordinates(UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.event_select_by_account_distance( + _account_id UUID, + _distance_max DOUBLE PRECISION +) +RETURNS TABLE ( + event_id UUID, + distance DOUBLE PRECISION +) AS $$ +BEGIN + RETURN QUERY + WITH account AS ( + SELECT location + FROM vibetype_private.account + WHERE id = _account_id + ) + SELECT + e.id AS event_id, + ST_Distance(a.location, addr.location) AS distance + FROM + account a, + vibetype.event e + JOIN + vibetype.address addr ON e.address_id = addr.id + WHERE + ST_DWithin(a.location, addr.location, _distance_max * 1000); +END; +$$ LANGUAGE PLPGSQL STRICT STABLE SECURITY DEFINER; + +COMMENT ON FUNCTION vibetype_test.event_select_by_account_distance(UUID, DOUBLE PRECISION) IS 'Returns event locations within a given radius around the location of an account.'; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_select_by_account_distance(UUID, DOUBLE PRECISION) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.event_test ( + _test_case TEXT, + _account_id UUID, + _expected_result UUID[] +) RETURNS VOID AS $$ +BEGIN + IF _account_id IS NULL THEN + SET LOCAL ROLE = 'vibetype_anonymous'; + SET LOCAL jwt.claims.account_id = ''; + ELSE + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; + END IF; + + IF EXISTS (SELECT id FROM vibetype.event EXCEPT SELECT * FROM unnest(_expected_result)) THEN + RAISE EXCEPTION '%: some event should not appear in the query result', _test_case; + END IF; + + IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.event) THEN + RAISE EXCEPTION '%: some event is missing in the query result', _test_case; + END IF; + + SET LOCAL ROLE NONE; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_test(TEXT, UUID, UUID[]) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.event_update_address_coordinates( + _event_id UUID, + _latitude DOUBLE PRECISION, + _longitude DOUBLE PRECISION +) +RETURNS VOID AS $$ +BEGIN + WITH event AS ( + SELECT address_id + FROM vibetype.event + WHERE id = _event_id + ) + UPDATE vibetype.address + SET + location = ST_Point(_longitude, _latitude, 4326) + WHERE + id = (SELECT address_id FROM event); +END; +$$ LANGUAGE PLPGSQL STRICT SECURITY DEFINER; + +COMMENT ON FUNCTION vibetype_test.event_update_address_coordinates(UUID, DOUBLE PRECISION, DOUBLE PRECISION) IS 'Updates an event''s location based on latitude and longitude (GPS coordinates).'; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_update_address_coordinates(UUID, DOUBLE PRECISION, DOUBLE PRECISION) TO vibetype_account; diff --git a/test/logic/utility/model/event_category.sql b/test/logic/utility/model/event_category.sql new file mode 100644 index 00000000..ccc26d37 --- /dev/null +++ b/test/logic/utility/model/event_category.sql @@ -0,0 +1,8 @@ +CREATE OR REPLACE FUNCTION vibetype_test.event_category_create ( + _category TEXT +) RETURNS VOID AS $$ +BEGIN + INSERT INTO vibetype.event_category(name) VALUES (_category); +END $$ LANGUAGE plpgsql STRICT sECURITY DEFINER; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_category_create(TEXT) TO vibetype_account; diff --git a/test/logic/utility/model/event_category_mapping.sql b/test/logic/utility/model/event_category_mapping.sql new file mode 100644 index 00000000..3df67a6f --- /dev/null +++ b/test/logic/utility/model/event_category_mapping.sql @@ -0,0 +1,44 @@ +CREATE OR REPLACE FUNCTION vibetype_test.event_category_mapping_create ( + _created_by UUID, + _event_id UUID, + _category TEXT +) RETURNS VOID AS $$ +BEGIN + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; + + INSERT INTO vibetype.event_category_mapping(event_id, category_id) + VALUES (_event_id, (SELECT id FROM vibetype.event_category WHERE name = _category)); + + SET LOCAL ROLE NONE; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_category_mapping_create(UUID, UUID, TEXT) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.event_category_mapping_test ( + _test_case TEXT, + _account_id UUID, + _expected_result UUID[] +) RETURNS VOID AS $$ +BEGIN + IF _account_id IS NULL THEN + SET LOCAL ROLE = 'vibetype_anonymous'; + SET LOCAL jwt.claims.account_id = ''; + ELSE + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; + END IF; + + IF EXISTS (SELECT event_id FROM vibetype.event_category_mapping EXCEPT SELECT * FROM unnest(_expected_result)) THEN + RAISE EXCEPTION '%: some event_category_mappings should not appear in the query result', _test_case; + END IF; + + IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT event_id FROM vibetype.event_category_mapping) THEN + RAISE EXCEPTION '%: some event_category_mappings is missing in the query result', _test_case; + END IF; + + SET LOCAL ROLE NONE; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.event_category_mapping_test(TEXT, UUID, UUID[]) TO vibetype_account; diff --git a/src/deploy/test_friendship.sql b/test/logic/utility/model/friendship.sql similarity index 82% rename from src/deploy/test_friendship.sql rename to test/logic/utility/model/friendship.sql index d835b4ec..78337634 100644 --- a/src/deploy/test_friendship.sql +++ b/test/logic/utility/model/friendship.sql @@ -1,6 +1,4 @@ -BEGIN; - -CREATE FUNCTION vibetype_test.friendship_accept ( +CREATE OR REPLACE FUNCTION vibetype_test.friendship_accept ( _invoker_account_id UUID, _id UUID ) RETURNS VOID AS $$ @@ -15,10 +13,13 @@ BEGIN SET "status" = 'accepted'::vibetype.friendship_status WHERE id = _id; - CALL vibetype_test.set_local_superuser(); + SET LOCAL ROLE NONE; END $$ LANGUAGE plpgsql; -CREATE FUNCTION vibetype_test.friendship_reject ( +GRANT EXECUTE ON FUNCTION vibetype_test.friendship_accept(UUID, UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.friendship_reject ( _invoker_account_id UUID, _id UUID ) RETURNS VOID AS $$ @@ -29,10 +30,13 @@ BEGIN DELETE FROM vibetype.friendship WHERE id = _id; - CALL vibetype_test.set_local_superuser(); + SET LOCAL ROLE NONE; END $$ LANGUAGE plpgsql; -CREATE FUNCTION vibetype_test.friendship_request ( +GRANT EXECUTE ON FUNCTION vibetype_test.friendship_reject(UUID, UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.friendship_request ( _invoker_account_id UUID, _friend_account_id UUID ) RETURNS UUID AS $$ @@ -56,12 +60,15 @@ BEGIN VALUES (_a_account_id, _b_account_id, _invoker_account_id) RETURNING id INTO _id; - CALL vibetype_test.set_local_superuser(); + SET LOCAL ROLE NONE; RETURN _id; END $$ LANGUAGE plpgsql; -CREATE FUNCTION vibetype_test.friendship_test ( +GRANT EXECUTE ON FUNCTION vibetype_test.friendship_request(UUID, UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.friendship_test ( _test_case TEXT, _invoker_account_id UUID, _status TEXT, -- status IS NULL means "any status" @@ -94,10 +101,13 @@ BEGIN RAISE EXCEPTION 'some account is missing in the query result'; END IF; - CALL vibetype_test.set_local_superuser(); + SET LOCAL ROLE NONE; END $$ LANGUAGE plpgsql; -CREATE FUNCTION vibetype_test.friendship_account_ids_test ( +GRANT EXECUTE ON FUNCTION vibetype_test.friendship_test(TEXT, UUID, TEXT, UUID[]) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.friendship_account_ids_test ( _test_case TEXT, _invoker_account_id UUID, _expected_result UUID[] @@ -154,4 +164,4 @@ BEGIN END IF; END $$ LANGUAGE plpgsql SECURITY DEFINER; -END; +GRANT EXECUTE ON FUNCTION vibetype_test.friendship_account_ids_test(TEXT, UUID, UUID[]) TO vibetype_account; diff --git a/test/logic/utility/model/guest.sql b/test/logic/utility/model/guest.sql new file mode 100644 index 00000000..65ed47f0 --- /dev/null +++ b/test/logic/utility/model/guest.sql @@ -0,0 +1,128 @@ +CREATE OR REPLACE FUNCTION vibetype_test.guest_create ( + _created_by UUID, + _event_id UUID, + _contact_id UUID +) RETURNS UUID AS $$ +DECLARE + _id UUID; +BEGIN + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _created_by || ''''; + + INSERT INTO vibetype.guest(contact_id, event_id) + VALUES (_contact_id, _event_id) + RETURNING id INTO _id; + + SET LOCAL ROLE NONE; + + RETURN _id; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.guest_create(UUID, UUID, UUID) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.guest_create_multiple_test ( + _test_case TEXT, + _account_id UUID, + _event_id UUID, + _contact_ids UUID[], + _guest_ids UUID[] +) RETURNS VOID AS $$ +BEGIN + IF _account_id IS NULL THEN + SET LOCAL ROLE = 'vibetype_anonymous'; + SET LOCAL jwt.claims.account_id = ''; + ELSE + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; + END IF; + + IF EXISTS ( + SELECT id FROM vibetype.guest WHERE event_id = _event_id AND contact_id = ANY(_contact_ids) + EXCEPT + SELECT * FROM unnest(_guest_ids) + ) THEN + RAISE EXCEPTION '%: some guest should not appear in table guest', _test_case; + END IF; + + IF EXISTS ( + SELECT * FROM unnest(_guest_ids) + EXCEPT + SELECT id FROM vibetype.guest WHERE event_id = _event_id AND contact_id = ANY(_contact_ids) + ) THEN + RAISE EXCEPTION '%: some guest is missing in table guest', _test_case; + END IF; + + SET LOCAL ROLE NONE; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.guest_create_multiple_test(TEXT, UUID, UUID, UUID[], UUID[]) TO vibetype_account; + + +CREATE OR REPLACE FUNCTION vibetype_test.guest_test ( + _test_case TEXT, + _account_id UUID, + _expected_result UUID[] +) RETURNS VOID AS $$ +BEGIN + IF _account_id IS NULL THEN + SET LOCAL ROLE = 'vibetype_anonymous'; + SET LOCAL jwt.claims.account_id = ''; + ELSE + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; + END IF; + + IF EXISTS (SELECT id FROM vibetype.guest EXCEPT SELECT * FROM unnest(_expected_result)) THEN + RAISE EXCEPTION '%: some guest should not appear in the query result', _test_case; + END IF; + + IF EXISTS (SELECT * FROM unnest(_expected_result) EXCEPT SELECT id FROM vibetype.guest) THEN + RAISE EXCEPTION '%: some guest is missing in the query result', _test_case; + END IF; + + SET LOCAL ROLE NONE; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.guest_test(TEXT, UUID, UUID[]) TO vibetype_account; + + +-- returns all guest ids that represent invitations received by the given account +CREATE OR REPLACE FUNCTION vibetype_test.guest_claim_from_account_guest ( + _account_id UUID +) +RETURNS UUID[] AS $$ +DECLARE + _guest vibetype.guest; + _result UUID[] := ARRAY[]::UUID[]; + _text TEXT := ''; +BEGIN + SET LOCAL ROLE = 'vibetype_account'; + EXECUTE 'SET LOCAL jwt.claims.account_id = ''' || _account_id || ''''; + + -- -- reads all guest ids that represent invitations received by the given account, + -- -- sets jwt.claims.guests to a string representation of these guests + -- -- and returns an array of these guests. + + FOR _guest IN + SELECT g.id + FROM vibetype.guest g JOIN vibetype.contact c + ON g.contact_id = c.id + WHERE c.account_id = _account_id + LOOP + _text := _text || ',"' || _guest.id || '"'; + _result := array_append(_result, _guest.id); + END LOOP; + + IF LENGTH(_text) > 0 THEN + _text := SUBSTR(_text, 2); + END IF; + + EXECUTE 'SET LOCAL jwt.claims.guests = ''[' || _text || ']'''; + + SET LOCAL ROLE NONE; + + RETURN _result; +END $$ LANGUAGE plpgsql; + +GRANT EXECUTE ON FUNCTION vibetype_test.guest_claim_from_account_guest(UUID) TO vibetype_account; diff --git a/test/logic/utility/model/legal_term.sql b/test/logic/utility/model/legal_term.sql new file mode 100644 index 00000000..249e2720 --- /dev/null +++ b/test/logic/utility/model/legal_term.sql @@ -0,0 +1,17 @@ +CREATE FUNCTION vibetype_test.legal_term_select_by_singleton () +RETURNS UUID AS $$ +DECLARE + _id UUID; + _verification UUID; +BEGIN + SELECT id INTO _id FROM vibetype.legal_term LIMIT 1; + + IF (_id IS NULL) THEN + INSERT INTO vibetype.legal_term (term, version) VALUES ('Be excellent to each other', '0.0.0') + RETURNING id INTO _id; + END IF; + + RETURN _id; +END $$ LANGUAGE plpgsql STRICT SECURITY DEFINER; + +GRANT EXECUTE ON FUNCTION vibetype_test.legal_term_select_by_singleton() TO vibetype_account, vibetype_anonymous; diff --git a/test/logic/utility/test/cleanup.sql b/test/logic/utility/test/cleanup.sql new file mode 100644 index 00000000..37e656e0 --- /dev/null +++ b/test/logic/utility/test/cleanup.sql @@ -0,0 +1,25 @@ +\echo drop all test functions... + +DO $$ +DECLARE + rec RECORD; +BEGIN + /* + * Array types are indicated by preceding underscore in the type name + * WITH ORDINALITY/ORDER BY ordinality is needed to preserve the order of type in p.proargtypes + */ + FOR rec IN + SELECT n.nspname, p.proname, + CASE p.prokind WHEN 'f' THEN 'FUNCTION' ELSE 'PROCEDURE' END prokind, + array_to_string(ARRAY( + SELECT CASE WHEN substring(t.typname for 1) = '_' THEN substring(t.typname FROM 2) || '[]' ELSE t.typname END + FROM UNNEST(p.proargtypes) WITH ORDINALITY JOIN pg_type t ON UNNEST = t.oid + ORDER BY ordinality + ), ',') args + FROM pg_proc p + JOIN pg_namespace n ON p.pronamespace = n.oid + WHERE n.nspname = 'vibetype_test' AND p.prokind IN ('f', 'p') + LOOP + EXECUTE format('DROP %s %s.%s(%s)', rec.prokind, rec.nspname, rec.proname, rec.args); + END LOOP; +END $$; diff --git a/test/schema/schema-update.sh b/test/schema/schema-update.sh deleted file mode 100755 index 19c94248..00000000 --- a/test/schema/schema-update.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -THIS=$(dirname "$(readlink -f "$0")") -image=maevsi/sqitch - -sudo docker build -t "$image:build" --target test-build "$THIS/../.." # --no-cache --progress plain - -container_id="$(sudo docker create $image:build)" -sudo docker cp "$container_id:/srv/app/schema.sql" "$THIS/schema.definition.sql" -sudo docker rm -v "$container_id" diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 00000000..dfd0b1c2 --- /dev/null +++ b/test/test.sh @@ -0,0 +1,15 @@ +#!/bin/sh +set -e + +THIS=$(dirname "$(readlink -f "$0")") +image=maevsi/sqitch + +if [ "$1" = "--update" ]; then + sudo docker build -t "$image:build" --target test-build "$THIS/.." # --no-cache --progress plain + + container_id="$(sudo docker create $image:build)" + sudo docker cp "$container_id:/srv/app/schema.sql" "$THIS/fixture/schema.definition.sql" + sudo docker rm -v "$container_id" +else + sudo docker build -t "$image:test" --target test "$THIS/.." # --no-cache --progress plain +fi From 1342047273966fbfda4353aca83fec97ad8b8cfe Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 2 May 2025 08:53:34 +0000 Subject: [PATCH 06/23] chore(release): 8.0.0-beta.3 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [8.0.0-beta.3](https://github.com/maevsi/sqitch/compare/8.0.0-beta.2...8.0.0-beta.3) (2025-05-02) ### ⚠ BREAKING CHANGES * run separately from `sqitch` (#187) ### Tests * run separately from `sqitch` ([#187](https://github.com/maevsi/sqitch/issues/187)) ([ef987b2](https://github.com/maevsi/sqitch/commit/ef987b26c615cd64c3f66d7f2947ca0347a430a4)) --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e8b44f3..e669ea4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [8.0.0-beta.3](https://github.com/maevsi/sqitch/compare/8.0.0-beta.2...8.0.0-beta.3) (2025-05-02) + +### ⚠ BREAKING CHANGES + +* run separately from `sqitch` (#187) + +### Tests + +* run separately from `sqitch` ([#187](https://github.com/maevsi/sqitch/issues/187)) ([ef987b2](https://github.com/maevsi/sqitch/commit/ef987b26c615cd64c3f66d7f2947ca0347a430a4)) + ## [8.0.0-beta.2](https://github.com/maevsi/sqitch/compare/8.0.0-beta.1...8.0.0-beta.2) (2025-04-17) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index 894281f9..6b5f3807 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@maevsi/sqitch", - "version": "8.0.0-beta.2", + "version": "8.0.0-beta.3", "private": true, "engines": { "node": "22" From 7e525e1e82cdeda035064bc8367030d0a57027e4 Mon Sep 17 00:00:00 2001 From: sthelemann Date: Fri, 2 May 2025 11:17:40 +0200 Subject: [PATCH 07/23] chore(policy)!: simplify policies (#190) The Row Level Security policies have been updated, using `FOR ALL` as often as possible. Also, many `table__policy.sql` were removed after moving content to `table_.sql`. --------- Co-authored-by: Jonas Thelemann --- src/deploy/table_account_block.sql | 10 + src/deploy/table_account_block_policy.sql | 23 -- ...able_account_preference_event_category.sql | 9 + ...count_preference_event_category_policy.sql | 22 -- .../table_account_preference_event_format.sql | 9 + ...account_preference_event_format_policy.sql | 22 -- .../table_account_preference_event_size.sql | 9 + ...e_account_preference_event_size_policy.sql | 22 -- src/deploy/table_account_social_network.sql | 15 ++ .../table_account_social_network_policy.sql | 23 -- src/deploy/table_achievement.sql | 3 +- src/deploy/table_achievement_code.sql | 3 +- src/deploy/table_address.sql | 17 ++ src/deploy/table_address_policy.sql | 18 -- src/deploy/table_contact_policy.sql | 16 +- src/deploy/table_device.sql | 9 + src/deploy/table_device_policy.sql | 12 - src/deploy/table_event_category.sql | 4 + src/deploy/table_event_category_mapping.sql | 21 ++ .../table_event_category_mapping_policy.sql | 27 --- src/deploy/table_event_category_policy.sql | 7 - src/deploy/table_event_favorite.sql | 9 +- src/deploy/table_event_favorite_policy.sql | 22 -- src/deploy/table_event_group.sql | 11 +- src/deploy/table_event_grouping.sql | 8 +- src/deploy/table_event_policy.sql | 36 +-- src/deploy/table_event_recommendation.sql | 8 + .../table_event_recommendation_policy.sql | 14 -- src/deploy/table_event_upload.sql | 34 +++ src/deploy/table_event_upload_policy.sql | 37 --- src/deploy/table_friendship.sql | 35 +++ src/deploy/table_friendship_policy.sql | 35 --- src/deploy/table_guest_policy.sql | 12 +- src/deploy/table_legal_term_acceptance.sql | 11 +- src/deploy/table_profile_picture.sql | 39 ++-- src/deploy/table_report.sql | 9 + src/deploy/table_report_policy.sql | 21 -- src/deploy/table_upload_policy.sql | 32 +-- src/revert/table_account_block.sql | 2 + src/revert/table_account_block_policy.sql | 7 - ...able_account_preference_event_category.sql | 2 + ...count_preference_event_category_policy.sql | 7 - .../table_account_preference_event_format.sql | 2 + ...account_preference_event_format_policy.sql | 7 - .../table_account_preference_event_size.sql | 2 + ...e_account_preference_event_size_policy.sql | 7 - src/revert/table_account_public.sql | 2 + src/revert/table_account_social_network.sql | 5 +- .../table_account_social_network_policy.sql | 7 - src/revert/table_achievement.sql | 1 + src/revert/table_achievement_code.sql | 2 + src/revert/table_address.sql | 3 + src/revert/table_address_policy.sql | 5 - src/revert/table_device.sql | 3 + src/revert/table_device_policy.sql | 5 - src/revert/table_event_category_mapping.sql | 4 + .../table_event_category_mapping_policy.sql | 7 - src/revert/table_event_category_policy.sql | 3 - src/revert/table_event_favorite.sql | 2 + src/revert/table_event_favorite_policy.sql | 7 - src/revert/table_event_policy.sql | 3 +- src/revert/table_event_recommendation.sql | 2 + .../table_event_recommendation_policy.sql | 5 - src/revert/table_event_upload.sql | 4 + src/revert/table_event_upload_policy.sql | 7 - src/revert/table_friendship.sql | 6 + src/revert/table_friendship_policy.sql | 7 - src/revert/table_legal_term.sql | 2 + src/revert/table_legal_term_acceptance.sql | 3 +- src/revert/table_profile_picture.sql | 4 + src/revert/table_report.sql | 2 + src/revert/table_report_policy.sql | 6 - src/revert/table_upload_policy.sql | 5 +- src/sqitch.plan | 14 -- src/verify/table_account_block.sql | 23 ++ src/verify/table_account_block_policy.sql | 22 -- ...able_account_preference_event_category.sql | 23 ++ ...count_preference_event_category_policy.sql | 22 -- .../table_account_preference_event_format.sql | 23 ++ ...account_preference_event_format_policy.sql | 22 -- .../table_account_preference_event_size.sql | 23 ++ ...e_account_preference_event_size_policy.sql | 22 -- src/verify/table_account_social_network.sql | 98 ++++++++ .../table_account_social_network_policy.sql | 5 - src/verify/table_address.sql | 23 ++ src/verify/table_address_policy.sql | 22 -- src/verify/table_device.sql | 23 ++ src/verify/table_device_policy.sql | 22 -- src/verify/table_event_category.sql | 24 ++ src/verify/table_event_category_mapping.sql | 23 ++ .../table_event_category_mapping_policy.sql | 22 -- src/verify/table_event_category_policy.sql | 22 -- src/verify/table_event_favorite.sql | 23 ++ src/verify/table_event_favorite_policy.sql | 22 -- src/verify/table_event_recommendation.sql | 23 ++ .../table_event_recommendation_policy.sql | 22 -- src/verify/table_event_upload.sql | 23 ++ src/verify/table_event_upload_policy.sql | 22 -- src/verify/table_friendship.sql | 23 ++ src/verify/table_friendship_policy.sql | 22 -- src/verify/table_report.sql | 23 ++ src/verify/table_report_policy.sql | 22 -- test/fixture/schema.definition.sql | 219 ++++-------------- 103 files changed, 764 insertions(+), 980 deletions(-) delete mode 100644 src/deploy/table_account_block_policy.sql delete mode 100644 src/deploy/table_account_preference_event_category_policy.sql delete mode 100644 src/deploy/table_account_preference_event_format_policy.sql delete mode 100644 src/deploy/table_account_preference_event_size_policy.sql delete mode 100644 src/deploy/table_account_social_network_policy.sql delete mode 100644 src/deploy/table_address_policy.sql delete mode 100644 src/deploy/table_device_policy.sql delete mode 100644 src/deploy/table_event_category_mapping_policy.sql delete mode 100644 src/deploy/table_event_category_policy.sql delete mode 100644 src/deploy/table_event_favorite_policy.sql delete mode 100644 src/deploy/table_event_recommendation_policy.sql delete mode 100644 src/deploy/table_event_upload_policy.sql delete mode 100644 src/deploy/table_friendship_policy.sql delete mode 100644 src/deploy/table_report_policy.sql delete mode 100644 src/revert/table_account_block_policy.sql delete mode 100644 src/revert/table_account_preference_event_category_policy.sql delete mode 100644 src/revert/table_account_preference_event_format_policy.sql delete mode 100644 src/revert/table_account_preference_event_size_policy.sql delete mode 100644 src/revert/table_account_social_network_policy.sql delete mode 100644 src/revert/table_address_policy.sql delete mode 100644 src/revert/table_device_policy.sql delete mode 100644 src/revert/table_event_category_mapping_policy.sql delete mode 100644 src/revert/table_event_category_policy.sql delete mode 100644 src/revert/table_event_favorite_policy.sql delete mode 100644 src/revert/table_event_recommendation_policy.sql delete mode 100644 src/revert/table_event_upload_policy.sql delete mode 100644 src/revert/table_friendship_policy.sql delete mode 100644 src/revert/table_report_policy.sql delete mode 100644 src/verify/table_account_block_policy.sql delete mode 100644 src/verify/table_account_preference_event_category_policy.sql delete mode 100644 src/verify/table_account_preference_event_format_policy.sql delete mode 100644 src/verify/table_account_preference_event_size_policy.sql delete mode 100644 src/verify/table_account_social_network_policy.sql delete mode 100644 src/verify/table_address_policy.sql delete mode 100644 src/verify/table_device_policy.sql delete mode 100644 src/verify/table_event_category_mapping_policy.sql delete mode 100644 src/verify/table_event_category_policy.sql delete mode 100644 src/verify/table_event_favorite_policy.sql delete mode 100644 src/verify/table_event_recommendation_policy.sql delete mode 100644 src/verify/table_event_upload_policy.sql delete mode 100644 src/verify/table_friendship_policy.sql delete mode 100644 src/verify/table_report_policy.sql diff --git a/src/deploy/table_account_block.sql b/src/deploy/table_account_block.sql index 85c8300a..58a93eea 100644 --- a/src/deploy/table_account_block.sql +++ b/src/deploy/table_account_block.sql @@ -18,4 +18,14 @@ COMMENT ON COLUMN vibetype.account_block.blocked_account_id IS 'The account id o COMMENT ON COLUMN vibetype.account_block.created_at IS E'@omit create\nTimestamp of when the account block was created.'; COMMENT ON COLUMN vibetype.account_block.created_by IS 'The account id of the user who created the account block.'; +GRANT INSERT, SELECT ON TABLE vibetype.account_block TO vibetype_account; +GRANT SELECT ON TABLE vibetype.account_block TO vibetype_anonymous; + +ALTER TABLE vibetype.account_block ENABLE ROW LEVEL SECURITY; + +CREATE POLICY account_block_all ON vibetype.account_block FOR ALL +USING ( + created_by = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_account_block_policy.sql b/src/deploy/table_account_block_policy.sql deleted file mode 100644 index 1aae086a..00000000 --- a/src/deploy/table_account_block_policy.sql +++ /dev/null @@ -1,23 +0,0 @@ -BEGIN; - -GRANT INSERT, SELECT ON TABLE vibetype.account_block TO vibetype_account; -GRANT SELECT ON TABLE vibetype.account_block TO vibetype_anonymous; - -ALTER TABLE vibetype.account_block ENABLE ROW LEVEL SECURITY; - --- Only allow selects by the current account. -CREATE POLICY account_block_select ON vibetype.account_block FOR SELECT USING ( - created_by = vibetype.invoker_account_id() -); - --- Only allow inserts by the current account. -CREATE POLICY account_block_insert ON vibetype.account_block FOR INSERT WITH CHECK ( - created_by = vibetype.invoker_account_id() -); - --- Only allow deletes by the current account. -CREATE POLICY account_block_delete ON vibetype.account_block FOR DELETE USING ( - created_by = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_account_preference_event_category.sql b/src/deploy/table_account_preference_event_category.sql index f4eeeb79..9c6561c3 100644 --- a/src/deploy/table_account_preference_event_category.sql +++ b/src/deploy/table_account_preference_event_category.sql @@ -13,4 +13,13 @@ COMMENT ON TABLE vibetype.account_preference_event_category IS 'Event categories COMMENT ON COLUMN vibetype.account_preference_event_category.account_id IS 'A user account id.'; COMMENT ON COLUMN vibetype.account_preference_event_category.category_id IS 'An event category id.'; +GRANT SELECT, INSERT, DELETE ON TABLE vibetype.account_preference_event_category TO vibetype_account; + +ALTER TABLE vibetype.account_preference_event_category ENABLE ROW LEVEL SECURITY; + +CREATE POLICY account_preference_event_category_all ON vibetype.account_preference_event_category FOR ALL +USING ( + account_id = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_account_preference_event_category_policy.sql b/src/deploy/table_account_preference_event_category_policy.sql deleted file mode 100644 index 660d3acb..00000000 --- a/src/deploy/table_account_preference_event_category_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -GRANT SELECT, INSERT, DELETE ON TABLE vibetype.account_preference_event_category TO vibetype_account; - -ALTER TABLE vibetype.account_preference_event_category ENABLE ROW LEVEL SECURITY; - --- Only allow selects by the current account. -CREATE POLICY account_preference_event_category_select ON vibetype.account_preference_event_category FOR SELECT USING ( - account_id = vibetype.invoker_account_id() -); - --- Only allow inserts by the current account. -CREATE POLICY account_preference_event_category_insert ON vibetype.account_preference_event_category FOR INSERT WITH CHECK ( - account_id = vibetype.invoker_account_id() -); - --- Only allow deletes by the current account. -CREATE POLICY account_preference_event_category_delete ON vibetype.account_preference_event_category FOR DELETE USING ( - account_id = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_account_preference_event_format.sql b/src/deploy/table_account_preference_event_format.sql index 56d7dd80..483139e6 100644 --- a/src/deploy/table_account_preference_event_format.sql +++ b/src/deploy/table_account_preference_event_format.sql @@ -14,4 +14,13 @@ COMMENT ON COLUMN vibetype.account_preference_event_format.account_id IS 'A user COMMENT ON COLUMN vibetype.account_preference_event_format.format_id IS 'The id of an event format.'; COMMENT ON COLUMN vibetype.account_preference_event_format.created_at IS 'The timestammp when the record was created..'; +GRANT SELECT, INSERT, DELETE ON TABLE vibetype.account_preference_event_format TO vibetype_account; + +ALTER TABLE vibetype.account_preference_event_format ENABLE ROW LEVEL SECURITY; + +CREATE POLICY account_preference_event_format_all ON vibetype.account_preference_event_format FOR ALL +USING ( + account_id = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_account_preference_event_format_policy.sql b/src/deploy/table_account_preference_event_format_policy.sql deleted file mode 100644 index 7e8256b6..00000000 --- a/src/deploy/table_account_preference_event_format_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -GRANT SELECT, INSERT, DELETE ON TABLE vibetype.account_preference_event_format TO vibetype_account; - -ALTER TABLE vibetype.account_preference_event_format ENABLE ROW LEVEL SECURITY; - --- Only allow selects by the current account. -CREATE POLICY account_preference_event_format_select ON vibetype.account_preference_event_format FOR SELECT USING ( - account_id = vibetype.invoker_account_id() -); - --- Only allow inserts by the current account. -CREATE POLICY account_preference_event_format_insert ON vibetype.account_preference_event_format FOR INSERT WITH CHECK ( - account_id = vibetype.invoker_account_id() -); - --- Only allow deletes by the current account. -CREATE POLICY account_preference_event_format_delete ON vibetype.account_preference_event_format FOR DELETE USING ( - account_id = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_account_preference_event_size.sql b/src/deploy/table_account_preference_event_size.sql index b3ad44a0..fae6d421 100644 --- a/src/deploy/table_account_preference_event_size.sql +++ b/src/deploy/table_account_preference_event_size.sql @@ -14,4 +14,13 @@ COMMENT ON COLUMN vibetype.account_preference_event_size.account_id IS 'The acco COMMENT ON COLUMN vibetype.account_preference_event_size.event_size IS 'A preferred event sized'; COMMENT ON COLUMN vibetype.account_preference_event_size.created_at IS E'@omit create,update\nTimestamp of when the event size preference was created, defaults to the current timestamp.'; +GRANT SELECT, INSERT, DELETE ON TABLE vibetype.account_preference_event_size TO vibetype_account; + +ALTER TABLE vibetype.account_preference_event_size ENABLE ROW LEVEL SECURITY; + +CREATE POLICY account_preference_event_size_all ON vibetype.account_preference_event_size FOR ALL +USING ( + account_id = vibetype.invoker_account_id() +); + END; diff --git a/src/deploy/table_account_preference_event_size_policy.sql b/src/deploy/table_account_preference_event_size_policy.sql deleted file mode 100644 index d2462a06..00000000 --- a/src/deploy/table_account_preference_event_size_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -GRANT SELECT, INSERT, DELETE ON TABLE vibetype.account_preference_event_size TO vibetype_account; - -ALTER TABLE vibetype.account_preference_event_size ENABLE ROW LEVEL SECURITY; - --- Only allow selects by the current account. -CREATE POLICY account_preference_event_size_select ON vibetype.account_preference_event_size FOR SELECT USING ( - account_id = vibetype.invoker_account_id() -); - --- Only allow inserts by the current account. -CREATE POLICY account_preference_event_size_insert ON vibetype.account_preference_event_size FOR INSERT WITH CHECK ( - account_id = vibetype.invoker_account_id() -); - --- Only allow deletes by the current account. -CREATE POLICY account_preference_event_size_delete ON vibetype.account_preference_event_size FOR DELETE USING ( - account_id = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_account_social_network.sql b/src/deploy/table_account_social_network.sql index 8c3fc7ac..573a891e 100644 --- a/src/deploy/table_account_social_network.sql +++ b/src/deploy/table_account_social_network.sql @@ -14,4 +14,19 @@ COMMENT ON COLUMN vibetype.account_social_network.social_network IS 'The social COMMENT ON COLUMN vibetype.account_social_network.social_network_username IS 'The username of the account on the specified social network.'; COMMENT ON CONSTRAINT account_social_network_pkey ON vibetype.account_social_network IS 'Ensures uniqueness by combining the account ID and social network, allowing each account to have a single entry per social network.'; +GRANT SELECT ON TABLE vibetype.account_social_network TO vibetype_anonymous; +GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE vibetype.account_social_network TO vibetype_account; + +ALTER TABLE vibetype.account_social_network ENABLE ROW LEVEL SECURITY; + +CREATE POLICY account_social_network_all ON vibetype.account_social_network FOR ALL +USING ( + account_id = vibetype.invoker_account_id() +); + +CREATE POLICY account_social_network_select ON vibetype.account_social_network FOR SELECT +USING ( + TRUE +); + COMMIT; diff --git a/src/deploy/table_account_social_network_policy.sql b/src/deploy/table_account_social_network_policy.sql deleted file mode 100644 index f3fab044..00000000 --- a/src/deploy/table_account_social_network_policy.sql +++ /dev/null @@ -1,23 +0,0 @@ -BEGIN; - -GRANT SELECT ON TABLE vibetype.account_social_network TO vibetype_anonymous; -GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE vibetype.account_social_network TO vibetype_account; - -ALTER TABLE vibetype.account_social_network ENABLE ROW LEVEL SECURITY; - --- Only allow inserting social links of the current account. -CREATE POLICY account_social_network_insert ON vibetype.account_social_network FOR INSERT WITH CHECK ( - account_id = vibetype.invoker_account_id() -); - --- Only allow updating social links of the current account. -CREATE POLICY account_social_network_update ON vibetype.account_social_network FOR UPDATE USING ( - account_id = vibetype.invoker_account_id() -); - --- Only allow deleting social links of the current account.. -CREATE POLICY account_social_network_delete ON vibetype.account_social_network FOR DELETE USING ( - account_id = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_achievement.sql b/src/deploy/table_achievement.sql index 34574488..971cf018 100644 --- a/src/deploy/table_achievement.sql +++ b/src/deploy/table_achievement.sql @@ -21,7 +21,8 @@ GRANT SELECT ON TABLE vibetype.achievement TO vibetype_account, vibetype_anonymo ALTER TABLE vibetype.achievement ENABLE ROW LEVEL SECURITY; -- Make all achievement unlocks accessible by everyone. -CREATE POLICY achievement_select ON vibetype.achievement FOR SELECT USING ( +CREATE POLICY achievement_select ON vibetype.achievement FOR SELECT +USING ( TRUE ); diff --git a/src/deploy/table_achievement_code.sql b/src/deploy/table_achievement_code.sql index 5dd9a3ae..f9255e82 100644 --- a/src/deploy/table_achievement_code.sql +++ b/src/deploy/table_achievement_code.sql @@ -19,7 +19,8 @@ GRANT SELECT ON TABLE vibetype_private.achievement_code TO :role_service_vibetyp ALTER TABLE vibetype_private.achievement_code ENABLE ROW LEVEL SECURITY; -- Make all achievement codes accessible. -CREATE POLICY achievement_code_select ON vibetype_private.achievement_code FOR SELECT USING ( +CREATE POLICY achievement_code_select ON vibetype_private.achievement_code FOR SELECT +USING ( TRUE ); diff --git a/src/deploy/table_address.sql b/src/deploy/table_address.sql index f156852a..d565acb9 100644 --- a/src/deploy/table_address.sql +++ b/src/deploy/table_address.sql @@ -48,4 +48,21 @@ CREATE TRIGGER vibetype_trigger_address_update FOR EACH ROW EXECUTE PROCEDURE vibetype.trigger_metadata_update(); +GRANT SELECT ON TABLE vibetype.address TO vibetype_anonymous; +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.address TO vibetype_account; + +ALTER TABLE vibetype.address ENABLE ROW LEVEL SECURITY; + +CREATE POLICY address_all ON vibetype.address FOR ALL +USING ( + created_by = vibetype.invoker_account_id() + AND + created_by NOT IN ( + SELECT id FROM vibetype_private.account_block_ids() + ) +) +WITH CHECK ( + created_by = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_address_policy.sql b/src/deploy/table_address_policy.sql deleted file mode 100644 index d10c1139..00000000 --- a/src/deploy/table_address_policy.sql +++ /dev/null @@ -1,18 +0,0 @@ -BEGIN; - -GRANT SELECT ON TABLE vibetype.address TO vibetype_anonymous; -GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.address TO vibetype_account; - -ALTER TABLE vibetype.address ENABLE ROW LEVEL SECURITY; - -CREATE POLICY address ON vibetype.address FOR ALL USING ( - created_by = vibetype.invoker_account_id() - AND - created_by NOT IN ( - SELECT id FROM vibetype_private.account_block_ids() - ) -) WITH CHECK ( - created_by = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_contact_policy.sql b/src/deploy/table_contact_policy.sql index e9f3eca4..24a9bb4f 100644 --- a/src/deploy/table_contact_policy.sql +++ b/src/deploy/table_contact_policy.sql @@ -1,7 +1,7 @@ BEGIN; -GRANT SELECT ON TABLE vibetype.contact TO vibetype_account, vibetype_anonymous; -GRANT INSERT, UPDATE, DELETE ON TABLE vibetype.contact TO vibetype_account; +GRANT SELECT ON TABLE vibetype.contact TO vibetype_anonymous; +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.contact TO vibetype_account; ALTER TABLE vibetype.contact ENABLE ROW LEVEL SECURITY; @@ -10,7 +10,8 @@ ALTER TABLE vibetype.contact ENABLE ROW LEVEL SECURITY; -- 2) Display contacts created by the invoker's account, omit contacts referring to an account -- blocked by the invoker or by an account that blocked the invoker. -- 3) Display contacts for which an accessible guest exists. -CREATE POLICY contact_select ON vibetype.contact FOR SELECT USING ( +CREATE POLICY contact_select ON vibetype.contact FOR SELECT +USING ( ( account_id = vibetype.invoker_account_id() AND @@ -35,7 +36,8 @@ CREATE POLICY contact_select ON vibetype.contact FOR SELECT USING ( -- Only allow inserts for contacts created by the invoker's account. -- Disallow inserts for contacts that refer to a blocked account. -CREATE POLICY contact_insert ON vibetype.contact FOR INSERT WITH CHECK ( +CREATE POLICY contact_insert ON vibetype.contact FOR INSERT +WITH CHECK ( created_by = vibetype.invoker_account_id() AND account_id NOT IN ( SELECT blocked_account_id @@ -46,7 +48,8 @@ CREATE POLICY contact_insert ON vibetype.contact FOR INSERT WITH CHECK ( -- Only allow updates for contacts created by the invoker's account. -- No contact referring to a blocked account can be updated. -CREATE POLICY contact_update ON vibetype.contact FOR UPDATE USING ( +CREATE POLICY contact_update ON vibetype.contact FOR UPDATE +USING ( created_by = vibetype.invoker_account_id() AND account_id NOT IN ( SELECT blocked_account_id @@ -56,7 +59,8 @@ CREATE POLICY contact_update ON vibetype.contact FOR UPDATE USING ( ); -- Only allow deletes for contacts created by the invoker's account except for the own account's contact. -CREATE POLICY contact_delete ON vibetype.contact FOR DELETE USING ( +CREATE POLICY contact_delete ON vibetype.contact FOR DELETE +USING ( vibetype.invoker_account_id() IS NOT NULL AND created_by = vibetype.invoker_account_id() diff --git a/src/deploy/table_device.sql b/src/deploy/table_device.sql index 99b36e96..6ec947b1 100644 --- a/src/deploy/table_device.sql +++ b/src/deploy/table_device.sql @@ -52,4 +52,13 @@ CREATE TRIGGER vibetype_trigger_device_update_fcm FOR EACH ROW EXECUTE FUNCTION vibetype.trigger_metadata_update_fcm(); +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.device TO vibetype_account; + +ALTER TABLE vibetype.device ENABLE ROW LEVEL SECURITY; + +CREATE POLICY device_all ON vibetype.device FOR ALL +USING ( + created_by = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_device_policy.sql b/src/deploy/table_device_policy.sql deleted file mode 100644 index f84cb19b..00000000 --- a/src/deploy/table_device_policy.sql +++ /dev/null @@ -1,12 +0,0 @@ -BEGIN; - -GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.device TO vibetype_account; - -ALTER TABLE vibetype.device ENABLE ROW LEVEL SECURITY; - -CREATE POLICY device ON vibetype.device USING ( - created_by = vibetype.invoker_account_id() -) -WITH CHECK (TRUE); - -COMMIT; diff --git a/src/deploy/table_event_category.sql b/src/deploy/table_event_category.sql index 7e9cfed5..e15fe15e 100644 --- a/src/deploy/table_event_category.sql +++ b/src/deploy/table_event_category.sql @@ -11,4 +11,8 @@ COMMENT ON TABLE vibetype.event_category IS 'Event categories.'; COMMENT ON COLUMN vibetype.event_category.id IS 'The id of the event category.'; COMMENT ON COLUMN vibetype.event_category.name IS 'A category name.'; +GRANT SELECT ON TABLE vibetype.event_category TO vibetype_anonymous, vibetype_account; + +-- no row level security necessary for this table as it does not contain user data + END; diff --git a/src/deploy/table_event_category_mapping.sql b/src/deploy/table_event_category_mapping.sql index 9b515865..b5082cfe 100644 --- a/src/deploy/table_event_category_mapping.sql +++ b/src/deploy/table_event_category_mapping.sql @@ -11,4 +11,25 @@ COMMENT ON TABLE vibetype.event_category_mapping IS 'Mapping events to categorie COMMENT ON COLUMN vibetype.event_category_mapping.event_id IS 'An event id.'; COMMENT ON COLUMN vibetype.event_category_mapping.category_id IS 'A category id.'; +GRANT SELECT ON TABLE vibetype.event_category_mapping TO vibetype_anonymous; +GRANT SELECT, INSERT, DELETE ON TABLE vibetype.event_category_mapping TO vibetype_account; + +ALTER TABLE vibetype.event_category_mapping ENABLE ROW LEVEL SECURITY; + +CREATE POLICY event_category_mapping_select ON vibetype.event_category_mapping FOR SELECT +USING ( + -- same policy as for table event + event_id IN (SELECT id FROM vibetype.event) +); + +CREATE POLICY event_category_mapping_insert ON vibetype.event_category_mapping FOR INSERT +WITH CHECK ( + (SELECT created_by FROM vibetype.event WHERE id = event_id) = vibetype.invoker_account_id() +); + +CREATE POLICY event_category_mapping_delete ON vibetype.event_category_mapping FOR DELETE +USING ( + (SELECT created_by FROM vibetype.event WHERE id = event_id) = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_event_category_mapping_policy.sql b/src/deploy/table_event_category_mapping_policy.sql deleted file mode 100644 index 229ddc9c..00000000 --- a/src/deploy/table_event_category_mapping_policy.sql +++ /dev/null @@ -1,27 +0,0 @@ -BEGIN; - -GRANT SELECT ON TABLE vibetype.event_category_mapping TO vibetype_anonymous; -GRANT SELECT, INSERT, DELETE ON TABLE vibetype.event_category_mapping TO vibetype_account; - -ALTER TABLE vibetype.event_category_mapping ENABLE ROW LEVEL SECURITY; - -CREATE POLICY event_category_mapping_select ON vibetype.event_category_mapping FOR SELECT USING ( - -- same policy as for table event - event_id IN (SELECT id FROM vibetype.event) -); - --- Only allow inserts for events created by user. -CREATE POLICY event_category_mapping_insert ON vibetype.event_category_mapping FOR INSERT WITH CHECK ( - vibetype.invoker_account_id() IS NOT NULL - AND - (SELECT created_by FROM vibetype.event WHERE id = event_id) = vibetype.invoker_account_id() -); - --- Only allow deletes for events created by user. -CREATE POLICY event_category_mapping_delete ON vibetype.event_category_mapping FOR DELETE USING ( - vibetype.invoker_account_id() IS NOT NULL - AND - (SELECT created_by FROM vibetype.event WHERE id = event_id) = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_event_category_policy.sql b/src/deploy/table_event_category_policy.sql deleted file mode 100644 index 72cec890..00000000 --- a/src/deploy/table_event_category_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -GRANT SELECT ON TABLE vibetype.event_category TO vibetype_anonymous, vibetype_account; - --- no row level security necessary for this table as it does not contain user data - -COMMIT; diff --git a/src/deploy/table_event_favorite.sql b/src/deploy/table_event_favorite.sql index 2b5975d2..0f71a394 100644 --- a/src/deploy/table_event_favorite.sql +++ b/src/deploy/table_event_favorite.sql @@ -18,6 +18,13 @@ COMMENT ON COLUMN vibetype.event_favorite.created_at IS E'@omit create,update\nT COMMENT ON COLUMN vibetype.event_favorite.created_by IS E'@omit create,update\nReference to the account that created the event favorite.'; COMMENT ON CONSTRAINT event_favorite_created_by_event_id_key ON vibetype.event_favorite IS 'Ensures that each user can mark an event as a favorite only once.'; --- GRANTs, RLS and POLICYs are specified in `table_event_favorite_policy`. +GRANT SELECT, INSERT, DELETE ON TABLE vibetype.event_favorite TO vibetype_account; + +ALTER TABLE vibetype.event_favorite ENABLE ROW LEVEL SECURITY; + +CREATE POLICY event_favorite_all ON vibetype.event_favorite FOR ALL +USING ( + created_by = vibetype.invoker_account_id() +); COMMIT; diff --git a/src/deploy/table_event_favorite_policy.sql b/src/deploy/table_event_favorite_policy.sql deleted file mode 100644 index 5f0a550c..00000000 --- a/src/deploy/table_event_favorite_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -GRANT SELECT, INSERT, DELETE ON TABLE vibetype.event_favorite TO vibetype_account; - -ALTER TABLE vibetype.event_favorite ENABLE ROW LEVEL SECURITY; - --- Only display event favorites that were created by the invoker. -CREATE POLICY event_favorite_select ON vibetype.event_favorite FOR SELECT USING ( - created_by = vibetype.invoker_account_id() -); - --- Only allow inserts for event favorites created by the invoker. -CREATE POLICY event_favorite_insert ON vibetype.event_favorite FOR INSERT WITH CHECK ( - created_by = vibetype.invoker_account_id() -); - --- Only allow deletes for event favorites created by the invoker. -CREATE POLICY event_favorite_delete ON vibetype.event_favorite FOR DELETE USING ( - created_by = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_event_group.sql b/src/deploy/table_event_group.sql index 1e6a0c16..9dfb52d1 100644 --- a/src/deploy/table_event_group.sql +++ b/src/deploy/table_event_group.sql @@ -23,16 +23,15 @@ COMMENT ON COLUMN vibetype.event_group.slug IS E'@omit create,update\nThe event COMMENT ON COLUMN vibetype.event_group.created_at IS E'@omit create,update\nTimestamp of when the event group was created, defaults to the current timestamp.'; COMMENT ON COLUMN vibetype.event_group.created_by IS 'The event group creator''s id.'; -GRANT SELECT ON TABLE vibetype.event_group TO vibetype_account, vibetype_anonymous; -GRANT INSERT, UPDATE, DELETE ON TABLE vibetype.event_group TO vibetype_account; +GRANT SELECT ON TABLE vibetype.event_group TO vibetype_anonymous; +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.event_group TO vibetype_account; ALTER TABLE vibetype.event_group ENABLE ROW LEVEL SECURITY; -- TODO: --- CREATE POLICY event_group_select ON vibetype.event_group FOR SELECT USING ( --- id IN ( --- SELECT event_group_id FROM vibetype.event_grouping --- ) +-- CREATE POLICY event_group_select ON vibetype.event_group FOR SELECT +-- USING ( +-- id IN (SELECT event_group_id FROM vibetype.event_grouping) -- ); COMMIT; diff --git a/src/deploy/table_event_grouping.sql b/src/deploy/table_event_grouping.sql index 614bc8aa..585284d0 100644 --- a/src/deploy/table_event_grouping.sql +++ b/src/deploy/table_event_grouping.sql @@ -14,16 +14,14 @@ COMMENT ON COLUMN vibetype.event_grouping.id IS E'@omit create,update\nThe event COMMENT ON COLUMN vibetype.event_grouping.event_group_id IS 'The event grouping''s internal event group id.'; COMMENT ON COLUMN vibetype.event_grouping.event_id IS 'The event grouping''s internal event id.'; -GRANT SELECT ON TABLE vibetype.event_grouping TO vibetype_account, vibetype_anonymous; -GRANT INSERT, UPDATE, DELETE ON TABLE vibetype.event_grouping TO vibetype_account; +GRANT SELECT ON TABLE vibetype.event_grouping TO vibetype_anonymous; +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.event_grouping TO vibetype_account; ALTER TABLE vibetype.event_grouping ENABLE ROW LEVEL SECURITY; -- TODO: -- CREATE POLICY event_grouping_select ON vibetype.event_grouping FOR SELECT USING ( --- event_id IN ( --- SELECT id FROM vibetype.event --- ) +-- event_id IN (SELECT id FROM vibetype.event) -- ); COMMIT; diff --git a/src/deploy/table_event_policy.sql b/src/deploy/table_event_policy.sql index b04e4aa8..22781741 100644 --- a/src/deploy/table_event_policy.sql +++ b/src/deploy/table_event_policy.sql @@ -1,14 +1,20 @@ BEGIN; -GRANT SELECT ON TABLE vibetype.event TO vibetype_account, vibetype_anonymous; -GRANT INSERT, UPDATE, DELETE ON TABLE vibetype.event TO vibetype_account; +GRANT SELECT ON TABLE vibetype.event TO vibetype_anonymous; +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.event TO vibetype_account; ALTER TABLE vibetype.event ENABLE ROW LEVEL SECURITY; +-- Only allow events that are organized by oneself. +CREATE POLICY event_all ON vibetype.event FOR ALL +USING ( + created_by = vibetype.invoker_account_id() +); + -- Only display events that are public and not full and not organized by a blocked account. --- Only display events that are organized by oneself. -- Only display events to which oneself is invited, but not by a guest created by a blocked account. -CREATE POLICY event_select ON vibetype.event FOR SELECT USING ( +CREATE POLICY event_select ON vibetype.event FOR SELECT +USING ( ( visibility = 'public' AND @@ -21,31 +27,9 @@ CREATE POLICY event_select ON vibetype.event FOR SELECT USING ( SELECT id FROM vibetype_private.account_block_ids() ) ) - OR ( - created_by = vibetype.invoker_account_id() - ) OR ( id IN (SELECT vibetype_private.events_invited()) ) ); --- Only allow inserts for events created by the current user. -CREATE POLICY event_insert ON vibetype.event FOR INSERT WITH CHECK ( - vibetype.invoker_account_id() IS NOT NULL - AND - created_by = vibetype.invoker_account_id() -); - --- Only allow updates for events created by the current user. -CREATE POLICY event_update ON vibetype.event FOR UPDATE USING ( - vibetype.invoker_account_id() IS NOT NULL - AND - created_by = vibetype.invoker_account_id() -); - --- Only allow deletes for events created by the current user. -CREATE POLICY event_delete ON vibetype.event FOR DELETE USING ( - created_by = vibetype.invoker_account_id() -); - COMMIT; diff --git a/src/deploy/table_event_recommendation.sql b/src/deploy/table_event_recommendation.sql index 3ed62cbb..ac076a11 100644 --- a/src/deploy/table_event_recommendation.sql +++ b/src/deploy/table_event_recommendation.sql @@ -16,4 +16,12 @@ COMMENT ON COLUMN vibetype.event_recommendation.score IS 'An event id.'; COMMENT ON COLUMN vibetype.event_recommendation.predicted_score IS 'The score of the recommendation.'; COMMENT ON COLUMN vibetype.event_recommendation.event_id IS 'The predicted score of the recommendation.'; +GRANT SELECT ON TABLE vibetype.event_recommendation TO vibetype_account; + +ALTER TABLE vibetype.event_recommendation ENABLE ROW LEVEL SECURITY; + +CREATE POLICY event_recommendation_select ON vibetype.event_recommendation FOR SELECT USING ( + account_id = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_event_recommendation_policy.sql b/src/deploy/table_event_recommendation_policy.sql deleted file mode 100644 index 44bc50bb..00000000 --- a/src/deploy/table_event_recommendation_policy.sql +++ /dev/null @@ -1,14 +0,0 @@ -BEGIN; - -GRANT SELECT, INSERT, DELETE ON TABLE vibetype.event_recommendation TO vibetype_account; - -ALTER TABLE vibetype.event_recommendation ENABLE ROW LEVEL SECURITY; - --- Only allow selects by the current user. -CREATE POLICY event_recommendation_select ON vibetype.event_recommendation FOR SELECT USING ( - vibetype.invoker_account_id() IS NOT NULL - AND - account_id = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_event_upload.sql b/src/deploy/table_event_upload.sql index 1b0a37dd..569bb743 100644 --- a/src/deploy/table_event_upload.sql +++ b/src/deploy/table_event_upload.sql @@ -22,4 +22,38 @@ COMMENT ON COLUMN vibetype.event_upload.upload_id IS E'@omit update\nReference t COMMENT ON CONSTRAINT event_upload_event_id_upload_id_key ON vibetype.event_upload IS 'Ensures that each upload is associated with a unique event, preventing duplicate uploads for the same event.'; COMMENT ON INDEX vibetype.idx_event_upload_is_header_image_unique IS 'Ensures that at most one header image exists per event.'; +GRANT SELECT ON TABLE vibetype.event_upload TO vibetype_anonymous; +GRANT INSERT, SELECT, DELETE ON TABLE vibetype.event_upload TO vibetype_account; + +ALTER TABLE vibetype.event_upload ENABLE ROW LEVEL SECURITY; + +-- Only select rows for accessable events where accessability is specified +-- by the event_select policy for table event. +CREATE POLICY event_upload_select ON vibetype.event_upload FOR SELECT USING ( + event_id IN ( + SELECT id FROM vibetype.event + ) +); + +-- Only allow inserts for events created by the current user and for uploads of the current_user. +CREATE POLICY event_upload_insert ON vibetype.event_upload FOR INSERT WITH CHECK ( + event_id IN ( + SELECT id FROM vibetype.event + WHERE created_by = vibetype.invoker_account_id() + ) + AND + upload_id IN ( + SELECT id FROM vibetype.upload + WHERE account_id = vibetype.invoker_account_id() + ) +); + +-- Only allow deletes if event is created by the current user. +CREATE POLICY event_upload_delete ON vibetype.event_upload FOR DELETE USING ( + event_id IN ( + SELECT id FROM vibetype.event + WHERE created_by = vibetype.invoker_account_id() + ) +); + END; diff --git a/src/deploy/table_event_upload_policy.sql b/src/deploy/table_event_upload_policy.sql deleted file mode 100644 index bded7a03..00000000 --- a/src/deploy/table_event_upload_policy.sql +++ /dev/null @@ -1,37 +0,0 @@ -BEGIN; - -GRANT SELECT ON TABLE vibetype.event_upload TO vibetype_account, vibetype_anonymous; -GRANT INSERT, DELETE ON TABLE vibetype.event_upload TO vibetype_account; - -ALTER TABLE vibetype.event_upload ENABLE ROW LEVEL SECURITY; - --- Only select rows for accessable events where accessability is specified --- by the event_select policy for table event. -CREATE POLICY event_upload_select ON vibetype.event_upload FOR SELECT USING ( - event_id IN ( - SELECT id FROM vibetype.event - ) -); - --- Only allow inserts for events created by the current user and for uploads of the current_user. -CREATE POLICY event_upload_insert ON vibetype.event_upload FOR INSERT WITH CHECK ( - event_id IN ( - SELECT id FROM vibetype.event - WHERE created_by = vibetype.invoker_account_id() - ) - AND - upload_id IN ( - SELECT id FROM vibetype.upload - WHERE account_id = vibetype.invoker_account_id() - ) -); - --- Only allow deletes if event is created by the current user. -CREATE POLICY event_upload_delete ON vibetype.event_upload FOR DELETE USING ( - event_id IN ( - SELECT id FROM vibetype.event - WHERE created_by = vibetype.invoker_account_id() - ) -); - -COMMIT; diff --git a/src/deploy/table_friendship.sql b/src/deploy/table_friendship.sql index 34ad4400..4744ce89 100644 --- a/src/deploy/table_friendship.sql +++ b/src/deploy/table_friendship.sql @@ -41,4 +41,39 @@ CREATE TRIGGER vibetype_trigger_friendship_update FOR EACH ROW EXECUTE PROCEDURE vibetype.trigger_metadata_update(); +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.friendship TO vibetype_account; + +ALTER TABLE vibetype.friendship ENABLE ROW LEVEL SECURITY; + +-- Only allow interactions with friendships in which the current user is involved. +CREATE POLICY friendship_existing ON vibetype.friendship FOR ALL +USING ( + ( + vibetype.invoker_account_id() = a_account_id + AND b_account_id NOT IN (SELECT id FROM vibetype_private.account_block_ids()) + ) + OR + ( + vibetype.invoker_account_id() = b_account_id + AND a_account_id NOT IN (SELECT id FROM vibetype_private.account_block_ids()) + ) +) +WITH CHECK (FALSE); + +-- Only allow creation by the current user. +CREATE POLICY friendship_insert ON vibetype.friendship FOR INSERT +WITH CHECK ( + created_by = vibetype.invoker_account_id() +); + +-- Only allow update by the current user and only the state transition requested -> accepted. +CREATE POLICY friendship_update ON vibetype.friendship FOR UPDATE +USING ( + status = 'requested'::vibetype.friendship_status +) WITH CHECK ( + status = 'accepted'::vibetype.friendship_status + AND + updated_by = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_friendship_policy.sql b/src/deploy/table_friendship_policy.sql deleted file mode 100644 index 49ada1fa..00000000 --- a/src/deploy/table_friendship_policy.sql +++ /dev/null @@ -1,35 +0,0 @@ -BEGIN; - -GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.friendship TO vibetype_account; - -ALTER TABLE vibetype.friendship ENABLE ROW LEVEL SECURITY; - --- Only allow interactions with friendships in which the current user is involved. -CREATE POLICY friendship_existing ON vibetype.friendship FOR ALL USING ( - ( - vibetype.invoker_account_id() = a_account_id - AND b_account_id NOT IN (SELECT id FROM vibetype_private.account_block_ids()) - ) - OR - ( - vibetype.invoker_account_id() = b_account_id - AND a_account_id NOT IN (SELECT id FROM vibetype_private.account_block_ids()) - ) -) -WITH CHECK (FALSE); - --- Only allow creation by the current user. -CREATE POLICY friendship_insert ON vibetype.friendship FOR INSERT WITH CHECK ( - created_by = vibetype.invoker_account_id() -); - --- Only allow update by the current user and only the state transition requested -> accepted. -CREATE POLICY friendship_update ON vibetype.friendship FOR UPDATE USING ( - status = 'requested'::vibetype.friendship_status -) WITH CHECK ( - status = 'accepted'::vibetype.friendship_status - AND - updated_by = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_guest_policy.sql b/src/deploy/table_guest_policy.sql index 79424541..d5cd5a0c 100644 --- a/src/deploy/table_guest_policy.sql +++ b/src/deploy/table_guest_policy.sql @@ -5,7 +5,8 @@ GRANT INSERT, DELETE ON TABLE vibetype.guest TO vibetype_account; ALTER TABLE vibetype.guest ENABLE ROW LEVEL SECURITY; -CREATE POLICY guest_select ON vibetype.guest FOR SELECT USING ( +CREATE POLICY guest_select ON vibetype.guest FOR SELECT +USING ( -- Display guests accessible through guest claims. id = ANY (vibetype.guest_claim_array()) OR @@ -52,7 +53,8 @@ CREATE POLICY guest_select ON vibetype.guest FOR SELECT USING ( -- Only allow inserts for guests of events for which the maximum guest count is not yet reached. -- Only allow inserts for guests for a contact that was created by oneself. -- Do not allow inserts for guests for a contact referring a blocked account. -CREATE POLICY guest_insert ON vibetype.guest FOR INSERT WITH CHECK ( +CREATE POLICY guest_insert ON vibetype.guest FOR INSERT +WITH CHECK ( event_id IN (SELECT vibetype.events_organized()) AND ( @@ -83,7 +85,8 @@ CREATE POLICY guest_insert ON vibetype.guest FOR INSERT WITH CHECK ( -- Only allow updates to guests accessible through guest claims. -- Only allow updates to guests accessible through the account, but not guests auhored by a blocked account. -- Only allow updates to guests to events organized by oneself, but not guests referencing a blocked account or authored by a blocked account. -CREATE POLICY guest_update ON vibetype.guest FOR UPDATE USING ( +CREATE POLICY guest_update ON vibetype.guest FOR UPDATE +USING ( id = ANY (vibetype.guest_claim_array()) OR ( @@ -125,7 +128,8 @@ CREATE POLICY guest_update ON vibetype.guest FOR UPDATE USING ( ); -- Only allow deletes for guests of events organized by oneself. -CREATE POLICY guest_delete ON vibetype.guest FOR DELETE USING ( +CREATE POLICY guest_delete ON vibetype.guest FOR DELETE +USING ( event_id IN (SELECT vibetype.events_organized()) ); diff --git a/src/deploy/table_legal_term_acceptance.sql b/src/deploy/table_legal_term_acceptance.sql index aa5beb37..e0b22fa5 100644 --- a/src/deploy/table_legal_term_acceptance.sql +++ b/src/deploy/table_legal_term_acceptance.sql @@ -20,15 +20,8 @@ GRANT SELECT, INSERT ON TABLE vibetype.legal_term_acceptance TO vibetype_account ALTER TABLE vibetype.legal_term_acceptance ENABLE ROW LEVEL SECURITY; -- Allow to select legal term acceptances for the own account. -CREATE POLICY legal_term_acceptance_select ON vibetype.legal_term_acceptance FOR SELECT USING ( - vibetype.invoker_account_id() IS NOT NULL - AND - account_id = vibetype.invoker_account_id() -); - -CREATE POLICY legal_term_acceptance_insert ON vibetype.legal_term_acceptance FOR INSERT WITH CHECK ( - vibetype.invoker_account_id() IS NOT NULL - AND +CREATE POLICY legal_term_acceptance_all ON vibetype.legal_term_acceptance FOR ALL +USING ( account_id = vibetype.invoker_account_id() ); diff --git a/src/deploy/table_profile_picture.sql b/src/deploy/table_profile_picture.sql index 8a6d39b5..5055aa0f 100644 --- a/src/deploy/table_profile_picture.sql +++ b/src/deploy/table_profile_picture.sql @@ -16,40 +16,27 @@ COMMENT ON COLUMN vibetype.profile_picture.id IS E'@omit create,update\nThe prof COMMENT ON COLUMN vibetype.profile_picture.account_id IS 'The account''s id.'; COMMENT ON COLUMN vibetype.profile_picture.upload_id IS 'The upload''s id.'; -GRANT SELECT ON TABLE vibetype.profile_picture TO vibetype_account, vibetype_anonymous, :role_service_vibetype_username; -GRANT INSERT, DELETE, UPDATE ON TABLE vibetype.profile_picture TO vibetype_account; -GRANT DELETE ON TABLE vibetype.profile_picture TO :role_service_vibetype_username; +GRANT SELECT ON TABLE vibetype.profile_picture TO vibetype_anonymous; +GRANT INSERT, SELECT, DELETE, UPDATE ON TABLE vibetype.profile_picture TO vibetype_account; +GRANT SELECT, DELETE ON TABLE vibetype.profile_picture TO :role_service_vibetype_username; ALTER TABLE vibetype.profile_picture ENABLE ROW LEVEL SECURITY; --- Make all profile pictures accessible by everyone. -CREATE POLICY profile_picture_select ON vibetype.profile_picture FOR SELECT USING ( - TRUE -); - --- Only allow inserts with a account id that matches the invoker's account id. -CREATE POLICY profile_picture_insert ON vibetype.profile_picture FOR INSERT WITH CHECK ( - vibetype.invoker_account_id() IS NOT NULL - AND +CREATE POLICY profile_picture_all ON vibetype.profile_picture FOR ALL +USING ( account_id = vibetype.invoker_account_id() ); --- Only allow updates to the item with the account id that matches the invoker's account id. -CREATE POLICY profile_picture_update ON vibetype.profile_picture FOR UPDATE USING ( - vibetype.invoker_account_id() IS NOT NULL - AND - account_id = vibetype.invoker_account_id() +-- Make all profile pictures accessible by everyone. +CREATE POLICY profile_picture_select ON vibetype.profile_picture FOR SELECT USING ( + TRUE ); --- Only allow deletes for the item with the account id that matches the invoker's account id. -CREATE POLICY profile_picture_delete ON vibetype.profile_picture FOR DELETE USING ( - (SELECT current_user) = :'role_service_vibetype_username' - OR - ( - vibetype.invoker_account_id() IS NOT NULL - AND - account_id = vibetype.invoker_account_id() - ) +-- Allow all profile pictures to be deleted by the service. +CREATE POLICY profile_picture_delete_service ON vibetype.profile_picture FOR DELETE +TO :role_service_vibetype_username +USING ( + TRUE ); COMMIT; diff --git a/src/deploy/table_report.sql b/src/deploy/table_report.sql index bc279835..b9575634 100644 --- a/src/deploy/table_report.sql +++ b/src/deploy/table_report.sql @@ -27,4 +27,13 @@ COMMENT ON CONSTRAINT report_reason_check ON vibetype.report IS 'Ensures the rea COMMENT ON CONSTRAINT report_check ON vibetype.report IS 'Ensures that the report targets exactly one element (account, event, or upload).'; COMMENT ON CONSTRAINT report_created_by_target_account_id_target_event_id_target__key ON vibetype.report IS 'Ensures that the same user cannot submit multiple reports on the same element (account, event, or upload).'; +GRANT INSERT, SELECT ON TABLE vibetype.report TO vibetype_account; + +ALTER TABLE vibetype.report ENABLE ROW LEVEL SECURITY; + +CREATE POLICY report_all ON vibetype.report FOR ALL +USING ( + created_by = vibetype.invoker_account_id() +); + COMMIT; diff --git a/src/deploy/table_report_policy.sql b/src/deploy/table_report_policy.sql deleted file mode 100644 index f61121a0..00000000 --- a/src/deploy/table_report_policy.sql +++ /dev/null @@ -1,21 +0,0 @@ -BEGIN; - -GRANT INSERT, SELECT ON TABLE vibetype.report TO vibetype_account; - -ALTER TABLE vibetype.report ENABLE ROW LEVEL SECURITY; - --- Only allow selects for reports created by the current user. -CREATE POLICY report_select ON vibetype.report FOR SELECT USING ( - vibetype.invoker_account_id() IS NOT NULL - AND - created_by = vibetype.invoker_account_id() -); - --- Only allow inserts for reports created by the current user. -CREATE POLICY report_insert ON vibetype.report FOR INSERT WITH CHECK ( - vibetype.invoker_account_id() IS NOT NULL - AND - created_by = vibetype.invoker_account_id() -); - -COMMIT; diff --git a/src/deploy/table_upload_policy.sql b/src/deploy/table_upload_policy.sql index 5d382699..7b5277f7 100644 --- a/src/deploy/table_upload_policy.sql +++ b/src/deploy/table_upload_policy.sql @@ -2,36 +2,26 @@ BEGIN; \set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -GRANT SELECT ON TABLE vibetype.upload TO vibetype_account, vibetype_anonymous, :role_service_vibetype_username; -GRANT UPDATE ON TABLE vibetype.upload TO :role_service_vibetype_username; -GRANT DELETE ON TABLE vibetype.upload TO :role_service_vibetype_username; +GRANT SELECT ON TABLE vibetype.upload TO vibetype_account, vibetype_anonymous; +GRANT SELECT, UPDATE, DELETE ON TABLE vibetype.upload TO :role_service_vibetype_username; ALTER TABLE vibetype.upload ENABLE ROW LEVEL SECURITY; +-- Allow the service role to select, update, or delete rows. +CREATE POLICY upload_all_service ON vibetype.upload FOR ALL +TO :role_service_vibetype_username +USING ( + TRUE +); + -- Display --- - all uploads for the server or -- - the uploads that are linked to the requesting account or -- - the uploads which are used as profile picture. -CREATE POLICY upload_select_using ON vibetype.upload FOR SELECT USING ( - (SELECT current_user) = :'role_service_vibetype_username' - OR - ( - vibetype.invoker_account_id() IS NOT NULL - AND - account_id = vibetype.invoker_account_id() - ) +CREATE POLICY upload_select ON vibetype.upload FOR SELECT USING ( + account_id = vibetype.invoker_account_id() OR id IN (SELECT upload_id FROM vibetype.profile_picture) ); --- Only allow the server to update rows. -CREATE POLICY upload_update_using ON vibetype.upload FOR UPDATE USING ( - (SELECT current_user) = :'role_service_vibetype_username' -); - --- Only allow the server to delete rows. -CREATE POLICY upload_delete_using ON vibetype.upload FOR DELETE USING ( - (SELECT current_user) = :'role_service_vibetype_username' -); COMMIT; diff --git a/src/revert/table_account_block.sql b/src/revert/table_account_block.sql index 8b6cb153..bad932ed 100644 --- a/src/revert/table_account_block.sql +++ b/src/revert/table_account_block.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY account_block_all ON vibetype.account_block; + DROP TABLE vibetype.account_block; COMMIT; diff --git a/src/revert/table_account_block_policy.sql b/src/revert/table_account_block_policy.sql deleted file mode 100644 index ba7f674d..00000000 --- a/src/revert/table_account_block_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY account_block_select ON vibetype.account_block; -DROP POLICY account_block_insert ON vibetype.account_block; -DROP POLICY account_block_delete ON vibetype.account_block; - -COMMIT; diff --git a/src/revert/table_account_preference_event_category.sql b/src/revert/table_account_preference_event_category.sql index a99a243e..d7f34511 100644 --- a/src/revert/table_account_preference_event_category.sql +++ b/src/revert/table_account_preference_event_category.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY account_preference_event_category_all ON vibetype.account_preference_event_category; + DROP TABLE vibetype.account_preference_event_category; COMMIT; diff --git a/src/revert/table_account_preference_event_category_policy.sql b/src/revert/table_account_preference_event_category_policy.sql deleted file mode 100644 index d047c031..00000000 --- a/src/revert/table_account_preference_event_category_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY account_preference_event_category_delete ON vibetype.account_preference_event_category; -DROP POLICY account_preference_event_category_insert ON vibetype.account_preference_event_category; -DROP POLICY account_preference_event_category_select ON vibetype.account_preference_event_category; - -COMMIT; diff --git a/src/revert/table_account_preference_event_format.sql b/src/revert/table_account_preference_event_format.sql index 7b393659..56ccaf4f 100644 --- a/src/revert/table_account_preference_event_format.sql +++ b/src/revert/table_account_preference_event_format.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY account_preference_event_format_all ON vibetype.account_preference_event_format; + DROP TABLE vibetype.account_preference_event_format; COMMIT; diff --git a/src/revert/table_account_preference_event_format_policy.sql b/src/revert/table_account_preference_event_format_policy.sql deleted file mode 100644 index 40f2f744..00000000 --- a/src/revert/table_account_preference_event_format_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY account_preference_event_format_delete ON vibetype.account_preference_event_format; -DROP POLICY account_preference_event_format_insert ON vibetype.account_preference_event_format; -DROP POLICY account_preference_event_format_select ON vibetype.account_preference_event_format; - -COMMIT; diff --git a/src/revert/table_account_preference_event_size.sql b/src/revert/table_account_preference_event_size.sql index f486b908..8d0a2d6c 100644 --- a/src/revert/table_account_preference_event_size.sql +++ b/src/revert/table_account_preference_event_size.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY account_preference_event_size_all ON vibetype.account_preference_event_size; + DROP TABLE vibetype.account_preference_event_size; COMMIT; diff --git a/src/revert/table_account_preference_event_size_policy.sql b/src/revert/table_account_preference_event_size_policy.sql deleted file mode 100644 index 3e0eaa01..00000000 --- a/src/revert/table_account_preference_event_size_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY account_preference_event_size_delete ON vibetype.account_preference_event_size; -DROP POLICY account_preference_event_size_insert ON vibetype.account_preference_event_size; -DROP POLICY account_preference_event_size_select ON vibetype.account_preference_event_size; - -COMMIT; diff --git a/src/revert/table_account_public.sql b/src/revert/table_account_public.sql index 9970368e..38809f0c 100644 --- a/src/revert/table_account_public.sql +++ b/src/revert/table_account_public.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY account_select ON vibetype.account; + DROP TABLE vibetype.account; COMMIT; diff --git a/src/revert/table_account_social_network.sql b/src/revert/table_account_social_network.sql index 84df1713..33cd3c47 100644 --- a/src/revert/table_account_social_network.sql +++ b/src/revert/table_account_social_network.sql @@ -1,5 +1,8 @@ BEGIN; -DROP TABLE vibetype.account_social_network ; +DROP POLICY account_social_network_select ON vibetype.account_social_network; +DROP POLICY account_social_network_all ON vibetype.account_social_network; + +DROP TABLE vibetype.account_social_network; COMMIT; diff --git a/src/revert/table_account_social_network_policy.sql b/src/revert/table_account_social_network_policy.sql deleted file mode 100644 index 6086e9cf..00000000 --- a/src/revert/table_account_social_network_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY account_social_network_delete ON vibetype.account_social_network; -DROP POLICY account_social_network_update ON vibetype.account_social_network; -DROP POLICY account_social_network_insert ON vibetype.account_social_network; - -COMMIT; diff --git a/src/revert/table_achievement.sql b/src/revert/table_achievement.sql index 644f4b60..e108df86 100644 --- a/src/revert/table_achievement.sql +++ b/src/revert/table_achievement.sql @@ -1,6 +1,7 @@ BEGIN; DROP POLICY achievement_select ON vibetype.achievement; + DROP TABLE vibetype.achievement; COMMIT; diff --git a/src/revert/table_achievement_code.sql b/src/revert/table_achievement_code.sql index c85468b2..569378e8 100644 --- a/src/revert/table_achievement_code.sql +++ b/src/revert/table_achievement_code.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY achievement_code_select ON vibetype_private.achievement_code; + DROP TABLE vibetype_private.achievement_code; COMMIT; diff --git a/src/revert/table_address.sql b/src/revert/table_address.sql index 45e034b7..1d0b99c4 100644 --- a/src/revert/table_address.sql +++ b/src/revert/table_address.sql @@ -1,6 +1,9 @@ BEGIN; +DROP POLICY address_all ON vibetype.address; + DROP TRIGGER vibetype_trigger_address_update ON vibetype.address; + DROP INDEX vibetype.idx_address_updated_by; DROP INDEX vibetype.idx_address_created_by; DROP INDEX vibetype.idx_address_location; diff --git a/src/revert/table_address_policy.sql b/src/revert/table_address_policy.sql deleted file mode 100644 index e05854c9..00000000 --- a/src/revert/table_address_policy.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP POLICY address ON vibetype.address; - -COMMIT; diff --git a/src/revert/table_device.sql b/src/revert/table_device.sql index 67bc62b4..981377b1 100644 --- a/src/revert/table_device.sql +++ b/src/revert/table_device.sql @@ -1,8 +1,11 @@ BEGIN; +DROP POLICY device_all ON vibetype.device; + DROP TRIGGER vibetype_trigger_device_update_fcm ON vibetype.device; DROP FUNCTION vibetype.trigger_metadata_update_fcm; DROP TRIGGER vibetype_trigger_device_update ON vibetype.device; + DROP INDEX vibetype.idx_device_updated_by; DROP TABLE vibetype.device; diff --git a/src/revert/table_device_policy.sql b/src/revert/table_device_policy.sql deleted file mode 100644 index 0524324d..00000000 --- a/src/revert/table_device_policy.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP POLICY device ON vibetype.device; - -COMMIT; diff --git a/src/revert/table_event_category_mapping.sql b/src/revert/table_event_category_mapping.sql index 35b80c8c..22818821 100644 --- a/src/revert/table_event_category_mapping.sql +++ b/src/revert/table_event_category_mapping.sql @@ -1,5 +1,9 @@ BEGIN; +DROP POLICY event_category_mapping_select ON vibetype.event_category_mapping; +DROP POLICY event_category_mapping_insert ON vibetype.event_category_mapping; +DROP POLICY event_category_mapping_delete ON vibetype.event_category_mapping; + DROP TABLE vibetype.event_category_mapping; COMMIT; diff --git a/src/revert/table_event_category_mapping_policy.sql b/src/revert/table_event_category_mapping_policy.sql deleted file mode 100644 index 10667659..00000000 --- a/src/revert/table_event_category_mapping_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY event_category_mapping_delete ON vibetype.event_category_mapping; -DROP POLICY event_category_mapping_insert ON vibetype.event_category_mapping; -DROP POLICY event_category_mapping_select ON vibetype.event_category_mapping; - -COMMIT; diff --git a/src/revert/table_event_category_policy.sql b/src/revert/table_event_category_policy.sql deleted file mode 100644 index c4c4836d..00000000 --- a/src/revert/table_event_category_policy.sql +++ /dev/null @@ -1,3 +0,0 @@ -BEGIN; - -COMMIT; diff --git a/src/revert/table_event_favorite.sql b/src/revert/table_event_favorite.sql index e334a00d..a31f2d14 100644 --- a/src/revert/table_event_favorite.sql +++ b/src/revert/table_event_favorite.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY event_favorite_all ON vibetype.event_favorite; + DROP TABLE vibetype.event_favorite; COMMIT; diff --git a/src/revert/table_event_favorite_policy.sql b/src/revert/table_event_favorite_policy.sql deleted file mode 100644 index 45c12b4f..00000000 --- a/src/revert/table_event_favorite_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY event_favorite_delete ON vibetype.event_favorite; -DROP POLICY event_favorite_insert ON vibetype.event_favorite; -DROP POLICY event_favorite_select ON vibetype.event_favorite; - -COMMIT; diff --git a/src/revert/table_event_policy.sql b/src/revert/table_event_policy.sql index f769fce9..3d79ea9e 100644 --- a/src/revert/table_event_policy.sql +++ b/src/revert/table_event_policy.sql @@ -1,7 +1,6 @@ BEGIN; -DROP POLICY event_update ON vibetype.event; -DROP POLICY event_insert ON vibetype.event; +DROP POLICY event_all ON vibetype.event; DROP POLICY event_select ON vibetype.event; COMMIT; diff --git a/src/revert/table_event_recommendation.sql b/src/revert/table_event_recommendation.sql index fc74aca2..14fcbeba 100644 --- a/src/revert/table_event_recommendation.sql +++ b/src/revert/table_event_recommendation.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY event_recommendation_select ON vibetype.event_recommendation; + DROP TABLE vibetype.event_recommendation; COMMIT; diff --git a/src/revert/table_event_recommendation_policy.sql b/src/revert/table_event_recommendation_policy.sql deleted file mode 100644 index 612414bd..00000000 --- a/src/revert/table_event_recommendation_policy.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP POLICY event_recommendation_select ON vibetype.event_recommendation; - -COMMIT; diff --git a/src/revert/table_event_upload.sql b/src/revert/table_event_upload.sql index 70a629e8..c57c9730 100644 --- a/src/revert/table_event_upload.sql +++ b/src/revert/table_event_upload.sql @@ -1,5 +1,9 @@ BEGIN; +DROP POLICY event_upload_delete ON vibetype.event_upload; +DROP POLICY event_upload_insert ON vibetype.event_upload; +DROP POLICY event_upload_select ON vibetype.event_upload; + DROP TABLE vibetype.event_upload; COMMIT; diff --git a/src/revert/table_event_upload_policy.sql b/src/revert/table_event_upload_policy.sql deleted file mode 100644 index 4b0b07b5..00000000 --- a/src/revert/table_event_upload_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY event_upload_delete ON vibetype.event_upload; -DROP POLICY event_upload_insert ON vibetype.event_upload; -DROP POLICY event_upload_select ON vibetype.event_upload; - -COMMIT; diff --git a/src/revert/table_friendship.sql b/src/revert/table_friendship.sql index dd268018..8d3a165d 100644 --- a/src/revert/table_friendship.sql +++ b/src/revert/table_friendship.sql @@ -1,5 +1,11 @@ BEGIN; +DROP POLICY friendship_update ON vibetype.friendship; +DROP POLICY friendship_insert ON vibetype.friendship; +DROP POLICY friendship_existing ON vibetype.friendship; + +DROP TRIGGER vibetype_trigger_friendship_update ON vibetype.friendship; + DROP INDEX vibetype.idx_friendship_updated_by; DROP INDEX vibetype.idx_friendship_created_by; DROP TABLE vibetype.friendship; diff --git a/src/revert/table_friendship_policy.sql b/src/revert/table_friendship_policy.sql deleted file mode 100644 index 703cdd98..00000000 --- a/src/revert/table_friendship_policy.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -DROP POLICY friendship_update ON vibetype.friendship; -DROP POLICY friendship_insert ON vibetype.friendship; -DROP POLICY friendship_existing ON vibetype.friendship; - -COMMIT; diff --git a/src/revert/table_legal_term.sql b/src/revert/table_legal_term.sql index 9a446d0c..a48d16b1 100644 --- a/src/revert/table_legal_term.sql +++ b/src/revert/table_legal_term.sql @@ -1,9 +1,11 @@ BEGIN; DROP POLICY legal_term_select ON vibetype.legal_term; + DROP TRIGGER vibetype_legal_term_delete ON vibetype.legal_term; DROP TRIGGER vibetype_legal_term_update ON vibetype.legal_term; DROP FUNCTION vibetype.legal_term_change; + DROP TABLE vibetype.legal_term; COMMIT; diff --git a/src/revert/table_legal_term_acceptance.sql b/src/revert/table_legal_term_acceptance.sql index d9b51eef..b75ef21b 100644 --- a/src/revert/table_legal_term_acceptance.sql +++ b/src/revert/table_legal_term_acceptance.sql @@ -1,7 +1,6 @@ BEGIN; -DROP POLICY legal_term_acceptance_insert ON vibetype.legal_term_acceptance; -DROP POLICY legal_term_acceptance_select ON vibetype.legal_term_acceptance; +DROP POLICY legal_term_acceptance_all ON vibetype.legal_term_acceptance; DROP TABLE vibetype.legal_term_acceptance; diff --git a/src/revert/table_profile_picture.sql b/src/revert/table_profile_picture.sql index 487e0742..f1a18c66 100644 --- a/src/revert/table_profile_picture.sql +++ b/src/revert/table_profile_picture.sql @@ -1,5 +1,9 @@ BEGIN; +DROP POLICY profile_picture_all ON vibetype.profile_picture; +DROP POLICY profile_picture_select ON vibetype.profile_picture; +DROP POLICY profile_picture_delete_service ON vibetype.profile_picture; + DROP TABLE vibetype.profile_picture; COMMIT; diff --git a/src/revert/table_report.sql b/src/revert/table_report.sql index c3d19552..1419b54d 100644 --- a/src/revert/table_report.sql +++ b/src/revert/table_report.sql @@ -1,5 +1,7 @@ BEGIN; +DROP POLICY report_all ON vibetype.report; + DROP TABLE vibetype.report; COMMIT; diff --git a/src/revert/table_report_policy.sql b/src/revert/table_report_policy.sql deleted file mode 100644 index 16491ff5..00000000 --- a/src/revert/table_report_policy.sql +++ /dev/null @@ -1,6 +0,0 @@ -BEGIN; - -DROP POLICY report_insert ON vibetype.report; -DROP POLICY report_select ON vibetype.report; - -COMMIT; diff --git a/src/revert/table_upload_policy.sql b/src/revert/table_upload_policy.sql index ff2ed41d..a3a0d604 100644 --- a/src/revert/table_upload_policy.sql +++ b/src/revert/table_upload_policy.sql @@ -1,7 +1,6 @@ BEGIN; -DROP POLICY upload_delete_using ON vibetype.upload; -DROP POLICY upload_update_using ON vibetype.upload; -DROP POLICY upload_select_using ON vibetype.upload; +DROP POLICY upload_all_service ON vibetype.upload; +DROP POLICY upload_select ON vibetype.upload; COMMIT; diff --git a/src/sqitch.plan b/src/sqitch.plan index d948cfc9..48ba8cc4 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -18,13 +18,11 @@ table_notification [schema_private] 1970-01-01T00:00:00Z Jonas Thelemann # Add private table account. table_account_public [schema_public schema_private table_account_private] 1970-01-01T00:00:00Z Jonas Thelemann # Add public table account. table_account_block [schema_public table_account_public] 1970-01-01T00:00:00Z Sven Thelemann # Blocking of an account by another account. -table_account_block_policy [schema_public table_account_block role_account role_anonymous function_invoker_account_id] 1970-01-01T00:00:00Z Sven Thelemann # Policy for table account block. function_account_block_ids [schema_public table_account_block role_account role_anonymous function_invoker_account_id] 1970-01-01T00:00:00Z Sven Thelemann # Function returning all account id's involved in blocking. table_event_group [schema_public role_account role_anonymous table_account_public enum_event_visibility] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event_group. enum_language [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Supported ISO 639 language codes. function_language_iso_full_text_search [privilege_execute_revoke schema_public enum_language] 1970-01-01T00:00:00Z Jonas Thelemann # ISO language code to full text search language conversion. table_address [schema_public table_account_public function_trigger_metadata_update] 1970-01-01T00:00:00Z Jonas Thelemann # Stores detailed address information, including lines, city, state, country, and metadata. -table_address_policy [schema_public table_address role_account role_anonymous function_invoker_account_id function_account_block_ids] 1970-01-01T00:00:00Z Jonas Thelemann # Policy for table address. table_event [schema_public table_address table_account_public enum_language enum_event_visibility function_language_iso_full_text_search role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event. function_events_organized [privilege_execute_revoke schema_public function_invoker_account_id table_event role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns all event ids for which the invoker is the creator. enum_invitation_feedback_paper 1970-01-01T00:00:00Z Jonas Thelemann # Possible choices on how to receive a paper invitation: paper, digital. @@ -68,37 +66,25 @@ table_achievement_code [schema_private schema_public enum_achievement_type] 1970 table_achievement [schema_public table_account_public enum_achievement_type role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Achievement unlocks by user. function_achievement_unlock [privilege_execute_revoke schema_public enum_achievement_type function_invoker_account_id schema_private table_achievement_code table_achievement role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Unlock achievements. table_report [schema_public table_account_public table_event table_upload] 1970-01-01T00:00:00Z Marlon # Stores reports made by users on other users, events, or uploads for moderation purposes. -table_report_policy [schema_public table_report role_account function_invoker_account_id] 1970-01-01T00:00:00Z Marlon # Access policies for reports. enum_social_network [schema_public] 1970-01-01T00:00:00Z sven # Social networks. table_account_social_network [schema_public table_account_public enum_social_network] 1970-01-01T00:00:00Z sven # Links accounts to their social media profiles. -table_account_social_network_policy [schema_public table_account_social_network function_invoker_account_id role_account] 1970-01-01T00:00:00Z sven # Security policies for the accounts' social networks. enum_event_size [schema_public] 1970-01-01T00:00:00Z Sven Thelemann # Possible event sizes: small, medium, large, huge. table_account_preference_event_size [schema_public table_account_public enum_event_size] 1970-01-01T00:00:00Z Sven Thelemann # Table for the user accounts' preferred event sizes (M:N relationship). -table_account_preference_event_size_policy [schema_public table_account_preference_event_size function_invoker_account_id role_account] 1970-01-01T00:00:00Z Sven Thelemann # Security policy for the accounts' event size preferences. table_event_upload [schema_public table_event table_upload] 1970-01-01T00:00:00Z Sven Thelemann # Add table event_upload. -table_event_upload_policy [schema_public table_event_upload role_account role_anonymous table_event table_upload] 1970-01-01T00:00:00Z Sven Thelemann # Grants and policies for event uploads. view_guest_flat [schema_public table_guest table_contact table_event role_account role_anonymous] 1970-01-01T00:00:00Z Sven Thelemann # View returning flattened guests. table_event_category [schema_public] 1970-01-01T00:00:00Z sven # Event categories. -table_event_category_policy [schema_public table_event_category role_anonymous role_account] 1970-01-01T00:00:00Z marlon # Security policies for event categories. table_account_preference_event_category [schema_public table_account_public table_event_category] 1970-01-01T00:00:00Z marlon # Event categories a user account is interested in (M:N relationship). -table_account_preference_event_category_policy [schema_public table_account_preference_event_category role_account] 1970-01-01T00:00:00Z marlon # Security policies for the accounts' event category preferences. table_event_category_mapping [schema_public table_event table_event_category] 1970-01-01T00:00:00Z marlon # Mapping events to categories (M:N relationship). -table_event_category_mapping_policy [schema_public table_event_category_mapping role_anonymous role_account table_event function_account_block_ids]1970-01-01T00:00:00Z marlon # Security policies for event category mappings. table_event_recommendation [schema_public table_account_public table_event] 1970-01-01T00:00:00Z marlon # Events recommended to a user account (M:N relationship). -table_event_recommendation_policy [schema_public table_event_recommendation role_account] 1970-01-01T00:00:00Z marlon # Security policies for event recommendations. table_event_favorite [schema_public table_account_public table_event] 1970-01-01T00:00:00Z Sven Thelemann # A table for the user accounts' favorite events. -table_event_favorite_policy [schema_public table_account_public table_event role_account] 1970-01-01T00:00:00Z Sven Thelemann # Security policies for event favorites. function_guest_create_multiple [schema_public table_guest role_account] 1970-01-01T00:00:00Z Sven Thelemann # Function for inserting multiple guest records. function_event_search [privilege_execute_revoke schema_public enum_language schema_private function_language_iso_full_text_search table_event role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Full-text search on events. table_device [schema_public table_account_public function_trigger_metadata_update] 1970-01-01T00:00:00Z Jonas Thelemann # A device that's assigned to an account. -table_device_policy [schema_public table_device role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Policies for devices. enum_friendship_status [schema_public] 1970-01-01T00:00:00Z Sven Thelemann # Possible status values of a friend relation. table_friendship [schema_public enum_friendship_status table_account_public function_trigger_metadata_update] 1970-01-01T00:00:00Z Sven Thelemann # A friend relation together with its status. -table_friendship_policy [schema_public table_friendship role_account] 1970-01-01T00:00:00Z Sven Thelemann # Policy for table friend. table_event_format [schema_public role_anonymous role_account] 1970-01-01T00:00:00Z Jonas Thelemann # Table for storing event formats. table_event_format_mapping [schema_public table_event table_event_format role_anonymous role_account function_invoker_account_id] 1970-01-01T00:00:00Z Jonas Thelemann # Table for storing event to category (M:N) relationships. table_audit_log [schema_private] 1970-01-01T00:00:00Z Sven Thelemann # Table for storing audit log records. view_audit_log_trigger [schema_private] 1970-01-01T00:00:00Z Sven Thelemann # View showing all audit log triggers. function_audit_log [schema_private table_audit_log view_audit_log_trigger] 1970-01-01T00:00:00Z Sven Thelemann # Utility functions for managing audit log triggers. table_account_preference_event_format [schema_public table_account_public table_event_category] 1970-01-01T00:00:00Z Sven Thelemann # Event formats a user account is interested in (M:N relationship). -table_account_preference_event_format_policy [schema_public table_account_preference_event_format role_account] 1970-01-01T00:00:00Z Sven Thelemann # Security policies for the accounts' event format preferences. diff --git a/src/verify/table_account_block.sql b/src/verify/table_account_block.sql index b84fd212..1e3b562e 100644 --- a/src/verify/table_account_block.sql +++ b/src/verify/table_account_block.sql @@ -7,3 +7,26 @@ SELECT id, FROM vibetype.account_block WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'DELETE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'DELETE')); +END $$; + +ROLLBACK; diff --git a/src/verify/table_account_block_policy.sql b/src/verify/table_account_block_policy.sql deleted file mode 100644 index e6ac6bb8..00000000 --- a/src/verify/table_account_block_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_block', 'DELETE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_block', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_block', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_account_preference_event_category.sql b/src/verify/table_account_preference_event_category.sql index ba583cb9..3b7cb764 100644 --- a/src/verify/table_account_preference_event_category.sql +++ b/src/verify/table_account_preference_event_category.sql @@ -9,3 +9,26 @@ FROM vibetype.account_preference_event_category a WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'DELETE')); +END $$; + +ROLLBACK; \ No newline at end of file diff --git a/src/verify/table_account_preference_event_category_policy.sql b/src/verify/table_account_preference_event_category_policy.sql deleted file mode 100644 index d5397ba9..00000000 --- a/src/verify/table_account_preference_event_category_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_category', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_category', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_category', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_account_preference_event_format.sql b/src/verify/table_account_preference_event_format.sql index 403e29ca..ba607fb4 100644 --- a/src/verify/table_account_preference_event_format.sql +++ b/src/verify/table_account_preference_event_format.sql @@ -9,3 +9,26 @@ FROM vibetype.account_preference_event_format a WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'DELETE')); +END $$; + +ROLLBACK; \ No newline at end of file diff --git a/src/verify/table_account_preference_event_format_policy.sql b/src/verify/table_account_preference_event_format_policy.sql deleted file mode 100644 index ca25eb52..00000000 --- a/src/verify/table_account_preference_event_format_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_format', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_format', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_format', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_account_preference_event_size.sql b/src/verify/table_account_preference_event_size.sql index 99760a15..3d493602 100644 --- a/src/verify/table_account_preference_event_size.sql +++ b/src/verify/table_account_preference_event_size.sql @@ -6,3 +6,26 @@ SELECT account_id, FROM vibetype.account_preference_event_size WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'DELETE')); +END $$; + +ROLLBACK; \ No newline at end of file diff --git a/src/verify/table_account_preference_event_size_policy.sql b/src/verify/table_account_preference_event_size_policy.sql deleted file mode 100644 index 6f9ba0f9..00000000 --- a/src/verify/table_account_preference_event_size_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.account_preference_event_size', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.account_preference_event_size', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.account_preference_event_size', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_account_social_network.sql b/src/verify/table_account_social_network.sql index 1ddbf6db..2cb98c7b 100644 --- a/src/verify/table_account_social_network.sql +++ b/src/verify/table_account_social_network.sql @@ -6,4 +6,102 @@ SELECT social_network_username FROM vibetype.account_social_network WHERE FALSE; +SAVEPOINT select_account; +DO $$ +BEGIN + SET LOCAL role TO vibetype_account; + PERFORM * FROM vibetype.account_social_network; +END $$; +ROLLBACK TO SAVEPOINT select_account; + +SAVEPOINT select_anonymous; +DO $$ +BEGIN + SET LOCAL role TO vibetype_anonymous; + PERFORM * FROM vibetype.account_social_network; +END $$; +ROLLBACK TO SAVEPOINT select_anonymous; + +SAVEPOINT insert_account; +DO $$ +BEGIN + INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); + INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); + + SET LOCAL role TO vibetype_account; + SET LOCAL jwt.claims.account_id TO '00000000-0000-0000-0000-000000000000'; + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); +END $$; +ROLLBACK TO SAVEPOINT insert_account; + +SAVEPOINT insert_anonymous; +DO $$ +BEGIN + INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); + INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); + + SET LOCAL role TO vibetype_anonymous; + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) + VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); + RAISE EXCEPTION 'Test insert_anonymous failed: Anonymous users should not be able to insert'; +EXCEPTION WHEN others THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT insert_anonymous; + +SAVEPOINT update_account; +DO $$ +BEGIN + INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); + INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); + + SET LOCAL role TO vibetype_account; + UPDATE vibetype.account_social_network SET social_network_username = 'username-updated'; +END $$; +ROLLBACK TO SAVEPOINT update_account; + +SAVEPOINT update_anonymous; +DO $$ +BEGIN + INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); + INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); + + SET LOCAL role TO vibetype_anonymous; + UPDATE vibetype.account_social_network SET social_network_username = 'username-updated'; + RAISE EXCEPTION 'Test update_anonymous failed: Anonymous users should not be able to update'; +EXCEPTION WHEN others THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT update_anonymous; + +SAVEPOINT delete_account; +DO $$ +BEGIN + INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); + INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); + + SET LOCAL role TO vibetype_account; + DELETE FROM vibetype.account_social_network; +END $$; +ROLLBACK TO SAVEPOINT delete_account; + +SAVEPOINT delete_anonymous; +DO $$ +BEGIN + INSERT INTO vibetype_private.account(id, email_address, password_hash) VALUES ('00000000-0000-0000-0000-000000000000', 'email@example.com', '$2a$06$xdJFoht/HQ/4798obSknNOc6hiBe60HXriyW/Oa3Ch7Oo3F.9WGLe'); + INSERT INTO vibetype.account(id, username) VALUES ('00000000-0000-0000-0000-000000000000', 'username'); + INSERT INTO vibetype.account_social_network(account_id, social_network, social_network_username) VALUES ('00000000-0000-0000-0000-000000000000', 'instagram', 'username'); + + SET LOCAL role TO vibetype_anonymous; + DELETE FROM vibetype.account_social_network; + RAISE EXCEPTION 'Test delete_anonymous failed: Anonymous users should not be able to delete'; +EXCEPTION WHEN others THEN + NULL; +END $$; +ROLLBACK TO SAVEPOINT delete_anonymous; + ROLLBACK; diff --git a/src/verify/table_account_social_network_policy.sql b/src/verify/table_account_social_network_policy.sql deleted file mode 100644 index e06f24e3..00000000 --- a/src/verify/table_account_social_network_policy.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - --- in /test/logic/scenario/model/account_social_network.sql - -ROLLBACK; diff --git a/src/verify/table_address.sql b/src/verify/table_address.sql index 5c6411ad..89a3d315 100644 --- a/src/verify/table_address.sql +++ b/src/verify/table_address.sql @@ -18,3 +18,26 @@ SELECT id, FROM vibetype.address WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'DELETE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'DELETE')); +END $$; + +ROLLBACK; \ No newline at end of file diff --git a/src/verify/table_address_policy.sql b/src/verify/table_address_policy.sql deleted file mode 100644 index cdf13553..00000000 --- a/src/verify/table_address_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'DELETE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_device.sql b/src/verify/table_device.sql index 9158547d..d0d745dd 100644 --- a/src/verify/table_device.sql +++ b/src/verify/table_device.sql @@ -9,4 +9,27 @@ SELECT id, FROM vibetype.device WHERE FALSE; +ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'DELETE')); +END $$; + ROLLBACK; diff --git a/src/verify/table_device_policy.sql b/src/verify/table_device_policy.sql deleted file mode 100644 index dd75283d..00000000 --- a/src/verify/table_device_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.device', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.device', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.device', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_event_category.sql b/src/verify/table_event_category.sql index 7b022b3c..af638c85 100644 --- a/src/verify/table_event_category.sql +++ b/src/verify/table_event_category.sql @@ -4,3 +4,27 @@ SELECT id, name FROM vibetype.event_category WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'DELETE')); +END $$; + +ROLLBACK; + diff --git a/src/verify/table_event_category_mapping.sql b/src/verify/table_event_category_mapping.sql index 1f0a8831..c857fec5 100644 --- a/src/verify/table_event_category_mapping.sql +++ b/src/verify/table_event_category_mapping.sql @@ -5,3 +5,26 @@ SELECT event_id, FROM vibetype.event_category_mapping WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'DELETE')); +END $$; + +ROLLBACK; diff --git a/src/verify/table_event_category_mapping_policy.sql b/src/verify/table_event_category_mapping_policy.sql deleted file mode 100644 index 34cf0cc3..00000000 --- a/src/verify/table_event_category_mapping_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category_mapping', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category_mapping', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category_mapping', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_event_category_policy.sql b/src/verify/table_event_category_policy.sql deleted file mode 100644 index ed5f4712..00000000 --- a/src/verify/table_event_category_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_category', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_category', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_category', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_event_favorite.sql b/src/verify/table_event_favorite.sql index 882ffd4e..31ddcdc1 100644 --- a/src/verify/table_event_favorite.sql +++ b/src/verify/table_event_favorite.sql @@ -7,3 +7,26 @@ SELECT id, FROM vibetype.event_favorite WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'DELETE')); +END $$; + +ROLLBACK; diff --git a/src/verify/table_event_favorite_policy.sql b/src/verify/table_event_favorite_policy.sql deleted file mode 100644 index 20ef1e24..00000000 --- a/src/verify/table_event_favorite_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_favorite', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_favorite', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_favorite', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_event_recommendation.sql b/src/verify/table_event_recommendation.sql index 69970521..71f022ea 100644 --- a/src/verify/table_event_recommendation.sql +++ b/src/verify/table_event_recommendation.sql @@ -7,3 +7,26 @@ SELECT account_id, FROM vibetype.event_recommendation WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'DELETE')); + ASSERT NOT(SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'DELETE')); +END $$; + +ROLLBACK; \ No newline at end of file diff --git a/src/verify/table_event_recommendation_policy.sql b/src/verify/table_event_recommendation_policy.sql deleted file mode 100644 index e5719c54..00000000 --- a/src/verify/table_event_recommendation_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'DELETE')); - ASSERT NOT(SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_recommendation', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_recommendation', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_recommendation', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_event_upload.sql b/src/verify/table_event_upload.sql index d09d7d73..9d66da63 100644 --- a/src/verify/table_event_upload.sql +++ b/src/verify/table_event_upload.sql @@ -5,3 +5,26 @@ SELECT id, is_header_image, upload_id FROM vibetype.event_upload WHERE FALSE; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'DELETE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'DELETE')); +END $$; + +ROLLBACK; diff --git a/src/verify/table_event_upload_policy.sql b/src/verify/table_event_upload_policy.sql deleted file mode 100644 index 26475d84..00000000 --- a/src/verify/table_event_upload_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_upload', 'DELETE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_upload', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_upload', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_friendship.sql b/src/verify/table_friendship.sql index 7c97ce57..66005c24 100644 --- a/src/verify/table_friendship.sql +++ b/src/verify/table_friendship.sql @@ -13,3 +13,26 @@ FROM vibetype.friendship WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'DELETE')); +END $$; + +ROLLBACK; diff --git a/src/verify/table_friendship_policy.sql b/src/verify/table_friendship_policy.sql deleted file mode 100644 index d3ff13f4..00000000 --- a/src/verify/table_friendship_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.friendship', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.friendship', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.friendship', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_report.sql b/src/verify/table_report.sql index 7275de4e..c9752765 100644 --- a/src/verify/table_report.sql +++ b/src/verify/table_report.sql @@ -10,3 +10,26 @@ SELECT id, FROM vibetype.report WHERE FALSE; ROLLBACK; + +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'DELETE')); +END $$; + +ROLLBACK; diff --git a/src/verify/table_report_policy.sql b/src/verify/table_report_policy.sql deleted file mode 100644 index 47842512..00000000 --- a/src/verify/table_report_policy.sql +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.report', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.report', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.report', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/test/fixture/schema.definition.sql b/test/fixture/schema.definition.sql index 27b32be6..ee2259e7 100644 --- a/test/fixture/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -6144,24 +6144,10 @@ ALTER TABLE vibetype.account ENABLE ROW LEVEL SECURITY; ALTER TABLE vibetype.account_block ENABLE ROW LEVEL SECURITY; -- --- Name: account_block account_block_delete; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: account_block account_block_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY account_block_delete ON vibetype.account_block FOR DELETE USING ((created_by = vibetype.invoker_account_id())); - - --- --- Name: account_block account_block_insert; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_block_insert ON vibetype.account_block FOR INSERT WITH CHECK ((created_by = vibetype.invoker_account_id())); - - --- --- Name: account_block account_block_select; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_block_select ON vibetype.account_block FOR SELECT USING ((created_by = vibetype.invoker_account_id())); +CREATE POLICY account_block_all ON vibetype.account_block USING ((created_by = vibetype.invoker_account_id())); -- @@ -6171,24 +6157,10 @@ CREATE POLICY account_block_select ON vibetype.account_block FOR SELECT USING (( ALTER TABLE vibetype.account_preference_event_category ENABLE ROW LEVEL SECURITY; -- --- Name: account_preference_event_category account_preference_event_category_delete; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: account_preference_event_category account_preference_event_category_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY account_preference_event_category_delete ON vibetype.account_preference_event_category FOR DELETE USING ((account_id = vibetype.invoker_account_id())); - - --- --- Name: account_preference_event_category account_preference_event_category_insert; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_preference_event_category_insert ON vibetype.account_preference_event_category FOR INSERT WITH CHECK ((account_id = vibetype.invoker_account_id())); - - --- --- Name: account_preference_event_category account_preference_event_category_select; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_preference_event_category_select ON vibetype.account_preference_event_category FOR SELECT USING ((account_id = vibetype.invoker_account_id())); +CREATE POLICY account_preference_event_category_all ON vibetype.account_preference_event_category USING ((account_id = vibetype.invoker_account_id())); -- @@ -6198,24 +6170,10 @@ CREATE POLICY account_preference_event_category_select ON vibetype.account_prefe ALTER TABLE vibetype.account_preference_event_format ENABLE ROW LEVEL SECURITY; -- --- Name: account_preference_event_format account_preference_event_format_delete; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_preference_event_format_delete ON vibetype.account_preference_event_format FOR DELETE USING ((account_id = vibetype.invoker_account_id())); - - --- --- Name: account_preference_event_format account_preference_event_format_insert; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_preference_event_format_insert ON vibetype.account_preference_event_format FOR INSERT WITH CHECK ((account_id = vibetype.invoker_account_id())); - - --- --- Name: account_preference_event_format account_preference_event_format_select; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: account_preference_event_format account_preference_event_format_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY account_preference_event_format_select ON vibetype.account_preference_event_format FOR SELECT USING ((account_id = vibetype.invoker_account_id())); +CREATE POLICY account_preference_event_format_all ON vibetype.account_preference_event_format USING ((account_id = vibetype.invoker_account_id())); -- @@ -6225,24 +6183,10 @@ CREATE POLICY account_preference_event_format_select ON vibetype.account_prefere ALTER TABLE vibetype.account_preference_event_size ENABLE ROW LEVEL SECURITY; -- --- Name: account_preference_event_size account_preference_event_size_delete; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_preference_event_size_delete ON vibetype.account_preference_event_size FOR DELETE USING ((account_id = vibetype.invoker_account_id())); - - --- --- Name: account_preference_event_size account_preference_event_size_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: account_preference_event_size account_preference_event_size_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY account_preference_event_size_insert ON vibetype.account_preference_event_size FOR INSERT WITH CHECK ((account_id = vibetype.invoker_account_id())); - - --- --- Name: account_preference_event_size account_preference_event_size_select; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_preference_event_size_select ON vibetype.account_preference_event_size FOR SELECT USING ((account_id = vibetype.invoker_account_id())); +CREATE POLICY account_preference_event_size_all ON vibetype.account_preference_event_size USING ((account_id = vibetype.invoker_account_id())); -- @@ -6259,24 +6203,17 @@ CREATE POLICY account_select ON vibetype.account FOR SELECT USING (true); ALTER TABLE vibetype.account_social_network ENABLE ROW LEVEL SECURITY; -- --- Name: account_social_network account_social_network_delete; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: account_social_network account_social_network_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY account_social_network_delete ON vibetype.account_social_network FOR DELETE USING ((account_id = vibetype.invoker_account_id())); +CREATE POLICY account_social_network_all ON vibetype.account_social_network USING ((account_id = vibetype.invoker_account_id())); -- --- Name: account_social_network account_social_network_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: account_social_network account_social_network_select; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY account_social_network_insert ON vibetype.account_social_network FOR INSERT WITH CHECK ((account_id = vibetype.invoker_account_id())); - - --- --- Name: account_social_network account_social_network_update; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY account_social_network_update ON vibetype.account_social_network FOR UPDATE USING ((account_id = vibetype.invoker_account_id())); +CREATE POLICY account_social_network_select ON vibetype.account_social_network FOR SELECT USING (true); -- @@ -6299,10 +6236,10 @@ CREATE POLICY achievement_select ON vibetype.achievement FOR SELECT USING (true) ALTER TABLE vibetype.address ENABLE ROW LEVEL SECURITY; -- --- Name: address address; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: address address_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY address ON vibetype.address USING (((created_by = vibetype.invoker_account_id()) AND (NOT (created_by IN ( SELECT account_block_ids.id +CREATE POLICY address_all ON vibetype.address USING (((created_by = vibetype.invoker_account_id()) AND (NOT (created_by IN ( SELECT account_block_ids.id FROM vibetype_private.account_block_ids() account_block_ids(id)))))) WITH CHECK ((created_by = vibetype.invoker_account_id())); @@ -6353,10 +6290,10 @@ CREATE POLICY contact_update ON vibetype.contact FOR UPDATE USING (((created_by ALTER TABLE vibetype.device ENABLE ROW LEVEL SECURITY; -- --- Name: device device; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: device device_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY device ON vibetype.device USING ((created_by = vibetype.invoker_account_id())) WITH CHECK (true); +CREATE POLICY device_all ON vibetype.device USING ((created_by = vibetype.invoker_account_id())); -- @@ -6365,6 +6302,13 @@ CREATE POLICY device ON vibetype.device USING ((created_by = vibetype.invoker_ac ALTER TABLE vibetype.event ENABLE ROW LEVEL SECURITY; +-- +-- Name: event event_all; Type: POLICY; Schema: vibetype; Owner: ci +-- + +CREATE POLICY event_all ON vibetype.event USING ((created_by = vibetype.invoker_account_id())); + + -- -- Name: event_category_mapping; Type: ROW SECURITY; Schema: vibetype; Owner: ci -- @@ -6375,18 +6319,18 @@ ALTER TABLE vibetype.event_category_mapping ENABLE ROW LEVEL SECURITY; -- Name: event_category_mapping event_category_mapping_delete; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_category_mapping_delete ON vibetype.event_category_mapping FOR DELETE USING (((vibetype.invoker_account_id() IS NOT NULL) AND (( SELECT event.created_by +CREATE POLICY event_category_mapping_delete ON vibetype.event_category_mapping FOR DELETE USING ((( SELECT event.created_by FROM vibetype.event - WHERE (event.id = event_category_mapping.event_id)) = vibetype.invoker_account_id()))); + WHERE (event.id = event_category_mapping.event_id)) = vibetype.invoker_account_id())); -- -- Name: event_category_mapping event_category_mapping_insert; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_category_mapping_insert ON vibetype.event_category_mapping FOR INSERT WITH CHECK (((vibetype.invoker_account_id() IS NOT NULL) AND (( SELECT event.created_by +CREATE POLICY event_category_mapping_insert ON vibetype.event_category_mapping FOR INSERT WITH CHECK ((( SELECT event.created_by FROM vibetype.event - WHERE (event.id = event_category_mapping.event_id)) = vibetype.invoker_account_id()))); + WHERE (event.id = event_category_mapping.event_id)) = vibetype.invoker_account_id())); -- @@ -6397,13 +6341,6 @@ CREATE POLICY event_category_mapping_select ON vibetype.event_category_mapping F FROM vibetype.event))); --- --- Name: event event_delete; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY event_delete ON vibetype.event FOR DELETE USING ((created_by = vibetype.invoker_account_id())); - - -- -- Name: event_favorite; Type: ROW SECURITY; Schema: vibetype; Owner: ci -- @@ -6411,24 +6348,10 @@ CREATE POLICY event_delete ON vibetype.event FOR DELETE USING ((created_by = vib ALTER TABLE vibetype.event_favorite ENABLE ROW LEVEL SECURITY; -- --- Name: event_favorite event_favorite_delete; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY event_favorite_delete ON vibetype.event_favorite FOR DELETE USING ((created_by = vibetype.invoker_account_id())); - - --- --- Name: event_favorite event_favorite_insert; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY event_favorite_insert ON vibetype.event_favorite FOR INSERT WITH CHECK ((created_by = vibetype.invoker_account_id())); - - --- --- Name: event_favorite event_favorite_select; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: event_favorite event_favorite_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_favorite_select ON vibetype.event_favorite FOR SELECT USING ((created_by = vibetype.invoker_account_id())); +CREATE POLICY event_favorite_all ON vibetype.event_favorite USING ((created_by = vibetype.invoker_account_id())); -- @@ -6475,13 +6398,6 @@ ALTER TABLE vibetype.event_group ENABLE ROW LEVEL SECURITY; ALTER TABLE vibetype.event_grouping ENABLE ROW LEVEL SECURITY; --- --- Name: event event_insert; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY event_insert ON vibetype.event FOR INSERT WITH CHECK (((vibetype.invoker_account_id() IS NOT NULL) AND (created_by = vibetype.invoker_account_id()))); - - -- -- Name: event_recommendation; Type: ROW SECURITY; Schema: vibetype; Owner: ci -- @@ -6492,7 +6408,7 @@ ALTER TABLE vibetype.event_recommendation ENABLE ROW LEVEL SECURITY; -- Name: event_recommendation event_recommendation_select; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_recommendation_select ON vibetype.event_recommendation FOR SELECT USING (((vibetype.invoker_account_id() IS NOT NULL) AND (account_id = vibetype.invoker_account_id()))); +CREATE POLICY event_recommendation_select ON vibetype.event_recommendation FOR SELECT USING ((account_id = vibetype.invoker_account_id())); -- @@ -6500,14 +6416,7 @@ CREATE POLICY event_recommendation_select ON vibetype.event_recommendation FOR S -- CREATE POLICY event_select ON vibetype.event FOR SELECT USING ((((visibility = 'public'::vibetype.event_visibility) AND ((guest_count_maximum IS NULL) OR (guest_count_maximum > vibetype.guest_count(id))) AND (NOT (created_by IN ( SELECT account_block_ids.id - FROM vibetype_private.account_block_ids() account_block_ids(id))))) OR (created_by = vibetype.invoker_account_id()) OR (id IN ( SELECT vibetype_private.events_invited() AS events_invited)))); - - --- --- Name: event event_update; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY event_update ON vibetype.event FOR UPDATE USING (((vibetype.invoker_account_id() IS NOT NULL) AND (created_by = vibetype.invoker_account_id()))); + FROM vibetype_private.account_block_ids() account_block_ids(id))))) OR (id IN ( SELECT vibetype_private.events_invited() AS events_invited)))); -- @@ -6645,17 +6554,10 @@ ALTER TABLE vibetype.legal_term ENABLE ROW LEVEL SECURITY; ALTER TABLE vibetype.legal_term_acceptance ENABLE ROW LEVEL SECURITY; -- --- Name: legal_term_acceptance legal_term_acceptance_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: legal_term_acceptance legal_term_acceptance_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY legal_term_acceptance_insert ON vibetype.legal_term_acceptance FOR INSERT WITH CHECK (((vibetype.invoker_account_id() IS NOT NULL) AND (account_id = vibetype.invoker_account_id()))); - - --- --- Name: legal_term_acceptance legal_term_acceptance_select; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY legal_term_acceptance_select ON vibetype.legal_term_acceptance FOR SELECT USING (((vibetype.invoker_account_id() IS NOT NULL) AND (account_id = vibetype.invoker_account_id()))); +CREATE POLICY legal_term_acceptance_all ON vibetype.legal_term_acceptance USING ((account_id = vibetype.invoker_account_id())); -- @@ -6672,17 +6574,17 @@ CREATE POLICY legal_term_select ON vibetype.legal_term FOR SELECT USING (true); ALTER TABLE vibetype.profile_picture ENABLE ROW LEVEL SECURITY; -- --- Name: profile_picture profile_picture_delete; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: profile_picture profile_picture_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY profile_picture_delete ON vibetype.profile_picture FOR DELETE USING (((( SELECT CURRENT_USER AS "current_user") = 'vibetype'::name) OR ((vibetype.invoker_account_id() IS NOT NULL) AND (account_id = vibetype.invoker_account_id())))); +CREATE POLICY profile_picture_all ON vibetype.profile_picture USING ((account_id = vibetype.invoker_account_id())); -- --- Name: profile_picture profile_picture_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: profile_picture profile_picture_delete_service; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY profile_picture_insert ON vibetype.profile_picture FOR INSERT WITH CHECK (((vibetype.invoker_account_id() IS NOT NULL) AND (account_id = vibetype.invoker_account_id()))); +CREATE POLICY profile_picture_delete_service ON vibetype.profile_picture FOR DELETE TO vibetype USING (true); -- @@ -6692,13 +6594,6 @@ CREATE POLICY profile_picture_insert ON vibetype.profile_picture FOR INSERT WITH CREATE POLICY profile_picture_select ON vibetype.profile_picture FOR SELECT USING (true); --- --- Name: profile_picture profile_picture_update; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY profile_picture_update ON vibetype.profile_picture FOR UPDATE USING (((vibetype.invoker_account_id() IS NOT NULL) AND (account_id = vibetype.invoker_account_id()))); - - -- -- Name: report; Type: ROW SECURITY; Schema: vibetype; Owner: ci -- @@ -6706,17 +6601,10 @@ CREATE POLICY profile_picture_update ON vibetype.profile_picture FOR UPDATE USIN ALTER TABLE vibetype.report ENABLE ROW LEVEL SECURITY; -- --- Name: report report_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: report report_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY report_insert ON vibetype.report FOR INSERT WITH CHECK (((vibetype.invoker_account_id() IS NOT NULL) AND (created_by = vibetype.invoker_account_id()))); - - --- --- Name: report report_select; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY report_select ON vibetype.report FOR SELECT USING (((vibetype.invoker_account_id() IS NOT NULL) AND (created_by = vibetype.invoker_account_id()))); +CREATE POLICY report_all ON vibetype.report USING ((created_by = vibetype.invoker_account_id())); -- @@ -6726,27 +6614,20 @@ CREATE POLICY report_select ON vibetype.report FOR SELECT USING (((vibetype.invo ALTER TABLE vibetype.upload ENABLE ROW LEVEL SECURITY; -- --- Name: upload upload_delete_using; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload upload_all_service; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY upload_delete_using ON vibetype.upload FOR DELETE USING ((( SELECT CURRENT_USER AS "current_user") = 'vibetype'::name)); +CREATE POLICY upload_all_service ON vibetype.upload TO vibetype USING (true); -- --- Name: upload upload_select_using; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload upload_select; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY upload_select_using ON vibetype.upload FOR SELECT USING (((( SELECT CURRENT_USER AS "current_user") = 'vibetype'::name) OR ((vibetype.invoker_account_id() IS NOT NULL) AND (account_id = vibetype.invoker_account_id())) OR (id IN ( SELECT profile_picture.upload_id +CREATE POLICY upload_select ON vibetype.upload FOR SELECT USING (((account_id = vibetype.invoker_account_id()) OR (id IN ( SELECT profile_picture.upload_id FROM vibetype.profile_picture)))); --- --- Name: upload upload_update_using; Type: POLICY; Schema: vibetype; Owner: ci --- - -CREATE POLICY upload_update_using ON vibetype.upload FOR UPDATE USING ((( SELECT CURRENT_USER AS "current_user") = 'vibetype'::name)); - - -- -- Name: achievement_code; Type: ROW SECURITY; Schema: vibetype_private; Owner: ci -- @@ -7126,8 +7007,8 @@ GRANT ALL ON FUNCTION vibetype.create_guests(event_id uuid, contact_ids uuid[]) -- Name: TABLE event; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event TO vibetype_account; GRANT SELECT ON TABLE vibetype.event TO vibetype_anonymous; +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event TO vibetype_account; -- @@ -7487,8 +7368,8 @@ GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.address TO vibetype_account; -- Name: TABLE contact; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.contact TO vibetype_account; GRANT SELECT ON TABLE vibetype.contact TO vibetype_anonymous; +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.contact TO vibetype_account; -- @@ -7541,31 +7422,31 @@ GRANT SELECT,INSERT,DELETE ON TABLE vibetype.event_format_mapping TO vibetype_ac -- Name: TABLE event_group; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event_group TO vibetype_account; GRANT SELECT ON TABLE vibetype.event_group TO vibetype_anonymous; +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event_group TO vibetype_account; -- -- Name: TABLE event_grouping; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event_grouping TO vibetype_account; GRANT SELECT ON TABLE vibetype.event_grouping TO vibetype_anonymous; +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event_grouping TO vibetype_account; -- -- Name: TABLE event_recommendation; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT,INSERT,DELETE ON TABLE vibetype.event_recommendation TO vibetype_account; +GRANT SELECT ON TABLE vibetype.event_recommendation TO vibetype_account; -- -- Name: TABLE event_upload; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT,INSERT,DELETE ON TABLE vibetype.event_upload TO vibetype_account; GRANT SELECT ON TABLE vibetype.event_upload TO vibetype_anonymous; +GRANT SELECT,INSERT,DELETE ON TABLE vibetype.event_upload TO vibetype_account; -- @@ -7602,8 +7483,8 @@ GRANT SELECT,INSERT ON TABLE vibetype.legal_term_acceptance TO vibetype_account; -- Name: TABLE profile_picture; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.profile_picture TO vibetype_account; GRANT SELECT ON TABLE vibetype.profile_picture TO vibetype_anonymous; +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.profile_picture TO vibetype_account; GRANT SELECT,DELETE ON TABLE vibetype.profile_picture TO vibetype; From 632973588a26cb88699be42e4749bb58b0923019 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 2 May 2025 09:19:53 +0000 Subject: [PATCH 08/23] chore(release): 8.0.0-beta.4 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [8.0.0-beta.4](https://github.com/maevsi/sqitch/compare/8.0.0-beta.3...8.0.0-beta.4) (2025-05-02) ### ⚠ BREAKING CHANGES * **policy:** simplify policies (#190) ### Miscellaneous Chores * **policy:** simplify policies ([#190](https://github.com/maevsi/sqitch/issues/190)) ([7e525e1](https://github.com/maevsi/sqitch/commit/7e525e1e82cdeda035064bc8367030d0a57027e4)) --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e669ea4b..3a9e6f89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [8.0.0-beta.4](https://github.com/maevsi/sqitch/compare/8.0.0-beta.3...8.0.0-beta.4) (2025-05-02) + +### ⚠ BREAKING CHANGES + +* **policy:** simplify policies (#190) + +### Miscellaneous Chores + +* **policy:** simplify policies ([#190](https://github.com/maevsi/sqitch/issues/190)) ([7e525e1](https://github.com/maevsi/sqitch/commit/7e525e1e82cdeda035064bc8367030d0a57027e4)) + ## [8.0.0-beta.3](https://github.com/maevsi/sqitch/compare/8.0.0-beta.2...8.0.0-beta.3) (2025-05-02) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index 6b5f3807..0e761641 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@maevsi/sqitch", - "version": "8.0.0-beta.3", + "version": "8.0.0-beta.4", "private": true, "engines": { "node": "22" From c97797938503a3845b0b07784b1e283236b25078 Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Fri, 2 May 2025 12:27:25 +0200 Subject: [PATCH 09/23] fix(event-favorite): correct smart tags --- src/deploy/table_event_favorite.sql | 8 ++++---- test/fixture/schema.definition.sql | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/deploy/table_event_favorite.sql b/src/deploy/table_event_favorite.sql index 0f71a394..bb1dc29b 100644 --- a/src/deploy/table_event_favorite.sql +++ b/src/deploy/table_event_favorite.sql @@ -11,11 +11,11 @@ CREATE TABLE vibetype.event_favorite ( UNIQUE (created_by, event_id) ); -COMMENT ON TABLE vibetype.event_favorite IS 'Stores user-specific event favorites, linking an event to the account that marked it as a favorite.'; -COMMENT ON COLUMN vibetype.event_favorite.id IS E'@omit create,update\nPrimary key, uniquely identifies each favorite entry.'; +COMMENT ON TABLE vibetype.event_favorite IS E'@omit update\nStores user-specific event favorites, linking an event to the account that marked it as a favorite.'; +COMMENT ON COLUMN vibetype.event_favorite.id IS E'@omit create\nPrimary key, uniquely identifies each favorite entry.'; COMMENT ON COLUMN vibetype.event_favorite.event_id IS 'Reference to the event that is marked as a favorite.'; -COMMENT ON COLUMN vibetype.event_favorite.created_at IS E'@omit create,update\nTimestamp when the favorite was created. Defaults to the current timestamp.'; -COMMENT ON COLUMN vibetype.event_favorite.created_by IS E'@omit create,update\nReference to the account that created the event favorite.'; +COMMENT ON COLUMN vibetype.event_favorite.created_at IS E'@omit create\nTimestamp when the favorite was created. Defaults to the current timestamp.'; +COMMENT ON COLUMN vibetype.event_favorite.created_by IS 'Reference to the account that created the event favorite.'; COMMENT ON CONSTRAINT event_favorite_created_by_event_id_key ON vibetype.event_favorite IS 'Ensures that each user can mark an event as a favorite only once.'; GRANT SELECT, INSERT, DELETE ON TABLE vibetype.event_favorite TO vibetype_account; diff --git a/test/fixture/schema.definition.sql b/test/fixture/schema.definition.sql index ee2259e7..fe2da94e 100644 --- a/test/fixture/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -3816,14 +3816,15 @@ ALTER TABLE vibetype.event_favorite OWNER TO ci; -- Name: TABLE event_favorite; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON TABLE vibetype.event_favorite IS 'Stores user-specific event favorites, linking an event to the account that marked it as a favorite.'; +COMMENT ON TABLE vibetype.event_favorite IS '@omit update +Stores user-specific event favorites, linking an event to the account that marked it as a favorite.'; -- -- Name: COLUMN event_favorite.id; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_favorite.id IS '@omit create,update +COMMENT ON COLUMN vibetype.event_favorite.id IS '@omit create Primary key, uniquely identifies each favorite entry.'; @@ -3838,7 +3839,7 @@ COMMENT ON COLUMN vibetype.event_favorite.event_id IS 'Reference to the event th -- Name: COLUMN event_favorite.created_at; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_favorite.created_at IS '@omit create,update +COMMENT ON COLUMN vibetype.event_favorite.created_at IS '@omit create Timestamp when the favorite was created. Defaults to the current timestamp.'; @@ -3846,8 +3847,7 @@ Timestamp when the favorite was created. Defaults to the current timestamp.'; -- Name: COLUMN event_favorite.created_by; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.event_favorite.created_by IS '@omit create,update -Reference to the account that created the event favorite.'; +COMMENT ON COLUMN vibetype.event_favorite.created_by IS 'Reference to the account that created the event favorite.'; -- From 31de779a25df8de81ebc40a69f9e8a109d60b527 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 2 May 2025 10:39:06 +0000 Subject: [PATCH 10/23] chore(release): 8.0.0-beta.5 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [8.0.0-beta.5](https://github.com/maevsi/sqitch/compare/8.0.0-beta.4...8.0.0-beta.5) (2025-05-02) ### ⚠ BREAKING CHANGES * **event-favorite:** correct smart tags (#194) ### Bug Fixes * **event-favorite:** correct smart tags ([c977979](https://github.com/maevsi/sqitch/commit/c97797938503a3845b0b07784b1e283236b25078)) * **event-favorite:** correct smart tags ([#194](https://github.com/maevsi/sqitch/issues/194)) ([fa81e9e](https://github.com/maevsi/sqitch/commit/fa81e9ecaea39d7bf9b809835fd1303c0412325b)) --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a9e6f89..c616f7cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [8.0.0-beta.5](https://github.com/maevsi/sqitch/compare/8.0.0-beta.4...8.0.0-beta.5) (2025-05-02) + +### ⚠ BREAKING CHANGES + +* **event-favorite:** correct smart tags (#194) + +### Bug Fixes + +* **event-favorite:** correct smart tags ([c977979](https://github.com/maevsi/sqitch/commit/c97797938503a3845b0b07784b1e283236b25078)) +* **event-favorite:** correct smart tags ([#194](https://github.com/maevsi/sqitch/issues/194)) ([fa81e9e](https://github.com/maevsi/sqitch/commit/fa81e9ecaea39d7bf9b809835fd1303c0412325b)) + ## [8.0.0-beta.4](https://github.com/maevsi/sqitch/compare/8.0.0-beta.3...8.0.0-beta.4) (2025-05-02) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index 0e761641..041ed46f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@maevsi/sqitch", - "version": "8.0.0-beta.4", + "version": "8.0.0-beta.5", "private": true, "engines": { "node": "22" From 22cf406c924bf048fc539faea747d2936312f28b Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Fri, 9 May 2025 16:47:53 +0200 Subject: [PATCH 11/23] feat(event)!: remove groups --- src/deploy/table_event_group.sql | 37 ----- src/deploy/table_event_grouping.sql | 27 ---- src/revert/table_event_group.sql | 5 - src/revert/table_event_grouping.sql | 5 - src/sqitch.plan | 2 - src/verify/table_event_group.sql | 31 ---- src/verify/table_event_grouping.sql | 28 ---- test/fixture/schema.definition.sql | 205 ------------------------- test/logic/scenario/database/index.sql | 8 - 9 files changed, 348 deletions(-) delete mode 100644 src/deploy/table_event_group.sql delete mode 100644 src/deploy/table_event_grouping.sql delete mode 100644 src/revert/table_event_group.sql delete mode 100644 src/revert/table_event_grouping.sql delete mode 100644 src/verify/table_event_group.sql delete mode 100644 src/verify/table_event_grouping.sql diff --git a/src/deploy/table_event_group.sql b/src/deploy/table_event_group.sql deleted file mode 100644 index 9dfb52d1..00000000 --- a/src/deploy/table_event_group.sql +++ /dev/null @@ -1,37 +0,0 @@ -BEGIN; - -CREATE TABLE vibetype.event_group ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - - description TEXT CHECK (char_length("description") < 1000000), - is_archived BOOLEAN NOT NULL DEFAULT FALSE, - name TEXT NOT NULL CHECK (char_length("name") > 0 AND char_length("name") < 100), - slug TEXT NOT NULL CHECK (char_length(slug) < 100 AND slug ~ '^[-A-Za-z0-9]+$'), - - created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, - created_by UUID NOT NULL REFERENCES vibetype.account(id) ON DELETE CASCADE, - - UNIQUE (created_by, slug) -); - -COMMENT ON TABLE vibetype.event_group IS 'A group of events.'; -COMMENT ON COLUMN vibetype.event_group.id IS E'@omit create,update\nThe event group''s internal id.'; -COMMENT ON COLUMN vibetype.event_group.description IS 'The event group''s description.'; -COMMENT ON COLUMN vibetype.event_group.is_archived IS 'Indicates whether the event group is archived.'; -COMMENT ON COLUMN vibetype.event_group.name IS 'The event group''s name.'; -COMMENT ON COLUMN vibetype.event_group.slug IS E'@omit create,update\nThe event group''s name, slugified.'; -COMMENT ON COLUMN vibetype.event_group.created_at IS E'@omit create,update\nTimestamp of when the event group was created, defaults to the current timestamp.'; -COMMENT ON COLUMN vibetype.event_group.created_by IS 'The event group creator''s id.'; - -GRANT SELECT ON TABLE vibetype.event_group TO vibetype_anonymous; -GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.event_group TO vibetype_account; - -ALTER TABLE vibetype.event_group ENABLE ROW LEVEL SECURITY; - --- TODO: --- CREATE POLICY event_group_select ON vibetype.event_group FOR SELECT --- USING ( --- id IN (SELECT event_group_id FROM vibetype.event_grouping) --- ); - -COMMIT; diff --git a/src/deploy/table_event_grouping.sql b/src/deploy/table_event_grouping.sql deleted file mode 100644 index 585284d0..00000000 --- a/src/deploy/table_event_grouping.sql +++ /dev/null @@ -1,27 +0,0 @@ -BEGIN; - -CREATE TABLE vibetype.event_grouping ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - - event_group_id UUID NOT NULL REFERENCES vibetype.event_group(id) ON DELETE CASCADE, - event_id UUID NOT NULL REFERENCES vibetype.event(id) ON DELETE CASCADE, - - UNIQUE (event_id, event_group_id) -); - -COMMENT ON TABLE vibetype.event_grouping IS 'A bidirectional mapping between an event and an event group.'; -COMMENT ON COLUMN vibetype.event_grouping.id IS E'@omit create,update\nThe event grouping''s internal id.'; -COMMENT ON COLUMN vibetype.event_grouping.event_group_id IS 'The event grouping''s internal event group id.'; -COMMENT ON COLUMN vibetype.event_grouping.event_id IS 'The event grouping''s internal event id.'; - -GRANT SELECT ON TABLE vibetype.event_grouping TO vibetype_anonymous; -GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.event_grouping TO vibetype_account; - -ALTER TABLE vibetype.event_grouping ENABLE ROW LEVEL SECURITY; - --- TODO: --- CREATE POLICY event_grouping_select ON vibetype.event_grouping FOR SELECT USING ( --- event_id IN (SELECT id FROM vibetype.event) --- ); - -COMMIT; diff --git a/src/revert/table_event_group.sql b/src/revert/table_event_group.sql deleted file mode 100644 index c3c1ab37..00000000 --- a/src/revert/table_event_group.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP TABLE vibetype.event_group; - -COMMIT; diff --git a/src/revert/table_event_grouping.sql b/src/revert/table_event_grouping.sql deleted file mode 100644 index 08b558e2..00000000 --- a/src/revert/table_event_grouping.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP TABLE vibetype.event_grouping; - -COMMIT; diff --git a/src/sqitch.plan b/src/sqitch.plan index 48ba8cc4..a6eddd70 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -19,7 +19,6 @@ table_account_private [schema_private] 1970-01-01T00:00:00Z Jonas Thelemann # Add public table account. table_account_block [schema_public table_account_public] 1970-01-01T00:00:00Z Sven Thelemann # Blocking of an account by another account. function_account_block_ids [schema_public table_account_block role_account role_anonymous function_invoker_account_id] 1970-01-01T00:00:00Z Sven Thelemann # Function returning all account id's involved in blocking. -table_event_group [schema_public role_account role_anonymous table_account_public enum_event_visibility] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event_group. enum_language [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Supported ISO 639 language codes. function_language_iso_full_text_search [privilege_execute_revoke schema_public enum_language] 1970-01-01T00:00:00Z Jonas Thelemann # ISO language code to full text search language conversion. table_address [schema_public table_account_public function_trigger_metadata_update] 1970-01-01T00:00:00Z Jonas Thelemann # Stores detailed address information, including lines, city, state, country, and metadata. @@ -36,7 +35,6 @@ function_guest_count [privilege_execute_revoke schema_public table_guest role_ac table_event_policy [schema_public table_event role_account role_anonymous function_guest_count function_account_block_ids function_invoker_account_id schema_private function_events_invited] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table event. function_event_guest_count_maximum [privilege_execute_revoke schema_public table_event function_guest_count function_invoker_account_id schema_private function_events_invited role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns the maximum guest count of an accessible event. table_guest_policy [schema_public table_guest role_account role_anonymous function_guest_claim_array function_invoker_account_id function_events_organized function_account_block_ids function_event_guest_count_maximum] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table contact. -table_event_grouping [schema_public role_account role_anonymous table_event table_event_group] 1970-01-01T00:00:00Z Jonas Thelemann # Add table event grouping. type_jwt [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Add type jwt. table_legal_term [schema_public role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Legal terms like privacy policies or terms of service. table_legal_term_acceptance [schema_public table_account_public table_legal_term role_account function_invoker_account_id] 1970-01-01T00:00:00Z Jonas Thelemann # Tracks each user account's acceptance of legal terms and conditions. diff --git a/src/verify/table_event_group.sql b/src/verify/table_event_group.sql deleted file mode 100644 index 9d292a34..00000000 --- a/src/verify/table_event_group.sql +++ /dev/null @@ -1,31 +0,0 @@ -BEGIN; - -SELECT id, - description, - is_archived, - name, - slug, - created_at, - created_by -FROM vibetype.event_group WHERE FALSE; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_group', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_group', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_group', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_group', 'DELETE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_group', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_group', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_group', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_group', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_group', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_group', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_group', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_group', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/src/verify/table_event_grouping.sql b/src/verify/table_event_grouping.sql deleted file mode 100644 index 56b8fd00..00000000 --- a/src/verify/table_event_grouping.sql +++ /dev/null @@ -1,28 +0,0 @@ -BEGIN; - -SELECT id, - event_group_id, - event_id -FROM vibetype.event_grouping WHERE FALSE; - - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_grouping', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_grouping', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_grouping', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.event_grouping', 'DELETE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_grouping', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_grouping', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_grouping', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.event_grouping', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_grouping', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_grouping', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_grouping', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.event_grouping', 'DELETE')); -END $$; - -ROLLBACK; diff --git a/test/fixture/schema.definition.sql b/test/fixture/schema.definition.sql index fe2da94e..ffb1472e 100644 --- a/test/fixture/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -3916,127 +3916,6 @@ COMMENT ON COLUMN vibetype.event_format_mapping.event_id IS 'An event id.'; COMMENT ON COLUMN vibetype.event_format_mapping.format_id IS 'A format id.'; --- --- Name: event_group; Type: TABLE; Schema: vibetype; Owner: ci --- - -CREATE TABLE vibetype.event_group ( - id uuid DEFAULT gen_random_uuid() NOT NULL, - description text, - is_archived boolean DEFAULT false NOT NULL, - name text NOT NULL, - slug text NOT NULL, - created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - created_by uuid NOT NULL, - CONSTRAINT event_group_description_check CHECK ((char_length(description) < 1000000)), - CONSTRAINT event_group_name_check CHECK (((char_length(name) > 0) AND (char_length(name) < 100))), - CONSTRAINT event_group_slug_check CHECK (((char_length(slug) < 100) AND (slug ~ '^[-A-Za-z0-9]+$'::text))) -); - - -ALTER TABLE vibetype.event_group OWNER TO ci; - --- --- Name: TABLE event_group; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON TABLE vibetype.event_group IS 'A group of events.'; - - --- --- Name: COLUMN event_group.id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_group.id IS '@omit create,update -The event group''s internal id.'; - - --- --- Name: COLUMN event_group.description; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_group.description IS 'The event group''s description.'; - - --- --- Name: COLUMN event_group.is_archived; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_group.is_archived IS 'Indicates whether the event group is archived.'; - - --- --- Name: COLUMN event_group.name; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_group.name IS 'The event group''s name.'; - - --- --- Name: COLUMN event_group.slug; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_group.slug IS '@omit create,update -The event group''s name, slugified.'; - - --- --- Name: COLUMN event_group.created_at; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_group.created_at IS '@omit create,update -Timestamp of when the event group was created, defaults to the current timestamp.'; - - --- --- Name: COLUMN event_group.created_by; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_group.created_by IS 'The event group creator''s id.'; - - --- --- Name: event_grouping; Type: TABLE; Schema: vibetype; Owner: ci --- - -CREATE TABLE vibetype.event_grouping ( - id uuid DEFAULT gen_random_uuid() NOT NULL, - event_group_id uuid NOT NULL, - event_id uuid NOT NULL -); - - -ALTER TABLE vibetype.event_grouping OWNER TO ci; - --- --- Name: TABLE event_grouping; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON TABLE vibetype.event_grouping IS 'A bidirectional mapping between an event and an event group.'; - - --- --- Name: COLUMN event_grouping.id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_grouping.id IS '@omit create,update -The event grouping''s internal id.'; - - --- --- Name: COLUMN event_grouping.event_group_id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_grouping.event_group_id IS 'The event grouping''s internal event group id.'; - - --- --- Name: COLUMN event_grouping.event_id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.event_grouping.event_id IS 'The event grouping''s internal event id.'; - - -- -- Name: event_recommendation; Type: TABLE; Schema: vibetype; Owner: ci -- @@ -5228,38 +5107,6 @@ ALTER TABLE ONLY vibetype.event_format ADD CONSTRAINT event_format_pkey PRIMARY KEY (id); --- --- Name: event_group event_group_created_by_slug_key; Type: CONSTRAINT; Schema: vibetype; Owner: ci --- - -ALTER TABLE ONLY vibetype.event_group - ADD CONSTRAINT event_group_created_by_slug_key UNIQUE (created_by, slug); - - --- --- Name: event_group event_group_pkey; Type: CONSTRAINT; Schema: vibetype; Owner: ci --- - -ALTER TABLE ONLY vibetype.event_group - ADD CONSTRAINT event_group_pkey PRIMARY KEY (id); - - --- --- Name: event_grouping event_grouping_event_id_event_group_id_key; Type: CONSTRAINT; Schema: vibetype; Owner: ci --- - -ALTER TABLE ONLY vibetype.event_grouping - ADD CONSTRAINT event_grouping_event_id_event_group_id_key UNIQUE (event_id, event_group_id); - - --- --- Name: event_grouping event_grouping_pkey; Type: CONSTRAINT; Schema: vibetype; Owner: ci --- - -ALTER TABLE ONLY vibetype.event_grouping - ADD CONSTRAINT event_grouping_pkey PRIMARY KEY (id); - - -- -- Name: event event_pkey; Type: CONSTRAINT; Schema: vibetype; Owner: ci -- @@ -5947,30 +5794,6 @@ ALTER TABLE ONLY vibetype.event_format_mapping ADD CONSTRAINT event_format_mapping_format_id_fkey FOREIGN KEY (format_id) REFERENCES vibetype.event_format(id) ON DELETE CASCADE; --- --- Name: event_group event_group_created_by_fkey; Type: FK CONSTRAINT; Schema: vibetype; Owner: ci --- - -ALTER TABLE ONLY vibetype.event_group - ADD CONSTRAINT event_group_created_by_fkey FOREIGN KEY (created_by) REFERENCES vibetype.account(id) ON DELETE CASCADE; - - --- --- Name: event_grouping event_grouping_event_group_id_fkey; Type: FK CONSTRAINT; Schema: vibetype; Owner: ci --- - -ALTER TABLE ONLY vibetype.event_grouping - ADD CONSTRAINT event_grouping_event_group_id_fkey FOREIGN KEY (event_group_id) REFERENCES vibetype.event_group(id) ON DELETE CASCADE; - - --- --- Name: event_grouping event_grouping_event_id_fkey; Type: FK CONSTRAINT; Schema: vibetype; Owner: ci --- - -ALTER TABLE ONLY vibetype.event_grouping - ADD CONSTRAINT event_grouping_event_id_fkey FOREIGN KEY (event_id) REFERENCES vibetype.event(id) ON DELETE CASCADE; - - -- -- Name: event_recommendation event_recommendation_account_id_fkey; Type: FK CONSTRAINT; Schema: vibetype; Owner: ci -- @@ -6386,18 +6209,6 @@ CREATE POLICY event_format_mapping_select ON vibetype.event_format_mapping FOR S FROM vibetype.event))); --- --- Name: event_group; Type: ROW SECURITY; Schema: vibetype; Owner: ci --- - -ALTER TABLE vibetype.event_group ENABLE ROW LEVEL SECURITY; - --- --- Name: event_grouping; Type: ROW SECURITY; Schema: vibetype; Owner: ci --- - -ALTER TABLE vibetype.event_grouping ENABLE ROW LEVEL SECURITY; - -- -- Name: event_recommendation; Type: ROW SECURITY; Schema: vibetype; Owner: ci -- @@ -7418,22 +7229,6 @@ GRANT SELECT ON TABLE vibetype.event_format_mapping TO vibetype_anonymous; GRANT SELECT,INSERT,DELETE ON TABLE vibetype.event_format_mapping TO vibetype_account; --- --- Name: TABLE event_group; Type: ACL; Schema: vibetype; Owner: ci --- - -GRANT SELECT ON TABLE vibetype.event_group TO vibetype_anonymous; -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event_group TO vibetype_account; - - --- --- Name: TABLE event_grouping; Type: ACL; Schema: vibetype; Owner: ci --- - -GRANT SELECT ON TABLE vibetype.event_grouping TO vibetype_anonymous; -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.event_grouping TO vibetype_account; - - -- -- Name: TABLE event_recommendation; Type: ACL; Schema: vibetype; Owner: ci -- diff --git a/test/logic/scenario/database/index.sql b/test/logic/scenario/database/index.sql index 5ba06325..f397cb56 100644 --- a/test/logic/scenario/database/index.sql +++ b/test/logic/scenario/database/index.sql @@ -148,10 +148,6 @@ SELECT vibetype_test.index_existence( ARRAY ['idx_device_updated_by', 'device_created_by_fcm_token_key'] ); -SELECT vibetype_test.index_existence( - ARRAY ['event_grouping_event_id_event_group_id_key'] -); - SELECT vibetype_test.index_existence( ARRAY ['event_created_by_slug_key', 'idx_event_search_vector'] ); @@ -160,10 +156,6 @@ SELECT vibetype_test.index_existence( ARRAY ['idx_friendship_created_by', 'idx_friendship_updated_by'] ); -SELECT vibetype_test.index_existence( - ARRAY ['event_group_created_by_slug_key'] -); - SELECT vibetype_test.index_existence( ARRAY ['guest_event_id_contact_id_key', 'idx_guest_updated_by'] ); From 4c6db6386ea006433ef39e888cb87250c56779a6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 9 May 2025 14:57:35 +0000 Subject: [PATCH 12/23] chore(release): 8.0.0-beta.6 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [8.0.0-beta.6](https://github.com/maevsi/sqitch/compare/8.0.0-beta.5...8.0.0-beta.6) (2025-05-09) ### ⚠ BREAKING CHANGES * **event:** remove groups (#195) * **event:** remove groups ### Features * **event:** remove groups ([22cf406](https://github.com/maevsi/sqitch/commit/22cf406c924bf048fc539faea747d2936312f28b)) * **event:** remove groups ([#195](https://github.com/maevsi/sqitch/issues/195)) ([4bae6c6](https://github.com/maevsi/sqitch/commit/4bae6c67b8a427d453cc8825ec6955a55f03fe3a)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c616f7cd..414be469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [8.0.0-beta.6](https://github.com/maevsi/sqitch/compare/8.0.0-beta.5...8.0.0-beta.6) (2025-05-09) + +### ⚠ BREAKING CHANGES + +* **event:** remove groups (#195) +* **event:** remove groups + +### Features + +* **event:** remove groups ([22cf406](https://github.com/maevsi/sqitch/commit/22cf406c924bf048fc539faea747d2936312f28b)) +* **event:** remove groups ([#195](https://github.com/maevsi/sqitch/issues/195)) ([4bae6c6](https://github.com/maevsi/sqitch/commit/4bae6c67b8a427d453cc8825ec6955a55f03fe3a)) + ## [8.0.0-beta.5](https://github.com/maevsi/sqitch/compare/8.0.0-beta.4...8.0.0-beta.5) (2025-05-02) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index 041ed46f..150a708e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@maevsi/sqitch", - "version": "8.0.0-beta.5", + "version": "8.0.0-beta.6", "private": true, "engines": { "node": "22" From c6f44f67777a0318fd8983346cfbd245e9c61530 Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Sat, 10 May 2025 20:07:04 +0200 Subject: [PATCH 13/23] chore(package): sort --- package.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 150a708e..a46fe7cc 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,19 @@ { - "name": "@maevsi/sqitch", - "version": "8.0.0-beta.6", - "private": true, + "devDependencies": { + "@commitlint/cli": "19.8.0", + "@commitlint/config-conventional": "19.8.0", + "conventional-changelog-conventionalcommits": "8.0.0", + "husky": "9.1.7" + }, "engines": { "node": "22" }, + "name": "@maevsi/sqitch", "packageManager": "pnpm@10.7.1", + "private": true, "scripts": { "prepare": "husky" }, - "devDependencies": { - "@commitlint/cli": "19.8.0", - "@commitlint/config-conventional": "19.8.0", - "conventional-changelog-conventionalcommits": "8.0.0", - "husky": "9.1.7" - }, - "type": "module" + "type": "module", + "version": "8.0.0-beta.6" } From 65a081df1c84e3bff1c52b2f25114b4125d631cb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 10 May 2025 18:10:33 +0000 Subject: [PATCH 14/23] chore(release): 8.0.0-beta.7 [skip ci] ## [8.0.0-beta.7](https://github.com/maevsi/sqitch/compare/8.0.0-beta.6...8.0.0-beta.7) (2025-05-10) ### Bug Fixes * schedule release ([8e1b5b8](https://github.com/maevsi/sqitch/commit/8e1b5b8f29e4de79249f693341ee42862825ced8)) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5cd64b2..47495f4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [8.0.0-beta.7](https://github.com/maevsi/sqitch/compare/8.0.0-beta.6...8.0.0-beta.7) (2025-05-10) + +### Bug Fixes + +* schedule release ([8e1b5b8](https://github.com/maevsi/sqitch/commit/8e1b5b8f29e4de79249f693341ee42862825ced8)) + ## [8.0.0-beta.6](https://github.com/maevsi/sqitch/compare/8.0.0-beta.5...8.0.0-beta.6) (2025-05-09) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index aaf174e9..6266cfa8 100644 --- a/package.json +++ b/package.json @@ -22,5 +22,5 @@ "test:update": "pnpm run test --update" }, "type": "module", - "version": "8.0.0-beta.6" + "version": "8.0.0-beta.7" } From 6743551c06995ce2da173c3360c702caa95f0861 Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Mon, 12 May 2025 02:20:36 +0200 Subject: [PATCH 15/23] chore(package): correct scripts --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d1b50792..f93ecec2 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,12 @@ "packageManager": "pnpm@10.10.0", "private": true, "scripts": { - "deploy": "npm run sqitch deploy", + "deploy": "pnpm run sqitch deploy", "prepare": "husky", - "revert": "npm run sqitch revert", + "revert": "pnpm run sqitch revert", "sqitch": "./src/sqitch", - "test": "./test/schema/schema-update.sh", - "test:update": "npm run test --update" + "test": "./test/test.sh", + "test:update": "pnpm run test --update" }, "type": "module", "version": "8.0.0-beta.7" From bfb36037b1e804184dd12b18cbc2acffe4ea9519 Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Sun, 11 May 2025 23:40:13 +0200 Subject: [PATCH 16/23] feat(upload)!: rework permissions --- src/deploy/function_upload_create.sql | 6 +- src/deploy/table_event_upload.sql | 2 +- src/deploy/table_upload.sql | 24 +++--- src/deploy/table_upload_policy.sql | 61 ++++++++++++-- src/revert/table_upload_policy.sql | 6 +- src/verify/table_event_upload.sql | 2 - src/verify/table_upload.sql | 2 +- src/verify/table_upload_policy.sql | 8 +- test/fixture/schema.definition.sql | 116 +++++++++++++++++++++----- 9 files changed, 175 insertions(+), 52 deletions(-) diff --git a/src/deploy/function_upload_create.sql b/src/deploy/function_upload_create.sql index 9905c19a..9bdfacd6 100644 --- a/src/deploy/function_upload_create.sql +++ b/src/deploy/function_upload_create.sql @@ -4,18 +4,18 @@ CREATE FUNCTION vibetype.upload_create( size_byte BIGINT ) RETURNS vibetype.upload AS $$ DECLARE - _upload vibetype.upload; + _upload vibetype.upload; BEGIN IF (COALESCE(( SELECT SUM(upload.size_byte) FROM vibetype.upload - WHERE upload.account_id = current_setting('jwt.claims.account_id')::UUID + WHERE upload.created_by = current_setting('jwt.claims.account_id')::UUID ), 0) + upload_create.size_byte <= ( SELECT upload_quota_bytes FROM vibetype_private.account WHERE account.id = current_setting('jwt.claims.account_id')::UUID )) THEN - INSERT INTO vibetype.upload(account_id, size_byte) + INSERT INTO vibetype.upload(created_by, size_byte) VALUES (current_setting('jwt.claims.account_id')::UUID, upload_create.size_byte) RETURNING upload.id INTO _upload; diff --git a/src/deploy/table_event_upload.sql b/src/deploy/table_event_upload.sql index 569bb743..b9cafeed 100644 --- a/src/deploy/table_event_upload.sql +++ b/src/deploy/table_event_upload.sql @@ -44,7 +44,7 @@ CREATE POLICY event_upload_insert ON vibetype.event_upload FOR INSERT WITH CHECK AND upload_id IN ( SELECT id FROM vibetype.upload - WHERE account_id = vibetype.invoker_account_id() + WHERE created_by = vibetype.invoker_account_id() ) ); diff --git a/src/deploy/table_upload.sql b/src/deploy/table_upload.sql index a42abe82..866768c0 100644 --- a/src/deploy/table_upload.sql +++ b/src/deploy/table_upload.sql @@ -1,24 +1,26 @@ BEGIN; CREATE TABLE vibetype.upload ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - account_id UUID NOT NULL REFERENCES vibetype.account(id) ON DELETE CASCADE, - name TEXT CHECK (char_length("name") > 0 AND char_length("name") < 300), - size_byte BIGINT NOT NULL CHECK (size_byte > 0), - storage_key TEXT UNIQUE, - type TEXT NOT NULL DEFAULT 'image', + name TEXT CHECK (char_length("name") > 0 AND char_length("name") < 300), + size_byte BIGINT NOT NULL CHECK (size_byte > 0), + storage_key TEXT UNIQUE, + type TEXT NOT NULL DEFAULT 'image', - created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_by UUID NOT NULL REFERENCES vibetype.account(id) ON DELETE CASCADE ); COMMENT ON TABLE vibetype.upload IS 'An upload.'; COMMENT ON COLUMN vibetype.upload.id IS E'@omit create,update\nThe upload''s internal id.'; -COMMENT ON COLUMN vibetype.upload.account_id IS 'The uploader''s account id.'; COMMENT ON COLUMN vibetype.upload.name IS 'The name of the uploaded file.'; -COMMENT ON COLUMN vibetype.upload.size_byte IS 'The upload''s size in bytes.'; -COMMENT ON COLUMN vibetype.upload.storage_key IS 'The upload''s storage key.'; -COMMENT ON COLUMN vibetype.upload.type IS 'The type of the uploaded file, default is ''image''.'; +COMMENT ON COLUMN vibetype.upload.size_byte IS E'@omit update\nThe upload''s size in bytes.'; +COMMENT ON COLUMN vibetype.upload.storage_key IS E'@omit create,update\nThe upload''s storage key.'; +COMMENT ON COLUMN vibetype.upload.type IS E'@omit create,update\nThe type of the uploaded file, default is ''image''.'; COMMENT ON COLUMN vibetype.upload.created_at IS E'@omit create,update\nTimestamp of when the upload was created, defaults to the current timestamp.'; +COMMENT ON COLUMN vibetype.upload.created_by IS 'The uploader''s account id.'; + +ALTER TABLE vibetype.upload REPLICA IDENTITY FULL; COMMIT; diff --git a/src/deploy/table_upload_policy.sql b/src/deploy/table_upload_policy.sql index 7b5277f7..c8d6cc23 100644 --- a/src/deploy/table_upload_policy.sql +++ b/src/deploy/table_upload_policy.sql @@ -2,26 +2,73 @@ BEGIN; \set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -GRANT SELECT ON TABLE vibetype.upload TO vibetype_account, vibetype_anonymous; -GRANT SELECT, UPDATE, DELETE ON TABLE vibetype.upload TO :role_service_vibetype_username; +GRANT SELECT ON TABLE vibetype.upload TO vibetype_anonymous; +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.upload TO vibetype_account; +GRANT SELECT, UPDATE ON TABLE vibetype.upload TO :role_service_vibetype_username; ALTER TABLE vibetype.upload ENABLE ROW LEVEL SECURITY; --- Allow the service role to select, update, or delete rows. -CREATE POLICY upload_all_service ON vibetype.upload FOR ALL +-- Allow the service role to select and update rows. +CREATE POLICY upload_service_vibetype_all ON vibetype.upload FOR ALL TO :role_service_vibetype_username USING ( TRUE ); +-- Allow accounts to create uploads for their own, but limit the upload quota per account. +CREATE POLICY upload_insert ON vibetype.upload FOR INSERT +WITH CHECK ( + created_by = vibetype.invoker_account_id() +); + +CREATE FUNCTION vibetype.trigger_upload_insert() +RETURNS trigger AS $$ +DECLARE + _current_usage BIGINT; + _quota BIGINT; +BEGIN + SELECT COALESCE(SUM(size_byte), 0) + INTO _current_usage + FROM vibetype.upload + WHERE created_by = current_setting('jwt.claims.account_id')::UUID; + + SELECT upload_quota_bytes + INTO _quota + FROM vibetype_private.account + WHERE id = current_setting('jwt.claims.account_id')::UUID; + + IF (_current_usage + NEW.size_byte) > _quota THEN + RAISE 'Upload quota limit reached!' USING ERRCODE = 'disk_full'; + END IF; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql SECURITY DEFINER; + +CREATE TRIGGER vibetype_trigger_upload_insert + BEFORE INSERT ON vibetype.upload + FOR EACH ROW EXECUTE FUNCTION vibetype.trigger_upload_insert(); + -- Display --- - the uploads that are linked to the requesting account or +-- - the uploads that were created by the requesting account or -- - the uploads which are used as profile picture. -CREATE POLICY upload_select ON vibetype.upload FOR SELECT USING ( - account_id = vibetype.invoker_account_id() +CREATE POLICY upload_select ON vibetype.upload FOR SELECT +USING ( + created_by = vibetype.invoker_account_id() OR id IN (SELECT upload_id FROM vibetype.profile_picture) ); +-- Allow accounts to update their own uploads. +CREATE POLICY upload_update ON vibetype.upload FOR UPDATE +USING ( + created_by = vibetype.invoker_account_id() +); + +-- Allow accounts to delete their own uploads. +CREATE POLICY upload_delete ON vibetype.upload FOR DELETE +USING ( + created_by = vibetype.invoker_account_id() +); COMMIT; diff --git a/src/revert/table_upload_policy.sql b/src/revert/table_upload_policy.sql index a3a0d604..08ca79c6 100644 --- a/src/revert/table_upload_policy.sql +++ b/src/revert/table_upload_policy.sql @@ -1,6 +1,10 @@ BEGIN; -DROP POLICY upload_all_service ON vibetype.upload; +DROP POLICY upload_delete ON vibetype.upload; DROP POLICY upload_select ON vibetype.upload; +DROP POLICY upload_insert ON vibetype.upload; +DROP TRIGGER vibetype_trigger_upload_insert ON vibetype.upload; +DROP FUNCTION vibetype.trigger_upload_insert(); +DROP POLICY upload_service_vibetype_all ON vibetype.upload; COMMIT; diff --git a/src/verify/table_event_upload.sql b/src/verify/table_event_upload.sql index 9d66da63..fb49c880 100644 --- a/src/verify/table_event_upload.sql +++ b/src/verify/table_event_upload.sql @@ -6,8 +6,6 @@ SELECT id, upload_id FROM vibetype.event_upload WHERE FALSE; -BEGIN; - \set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` SET local role.vibetype_username TO :'role_service_vibetype_username'; diff --git a/src/verify/table_upload.sql b/src/verify/table_upload.sql index ac319274..046a1ad8 100644 --- a/src/verify/table_upload.sql +++ b/src/verify/table_upload.sql @@ -1,11 +1,11 @@ BEGIN; SELECT id, - account_id, name, size_byte, storage_key, type, + created_by, created_at FROM vibetype.upload WHERE FALSE; diff --git a/src/verify/table_upload_policy.sql b/src/verify/table_upload_policy.sql index cb2d745e..02645aab 100644 --- a/src/verify/table_upload_policy.sql +++ b/src/verify/table_upload_policy.sql @@ -6,9 +6,9 @@ SET local role.vibetype_username TO :'role_service_vibetype_username'; DO $$ BEGIN ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.upload', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.upload', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.upload', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.upload', 'DELETE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.upload', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.upload', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.upload', 'DELETE')); ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.upload', 'SELECT')); ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.upload', 'INSERT')); ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.upload', 'UPDATE')); @@ -16,7 +16,7 @@ BEGIN ASSERT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.upload', 'SELECT')); ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.upload', 'INSERT')); ASSERT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.upload', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.upload', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.upload', 'DELETE')); END $$; ROLLBACK; diff --git a/test/fixture/schema.definition.sql b/test/fixture/schema.definition.sql index 90e1b167..9c5fd0f0 100644 --- a/test/fixture/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -1901,22 +1901,56 @@ $$; ALTER FUNCTION vibetype.trigger_metadata_update_fcm() OWNER TO ci; +-- +-- Name: trigger_upload_insert(); Type: FUNCTION; Schema: vibetype; Owner: ci +-- + +CREATE FUNCTION vibetype.trigger_upload_insert() RETURNS trigger + LANGUAGE plpgsql SECURITY DEFINER + AS $$ +DECLARE + _current_usage BIGINT; + _quota BIGINT; +BEGIN + SELECT COALESCE(SUM(size_byte), 0) + INTO _current_usage + FROM vibetype.upload + WHERE created_by = current_setting('jwt.claims.account_id')::UUID; + + SELECT upload_quota_bytes + INTO _quota + FROM vibetype_private.account + WHERE id = current_setting('jwt.claims.account_id')::UUID; + + IF (_current_usage + NEW.size_byte) > _quota THEN + RAISE 'Upload quota limit reached!' USING ERRCODE = 'disk_full'; + END IF; + + RETURN NEW; +END; +$$; + + +ALTER FUNCTION vibetype.trigger_upload_insert() OWNER TO ci; + -- -- Name: upload; Type: TABLE; Schema: vibetype; Owner: ci -- CREATE TABLE vibetype.upload ( id uuid DEFAULT gen_random_uuid() NOT NULL, - account_id uuid NOT NULL, name text, size_byte bigint NOT NULL, storage_key text, type text DEFAULT 'image'::text NOT NULL, created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + created_by uuid NOT NULL, CONSTRAINT upload_name_check CHECK (((char_length(name) > 0) AND (char_length(name) < 300))), CONSTRAINT upload_size_byte_check CHECK ((size_byte > 0)) ); +ALTER TABLE ONLY vibetype.upload REPLICA IDENTITY FULL; + ALTER TABLE vibetype.upload OWNER TO ci; @@ -1935,13 +1969,6 @@ COMMENT ON COLUMN vibetype.upload.id IS '@omit create,update The upload''s internal id.'; --- --- Name: COLUMN upload.account_id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.account_id IS 'The uploader''s account id.'; - - -- -- Name: COLUMN upload.name; Type: COMMENT; Schema: vibetype; Owner: ci -- @@ -1953,21 +1980,24 @@ COMMENT ON COLUMN vibetype.upload.name IS 'The name of the uploaded file.'; -- Name: COLUMN upload.size_byte; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.upload.size_byte IS 'The upload''s size in bytes.'; +COMMENT ON COLUMN vibetype.upload.size_byte IS '@omit update +The upload''s size in bytes.'; -- -- Name: COLUMN upload.storage_key; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.upload.storage_key IS 'The upload''s storage key.'; +COMMENT ON COLUMN vibetype.upload.storage_key IS '@omit create,update +The upload''s storage key.'; -- -- Name: COLUMN upload.type; Type: COMMENT; Schema: vibetype; Owner: ci -- -COMMENT ON COLUMN vibetype.upload.type IS 'The type of the uploaded file, default is ''image''.'; +COMMENT ON COLUMN vibetype.upload.type IS '@omit create,update +The type of the uploaded file, default is ''image''.'; -- @@ -1978,6 +2008,13 @@ COMMENT ON COLUMN vibetype.upload.created_at IS '@omit create,update Timestamp of when the upload was created, defaults to the current timestamp.'; +-- +-- Name: COLUMN upload.created_by; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.created_by IS 'The uploader''s account id.'; + + -- -- Name: upload_create(bigint); Type: FUNCTION; Schema: vibetype; Owner: ci -- @@ -1986,18 +2023,18 @@ CREATE FUNCTION vibetype.upload_create(size_byte bigint) RETURNS vibetype.upload LANGUAGE plpgsql STRICT SECURITY DEFINER AS $$ DECLARE - _upload vibetype.upload; + _upload vibetype.upload; BEGIN IF (COALESCE(( SELECT SUM(upload.size_byte) FROM vibetype.upload - WHERE upload.account_id = current_setting('jwt.claims.account_id')::UUID + WHERE upload.created_by = current_setting('jwt.claims.account_id')::UUID ), 0) + upload_create.size_byte <= ( SELECT upload_quota_bytes FROM vibetype_private.account WHERE account.id = current_setting('jwt.claims.account_id')::UUID )) THEN - INSERT INTO vibetype.upload(account_id, size_byte) + INSERT INTO vibetype.upload(created_by, size_byte) VALUES (current_setting('jwt.claims.account_id')::UUID, upload_create.size_byte) RETURNING upload.id INTO _upload; @@ -5532,6 +5569,13 @@ CREATE TRIGGER vibetype_trigger_event_search_vector BEFORE INSERT OR UPDATE OF n CREATE TRIGGER vibetype_trigger_friendship_update BEFORE UPDATE ON vibetype.friendship FOR EACH ROW EXECUTE FUNCTION vibetype.trigger_metadata_update(); +-- +-- Name: upload vibetype_trigger_upload_insert; Type: TRIGGER; Schema: vibetype; Owner: ci +-- + +CREATE TRIGGER vibetype_trigger_upload_insert BEFORE INSERT ON vibetype.upload FOR EACH ROW EXECUTE FUNCTION vibetype.trigger_upload_insert(); + + -- -- Name: account vibetype_private_account_email_address_verification_valid_until; Type: TRIGGER; Schema: vibetype_private; Owner: ci -- @@ -5947,11 +5991,11 @@ ALTER TABLE ONLY vibetype.report -- --- Name: upload upload_account_id_fkey; Type: FK CONSTRAINT; Schema: vibetype; Owner: ci +-- Name: upload upload_created_by_fkey; Type: FK CONSTRAINT; Schema: vibetype; Owner: ci -- ALTER TABLE ONLY vibetype.upload - ADD CONSTRAINT upload_account_id_fkey FOREIGN KEY (account_id) REFERENCES vibetype.account(id) ON DELETE CASCADE; + ADD CONSTRAINT upload_created_by_fkey FOREIGN KEY (created_by) REFERENCES vibetype.account(id) ON DELETE CASCADE; -- @@ -6253,7 +6297,7 @@ CREATE POLICY event_upload_insert ON vibetype.event_upload FOR INSERT WITH CHECK FROM vibetype.event WHERE (event.created_by = vibetype.invoker_account_id()))) AND (upload_id IN ( SELECT upload.id FROM vibetype.upload - WHERE (upload.account_id = vibetype.invoker_account_id()))))); + WHERE (upload.created_by = vibetype.invoker_account_id()))))); -- @@ -6425,20 +6469,41 @@ CREATE POLICY report_all ON vibetype.report USING ((created_by = vibetype.invoke ALTER TABLE vibetype.upload ENABLE ROW LEVEL SECURITY; -- --- Name: upload upload_all_service; Type: POLICY; Schema: vibetype; Owner: ci +-- Name: upload upload_delete; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY upload_all_service ON vibetype.upload TO vibetype USING (true); +CREATE POLICY upload_delete ON vibetype.upload FOR DELETE USING ((created_by = vibetype.invoker_account_id())); + + +-- +-- Name: upload upload_insert; Type: POLICY; Schema: vibetype; Owner: ci +-- + +CREATE POLICY upload_insert ON vibetype.upload FOR INSERT WITH CHECK ((created_by = vibetype.invoker_account_id())); -- -- Name: upload upload_select; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY upload_select ON vibetype.upload FOR SELECT USING (((account_id = vibetype.invoker_account_id()) OR (id IN ( SELECT profile_picture.upload_id +CREATE POLICY upload_select ON vibetype.upload FOR SELECT USING (((created_by = vibetype.invoker_account_id()) OR (id IN ( SELECT profile_picture.upload_id FROM vibetype.profile_picture)))); +-- +-- Name: upload upload_service_vibetype_all; Type: POLICY; Schema: vibetype; Owner: ci +-- + +CREATE POLICY upload_service_vibetype_all ON vibetype.upload TO vibetype USING (true); + + +-- +-- Name: upload upload_update; Type: POLICY; Schema: vibetype; Owner: ci +-- + +CREATE POLICY upload_update ON vibetype.upload FOR UPDATE USING ((created_by = vibetype.invoker_account_id())); + + -- -- Name: achievement_code; Type: ROW SECURITY; Schema: vibetype_private; Owner: ci -- @@ -6993,13 +7058,20 @@ GRANT ALL ON FUNCTION vibetype.trigger_metadata_update() TO vibetype_account; REVOKE ALL ON FUNCTION vibetype.trigger_metadata_update_fcm() FROM PUBLIC; +-- +-- Name: FUNCTION trigger_upload_insert(); Type: ACL; Schema: vibetype; Owner: ci +-- + +REVOKE ALL ON FUNCTION vibetype.trigger_upload_insert() FROM PUBLIC; + + -- -- Name: TABLE upload; Type: ACL; Schema: vibetype; Owner: ci -- -GRANT SELECT ON TABLE vibetype.upload TO vibetype_account; GRANT SELECT ON TABLE vibetype.upload TO vibetype_anonymous; -GRANT SELECT,DELETE,UPDATE ON TABLE vibetype.upload TO vibetype; +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.upload TO vibetype_account; +GRANT SELECT,UPDATE ON TABLE vibetype.upload TO vibetype; -- From caa5e053a85f62861e3ddaee4d366c8db7a5a81a Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Mon, 12 May 2025 02:11:56 +0200 Subject: [PATCH 17/23] feat(upload)!: drop custom create function --- src/deploy/function_upload_create.sql | 33 ---- src/revert/function_upload_create.sql | 5 - src/sqitch.plan | 1 - src/verify/function_upload_create.sql | 9 - test/fixture/schema.definition.sql | 230 ++++++++++---------------- 5 files changed, 91 insertions(+), 187 deletions(-) delete mode 100644 src/deploy/function_upload_create.sql delete mode 100644 src/revert/function_upload_create.sql delete mode 100644 src/verify/function_upload_create.sql diff --git a/src/deploy/function_upload_create.sql b/src/deploy/function_upload_create.sql deleted file mode 100644 index 9bdfacd6..00000000 --- a/src/deploy/function_upload_create.sql +++ /dev/null @@ -1,33 +0,0 @@ -BEGIN; - -CREATE FUNCTION vibetype.upload_create( - size_byte BIGINT -) RETURNS vibetype.upload AS $$ -DECLARE - _upload vibetype.upload; -BEGIN - IF (COALESCE(( - SELECT SUM(upload.size_byte) - FROM vibetype.upload - WHERE upload.created_by = current_setting('jwt.claims.account_id')::UUID - ), 0) + upload_create.size_byte <= ( - SELECT upload_quota_bytes - FROM vibetype_private.account - WHERE account.id = current_setting('jwt.claims.account_id')::UUID - )) THEN - INSERT INTO vibetype.upload(created_by, size_byte) - VALUES (current_setting('jwt.claims.account_id')::UUID, upload_create.size_byte) - RETURNING upload.id INTO _upload; - - RETURN _upload; - ELSE - RAISE 'Upload quota limit reached!' USING ERRCODE = 'disk_full'; - END IF; -END; -$$ LANGUAGE PLPGSQL STRICT VOLATILE SECURITY DEFINER; - -COMMENT ON FUNCTION vibetype.upload_create(BIGINT) IS 'Creates an upload with the given size if quota is available.'; - -GRANT EXECUTE ON FUNCTION vibetype.upload_create(BIGINT) TO vibetype_account; - -COMMIT; diff --git a/src/revert/function_upload_create.sql b/src/revert/function_upload_create.sql deleted file mode 100644 index 4d43b72a..00000000 --- a/src/revert/function_upload_create.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN; - -DROP FUNCTION vibetype.upload_create(BIGINT); - -COMMIT; diff --git a/src/sqitch.plan b/src/sqitch.plan index a6eddd70..3193aef7 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -47,7 +47,6 @@ type_event_unlock_response [schema_public type_jwt] 1970-01-01T00:00:00Z Jonas T function_event_unlock [privilege_execute_revoke schema_public function_invoker_account_id table_event table_guest function_guest_claim_array type_jwt table_jwt type_event_unlock_response] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that assigns a guest to the current session function_jwt_refresh [privilege_execute_revoke schema_public type_jwt table_jwt] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that refreshes tokens. table_upload [schema_public table_account_public] 1970-01-01T00:00:00Z Jonas Thelemann # An upload. -function_upload_create [privilege_execute_revoke schema_public schema_private role_account table_upload table_account_private] 1970-01-01T00:00:00Z Jonas Thelemann # Creates an upload with the given size if quota is available. table_profile_picture [schema_public table_account_public table_upload role_account role_anonymous role_vibetype function_invoker_account_id] 1970-01-01T00:00:00Z Jonas Thelemann # Mapping of usernames to upload storage keys. table_upload_policy [schema_public table_upload role_account role_anonymous role_vibetype function_invoker_account_id] 1970-01-01T00:00:00Z Jonas Thelemann # Policies for uploads. function_profile_picture_set [privilege_execute_revoke schema_public role_account table_profile_picture] 1970-01-01T00:00:00Z Jonas Thelemann # Sets the picture with the given storage key as the invoker's profile picture. diff --git a/src/verify/function_upload_create.sql b/src/verify/function_upload_create.sql deleted file mode 100644 index b7844dbd..00000000 --- a/src/verify/function_upload_create.sql +++ /dev/null @@ -1,9 +0,0 @@ -BEGIN; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_function_privilege('vibetype_account', 'vibetype.upload_create(BIGINT)', 'EXECUTE')); - ASSERT NOT (SELECT pg_catalog.has_function_privilege('vibetype_anonymous', 'vibetype.upload_create(BIGINT)', 'EXECUTE')); -END $$; - -ROLLBACK; diff --git a/test/fixture/schema.definition.sql b/test/fixture/schema.definition.sql index 9c5fd0f0..c12e7908 100644 --- a/test/fixture/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -1933,128 +1933,6 @@ $$; ALTER FUNCTION vibetype.trigger_upload_insert() OWNER TO ci; --- --- Name: upload; Type: TABLE; Schema: vibetype; Owner: ci --- - -CREATE TABLE vibetype.upload ( - id uuid DEFAULT gen_random_uuid() NOT NULL, - name text, - size_byte bigint NOT NULL, - storage_key text, - type text DEFAULT 'image'::text NOT NULL, - created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - created_by uuid NOT NULL, - CONSTRAINT upload_name_check CHECK (((char_length(name) > 0) AND (char_length(name) < 300))), - CONSTRAINT upload_size_byte_check CHECK ((size_byte > 0)) -); - -ALTER TABLE ONLY vibetype.upload REPLICA IDENTITY FULL; - - -ALTER TABLE vibetype.upload OWNER TO ci; - --- --- Name: TABLE upload; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON TABLE vibetype.upload IS 'An upload.'; - - --- --- Name: COLUMN upload.id; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.id IS '@omit create,update -The upload''s internal id.'; - - --- --- Name: COLUMN upload.name; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.name IS 'The name of the uploaded file.'; - - --- --- Name: COLUMN upload.size_byte; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.size_byte IS '@omit update -The upload''s size in bytes.'; - - --- --- Name: COLUMN upload.storage_key; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.storage_key IS '@omit create,update -The upload''s storage key.'; - - --- --- Name: COLUMN upload.type; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.type IS '@omit create,update -The type of the uploaded file, default is ''image''.'; - - --- --- Name: COLUMN upload.created_at; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.created_at IS '@omit create,update -Timestamp of when the upload was created, defaults to the current timestamp.'; - - --- --- Name: COLUMN upload.created_by; Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON COLUMN vibetype.upload.created_by IS 'The uploader''s account id.'; - - --- --- Name: upload_create(bigint); Type: FUNCTION; Schema: vibetype; Owner: ci --- - -CREATE FUNCTION vibetype.upload_create(size_byte bigint) RETURNS vibetype.upload - LANGUAGE plpgsql STRICT SECURITY DEFINER - AS $$ -DECLARE - _upload vibetype.upload; -BEGIN - IF (COALESCE(( - SELECT SUM(upload.size_byte) - FROM vibetype.upload - WHERE upload.created_by = current_setting('jwt.claims.account_id')::UUID - ), 0) + upload_create.size_byte <= ( - SELECT upload_quota_bytes - FROM vibetype_private.account - WHERE account.id = current_setting('jwt.claims.account_id')::UUID - )) THEN - INSERT INTO vibetype.upload(created_by, size_byte) - VALUES (current_setting('jwt.claims.account_id')::UUID, upload_create.size_byte) - RETURNING upload.id INTO _upload; - - RETURN _upload; - ELSE - RAISE 'Upload quota limit reached!' USING ERRCODE = 'disk_full'; - END IF; -END; -$$; - - -ALTER FUNCTION vibetype.upload_create(size_byte bigint) OWNER TO ci; - --- --- Name: FUNCTION upload_create(size_byte bigint); Type: COMMENT; Schema: vibetype; Owner: ci --- - -COMMENT ON FUNCTION vibetype.upload_create(size_byte bigint) IS 'Creates an upload with the given size if quota is available.'; - - -- -- Name: account_block_ids(); Type: FUNCTION; Schema: vibetype_private; Owner: ci -- @@ -4441,6 +4319,88 @@ COMMENT ON CONSTRAINT report_check ON vibetype.report IS 'Ensures that the repor COMMENT ON CONSTRAINT report_reason_check ON vibetype.report IS 'Ensures the reason field contains between 1 and 2000 characters.'; +-- +-- Name: upload; Type: TABLE; Schema: vibetype; Owner: ci +-- + +CREATE TABLE vibetype.upload ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + name text, + size_byte bigint NOT NULL, + storage_key text, + type text DEFAULT 'image'::text NOT NULL, + created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + created_by uuid NOT NULL, + CONSTRAINT upload_name_check CHECK (((char_length(name) > 0) AND (char_length(name) < 300))), + CONSTRAINT upload_size_byte_check CHECK ((size_byte > 0)) +); + +ALTER TABLE ONLY vibetype.upload REPLICA IDENTITY FULL; + + +ALTER TABLE vibetype.upload OWNER TO ci; + +-- +-- Name: TABLE upload; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON TABLE vibetype.upload IS 'An upload.'; + + +-- +-- Name: COLUMN upload.id; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.id IS '@omit create,update +The upload''s internal id.'; + + +-- +-- Name: COLUMN upload.name; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.name IS 'The name of the uploaded file.'; + + +-- +-- Name: COLUMN upload.size_byte; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.size_byte IS '@omit update +The upload''s size in bytes.'; + + +-- +-- Name: COLUMN upload.storage_key; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.storage_key IS '@omit create,update +The upload''s storage key.'; + + +-- +-- Name: COLUMN upload.type; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.type IS '@omit create,update +The type of the uploaded file, default is ''image''.'; + + +-- +-- Name: COLUMN upload.created_at; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.created_at IS '@omit create,update +Timestamp of when the upload was created, defaults to the current timestamp.'; + + +-- +-- Name: COLUMN upload.created_by; Type: COMMENT; Schema: vibetype; Owner: ci +-- + +COMMENT ON COLUMN vibetype.upload.created_by IS 'The uploader''s account id.'; + + -- -- Name: account; Type: TABLE; Schema: vibetype_private; Owner: ci -- @@ -7065,23 +7025,6 @@ REVOKE ALL ON FUNCTION vibetype.trigger_metadata_update_fcm() FROM PUBLIC; REVOKE ALL ON FUNCTION vibetype.trigger_upload_insert() FROM PUBLIC; --- --- Name: TABLE upload; Type: ACL; Schema: vibetype; Owner: ci --- - -GRANT SELECT ON TABLE vibetype.upload TO vibetype_anonymous; -GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.upload TO vibetype_account; -GRANT SELECT,UPDATE ON TABLE vibetype.upload TO vibetype; - - --- --- Name: FUNCTION upload_create(size_byte bigint); Type: ACL; Schema: vibetype; Owner: ci --- - -REVOKE ALL ON FUNCTION vibetype.upload_create(size_byte bigint) FROM PUBLIC; -GRANT ALL ON FUNCTION vibetype.upload_create(size_byte bigint) TO vibetype_account; - - -- -- Name: FUNCTION account_block_ids(); Type: ACL; Schema: vibetype_private; Owner: ci -- @@ -7362,6 +7305,15 @@ GRANT SELECT,DELETE ON TABLE vibetype.profile_picture TO vibetype; GRANT SELECT,INSERT ON TABLE vibetype.report TO vibetype_account; +-- +-- Name: TABLE upload; Type: ACL; Schema: vibetype; Owner: ci +-- + +GRANT SELECT ON TABLE vibetype.upload TO vibetype_anonymous; +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.upload TO vibetype_account; +GRANT SELECT,UPDATE ON TABLE vibetype.upload TO vibetype; + + -- -- Name: TABLE achievement_code; Type: ACL; Schema: vibetype_private; Owner: ci -- From 52431bb791df6b0df22fc94fe2e9c874719be2f3 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 12 May 2025 22:45:56 +0000 Subject: [PATCH 18/23] chore(release): 8.0.0-beta.8 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [8.0.0-beta.8](https://github.com/maevsi/sqitch/compare/8.0.0-beta.7...8.0.0-beta.8) (2025-05-12) ### ⚠ BREAKING CHANGES * **upload:** drop custom create function * **upload:** rework permissions ### Features * **upload:** drop custom create function ([caa5e05](https://github.com/maevsi/sqitch/commit/caa5e053a85f62861e3ddaee4d366c8db7a5a81a)) * **upload:** rework permissions ([bfb3603](https://github.com/maevsi/sqitch/commit/bfb36037b1e804184dd12b18cbc2acffe4ea9519)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47495f4f..ee3ecee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [8.0.0-beta.8](https://github.com/maevsi/sqitch/compare/8.0.0-beta.7...8.0.0-beta.8) (2025-05-12) + +### ⚠ BREAKING CHANGES + +* **upload:** drop custom create function +* **upload:** rework permissions + +### Features + +* **upload:** drop custom create function ([caa5e05](https://github.com/maevsi/sqitch/commit/caa5e053a85f62861e3ddaee4d366c8db7a5a81a)) +* **upload:** rework permissions ([bfb3603](https://github.com/maevsi/sqitch/commit/bfb36037b1e804184dd12b18cbc2acffe4ea9519)) + ## [8.0.0-beta.7](https://github.com/maevsi/sqitch/compare/8.0.0-beta.6...8.0.0-beta.7) (2025-05-10) ### Bug Fixes diff --git a/package.json b/package.json index f93ecec2..d3db0fea 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,5 @@ "test:update": "pnpm run test --update" }, "type": "module", - "version": "8.0.0-beta.7" + "version": "8.0.0-beta.8" } From b26e0b7708720f377a278a29355e7d6d386a82b2 Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Tue, 13 May 2025 01:51:06 +0200 Subject: [PATCH 19/23] chore: sort service secrets --- Dockerfile | 2 +- src/sqitch | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ed45ad36..68c545b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,8 +39,8 @@ RUN apt-get update \ && echo "postgraphile" > /run/secrets/postgres_role_service_postgraphile_username \ && echo "vibetype" > /run/secrets/postgres_role_service_vibetype_username \ && echo "placeholder" | tee \ - /run/secrets/postgres_role_service_vibetype_password \ /run/secrets/postgres_role_service_postgraphile_password \ + /run/secrets/postgres_role_service_vibetype_password \ /dev/null COPY ./src ./src diff --git a/src/sqitch b/src/sqitch index 4fd6c129..925ce631 100755 --- a/src/sqitch +++ b/src/sqitch @@ -79,8 +79,8 @@ function docker_sudo() { docker_sudo run --rm --network host \ --mount "type=bind,src=$THIS,dst=/repo" \ --mount "type=bind,src=$HOME,dst=$homedst" \ - --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_vibetype_password.secret,dst=/run/secrets/postgres_role_service_vibetype_password" \ - --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_vibetype_username.secret,dst=/run/secrets/postgres_role_service_vibetype_username" \ --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_postgraphile_password.secret,dst=/run/secrets/postgres_role_service_postgraphile_password" \ --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_postgraphile_username.secret,dst=/run/secrets/postgres_role_service_postgraphile_username" \ + --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_vibetype_password.secret,dst=/run/secrets/postgres_role_service_vibetype_password" \ + --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_vibetype_username.secret,dst=/run/secrets/postgres_role_service_vibetype_username" \ "${passopt[@]}" "$SQITCH_IMAGE" "$@" From 0fbae08feb875e51c2fc19ac18a3d9a25f4f2234 Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Tue, 13 May 2025 05:50:17 +0200 Subject: [PATCH 20/23] feat(grafana): readd --- Dockerfile | 2 ++ src/deploy/database_grafana.sql | 8 ++++++++ src/deploy/role_grafana.sql | 9 +++++++++ src/deploy/schema_private.sql | 4 ++++ src/deploy/table_account_private.sql | 4 ++++ src/revert/database_grafana.sql | 1 + src/revert/role_grafana.sql | 7 +++++++ src/sqitch | 2 ++ src/sqitch.plan | 2 ++ src/verify/database_grafana.sql | 8 ++++++++ src/verify/role_grafana.sql | 13 +++++++++++++ test/fixture/schema.definition.sql | 14 ++++++++++++++ 12 files changed, 74 insertions(+) create mode 100644 src/deploy/database_grafana.sql create mode 100644 src/deploy/role_grafana.sql create mode 100644 src/revert/database_grafana.sql create mode 100644 src/revert/role_grafana.sql create mode 100644 src/verify/database_grafana.sql create mode 100644 src/verify/role_grafana.sql diff --git a/Dockerfile b/Dockerfile index 68c545b2..b141eb23 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,10 +35,12 @@ RUN apt-get update \ && apt-get install --no-install-recommends -y \ sqitch=1.1.0000-1 \ && mkdir -p /run/secrets \ + && echo "grafana" > /run/secrets/postgres_role_service_grafana_username \ && echo "postgres" > /run/secrets/postgres_password \ && echo "postgraphile" > /run/secrets/postgres_role_service_postgraphile_username \ && echo "vibetype" > /run/secrets/postgres_role_service_vibetype_username \ && echo "placeholder" | tee \ + /run/secrets/postgres_role_service_grafana_password \ /run/secrets/postgres_role_service_postgraphile_password \ /run/secrets/postgres_role_service_vibetype_password \ /dev/null diff --git a/src/deploy/database_grafana.sql b/src/deploy/database_grafana.sql new file mode 100644 index 00000000..a9f37819 --- /dev/null +++ b/src/deploy/database_grafana.sql @@ -0,0 +1,8 @@ +\set role_service_grafana_username `cat /run/secrets/postgres_role_service_grafana_username` + +SELECT 'CREATE DATABASE grafana OWNER "' || :'role_service_grafana_username' || '";' +WHERE NOT EXISTS ( + SELECT FROM pg_database WHERE datname = 'grafana' +)\gexec + +COMMENT ON DATABASE grafana IS 'The observation dashboard''s database.'; diff --git a/src/deploy/role_grafana.sql b/src/deploy/role_grafana.sql new file mode 100644 index 00000000..31715e63 --- /dev/null +++ b/src/deploy/role_grafana.sql @@ -0,0 +1,9 @@ +BEGIN; + +\set role_service_grafana_password `cat /run/secrets/postgres_role_service_grafana_password` +\set role_service_grafana_username `cat /run/secrets/postgres_role_service_grafana_username` + +DROP ROLE IF EXISTS :role_service_grafana_username; +CREATE ROLE :role_service_grafana_username LOGIN PASSWORD :'role_service_grafana_password'; + +COMMIT; diff --git a/src/deploy/schema_private.sql b/src/deploy/schema_private.sql index e8f7c00f..d044bd43 100644 --- a/src/deploy/schema_private.sql +++ b/src/deploy/schema_private.sql @@ -1,7 +1,11 @@ BEGIN; +\set role_service_grafana_username `cat /run/secrets/postgres_role_service_grafana_username` + CREATE SCHEMA vibetype_private; COMMENT ON SCHEMA vibetype_private IS 'Contains account information and is not used by PostGraphile.'; +GRANT USAGE ON SCHEMA vibetype_private TO :role_service_grafana_username; + COMMIT; diff --git a/src/deploy/table_account_private.sql b/src/deploy/table_account_private.sql index a44bd875..49d5d7a6 100644 --- a/src/deploy/table_account_private.sql +++ b/src/deploy/table_account_private.sql @@ -1,5 +1,7 @@ BEGIN; +\set role_service_grafana_username `cat /run/secrets/postgres_role_service_grafana_username` + CREATE TABLE vibetype_private.account ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), @@ -86,4 +88,6 @@ CREATE TRIGGER vibetype_private_account_password_reset_verification_valid_until FOR EACH ROW EXECUTE PROCEDURE vibetype_private.account_password_reset_verification_valid_until(); +GRANT SELECT ON TABLE vibetype_private.account TO :role_service_grafana_username; + COMMIT; diff --git a/src/revert/database_grafana.sql b/src/revert/database_grafana.sql new file mode 100644 index 00000000..b4229d9e --- /dev/null +++ b/src/revert/database_grafana.sql @@ -0,0 +1 @@ +DROP DATABASE grafana WITH (FORCE); diff --git a/src/revert/role_grafana.sql b/src/revert/role_grafana.sql new file mode 100644 index 00000000..07f63f0e --- /dev/null +++ b/src/revert/role_grafana.sql @@ -0,0 +1,7 @@ +BEGIN; + +\set role_service_grafana_username `cat /run/secrets/postgres_role_service_grafana_username` + +DROP ROLE :role_service_grafana_username; + +COMMIT; diff --git a/src/sqitch b/src/sqitch index 925ce631..b74f4ef0 100755 --- a/src/sqitch +++ b/src/sqitch @@ -79,6 +79,8 @@ function docker_sudo() { docker_sudo run --rm --network host \ --mount "type=bind,src=$THIS,dst=/repo" \ --mount "type=bind,src=$HOME,dst=$homedst" \ + --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_grafana_password.secret,dst=/run/secrets/postgres_role_service_grafana_password" \ + --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_grafana_username.secret,dst=/run/secrets/postgres_role_service_grafana_username" \ --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_postgraphile_password.secret,dst=/run/secrets/postgres_role_service_postgraphile_password" \ --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_postgraphile_username.secret,dst=/run/secrets/postgres_role_service_postgraphile_username" \ --mount "type=bind,src=$THIS/../../stack/src/development/secrets/postgres/role_service_vibetype_password.secret,dst=/run/secrets/postgres_role_service_vibetype_password" \ diff --git a/src/sqitch.plan b/src/sqitch.plan index 3193aef7..381ecf49 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -3,6 +3,8 @@ %uri=https://github.com/maevsi/vibetype/ privilege_execute_revoke 1970-01-01T00:00:00Z Jonas Thelemann # Revoke execute privilege from public. +role_grafana 1970-01-01T00:00:00Z Jonas Thelemann # Add role grafana. +database_grafana [role_grafana] 1970-01-01T00:00:00Z Jonas Thelemann # Add the database for grafana. role_postgraphile 1970-01-01T00:00:00Z Jonas Thelemann # Add role postgraphile. role_anonymous [role_postgraphile] 1970-01-01T00:00:00Z Jonas Thelemann # Add role anonymous. role_account [role_postgraphile] 1970-01-01T00:00:00Z Jonas Thelemann # Add role account. diff --git a/src/verify/database_grafana.sql b/src/verify/database_grafana.sql new file mode 100644 index 00000000..09570d2d --- /dev/null +++ b/src/verify/database_grafana.sql @@ -0,0 +1,8 @@ +BEGIN; + +DO $$ +BEGIN + ASSERT (SELECT 1 FROM pg_database WHERE datname='grafana') = 1; +END $$; + +ROLLBACK; diff --git a/src/verify/role_grafana.sql b/src/verify/role_grafana.sql new file mode 100644 index 00000000..56f26b29 --- /dev/null +++ b/src/verify/role_grafana.sql @@ -0,0 +1,13 @@ +BEGIN; + +\set role_service_grafana_username `cat /run/secrets/postgres_role_service_grafana_username` + +SET LOCAL role.service_grafana_username TO :'role_service_grafana_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.pg_has_role(current_setting('role.service_grafana_username'), 'USAGE')); + -- Other accounts might not exist yet for a NOT-check. +END $$; + +ROLLBACK; diff --git a/test/fixture/schema.definition.sql b/test/fixture/schema.definition.sql index c12e7908..9eef22a0 100644 --- a/test/fixture/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -6486,6 +6486,13 @@ GRANT USAGE ON SCHEMA vibetype TO vibetype_account; GRANT USAGE ON SCHEMA vibetype TO vibetype; +-- +-- Name: SCHEMA vibetype_private; Type: ACL; Schema: -; Owner: ci +-- + +GRANT USAGE ON SCHEMA vibetype_private TO grafana; + + -- -- Name: FUNCTION armor(bytea); Type: ACL; Schema: public; Owner: ci -- @@ -7314,6 +7321,13 @@ GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE vibetype.upload TO vibetype_account; GRANT SELECT,UPDATE ON TABLE vibetype.upload TO vibetype; +-- +-- Name: TABLE account; Type: ACL; Schema: vibetype_private; Owner: ci +-- + +GRANT SELECT ON TABLE vibetype_private.account TO grafana; + + -- -- Name: TABLE achievement_code; Type: ACL; Schema: vibetype_private; Owner: ci -- From 9c24ddbb6475775dc4ba1969e23e71dada61b03c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 13 May 2025 04:16:45 +0000 Subject: [PATCH 21/23] chore(release): 8.0.0-beta.9 [skip ci] ## [8.0.0-beta.9](https://github.com/maevsi/sqitch/compare/8.0.0-beta.8...8.0.0-beta.9) (2025-05-13) ### Features * **grafana:** readd ([0fbae08](https://github.com/maevsi/sqitch/commit/0fbae08feb875e51c2fc19ac18a3d9a25f4f2234)) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee3ecee7..46d022b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [8.0.0-beta.9](https://github.com/maevsi/sqitch/compare/8.0.0-beta.8...8.0.0-beta.9) (2025-05-13) + +### Features + +* **grafana:** readd ([0fbae08](https://github.com/maevsi/sqitch/commit/0fbae08feb875e51c2fc19ac18a3d9a25f4f2234)) + ## [8.0.0-beta.8](https://github.com/maevsi/sqitch/compare/8.0.0-beta.7...8.0.0-beta.8) (2025-05-12) ### ⚠ BREAKING CHANGES diff --git a/package.json b/package.json index d3db0fea..cce88b28 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,5 @@ "test:update": "pnpm run test --update" }, "type": "module", - "version": "8.0.0-beta.8" + "version": "8.0.0-beta.9" } From dec870a9236a44adf688a4d61444e138afb9c1bb Mon Sep 17 00:00:00 2001 From: Jonas Thelemann Date: Thu, 15 May 2025 09:21:39 +0200 Subject: [PATCH 22/23] fix(address): allow selects for accessible events --- src/deploy/table_address.sql | 17 ---------- src/deploy/table_address_policy.sql | 24 ++++++++++++++ src/deploy/table_event_policy.sql | 43 ++++++++++++++++--------- src/revert/table_address.sql | 2 -- src/revert/table_address_policy.sql | 5 +++ src/revert/table_event_policy.sql | 3 +- src/sqitch.plan | 1 + src/verify/table_address.sql | 23 -------------- src/verify/table_address_policy.sql | 22 +++++++++++++ test/fixture/schema.definition.sql | 49 +++++++++++++++++++++++++++-- 10 files changed, 128 insertions(+), 61 deletions(-) create mode 100644 src/deploy/table_address_policy.sql create mode 100644 src/revert/table_address_policy.sql create mode 100644 src/verify/table_address_policy.sql diff --git a/src/deploy/table_address.sql b/src/deploy/table_address.sql index d565acb9..f156852a 100644 --- a/src/deploy/table_address.sql +++ b/src/deploy/table_address.sql @@ -48,21 +48,4 @@ CREATE TRIGGER vibetype_trigger_address_update FOR EACH ROW EXECUTE PROCEDURE vibetype.trigger_metadata_update(); -GRANT SELECT ON TABLE vibetype.address TO vibetype_anonymous; -GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.address TO vibetype_account; - -ALTER TABLE vibetype.address ENABLE ROW LEVEL SECURITY; - -CREATE POLICY address_all ON vibetype.address FOR ALL -USING ( - created_by = vibetype.invoker_account_id() - AND - created_by NOT IN ( - SELECT id FROM vibetype_private.account_block_ids() - ) -) -WITH CHECK ( - created_by = vibetype.invoker_account_id() -); - COMMIT; diff --git a/src/deploy/table_address_policy.sql b/src/deploy/table_address_policy.sql new file mode 100644 index 00000000..d3924e59 --- /dev/null +++ b/src/deploy/table_address_policy.sql @@ -0,0 +1,24 @@ +BEGIN; + +GRANT SELECT ON TABLE vibetype.address TO vibetype_anonymous; +GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE vibetype.address TO vibetype_account; + +ALTER TABLE vibetype.address ENABLE ROW LEVEL SECURITY; + +CREATE POLICY address_all ON vibetype.address FOR ALL +USING ( + ( + created_by = vibetype.invoker_account_id() + OR + id IN (SELECT address_id FROM vibetype_private.event_policy_select()) + ) + AND + created_by NOT IN ( + SELECT id FROM vibetype_private.account_block_ids() + ) +) +WITH CHECK ( + created_by = vibetype.invoker_account_id() +); + +COMMIT; diff --git a/src/deploy/table_event_policy.sql b/src/deploy/table_event_policy.sql index 22781741..c081a3d2 100644 --- a/src/deploy/table_event_policy.sql +++ b/src/deploy/table_event_policy.sql @@ -13,23 +13,36 @@ USING ( -- Only display events that are public and not full and not organized by a blocked account. -- Only display events to which oneself is invited, but not by a guest created by a blocked account. +CREATE FUNCTION vibetype_private.event_policy_select() +RETURNS SETOF vibetype.event AS $$ +BEGIN + RETURN QUERY + SELECT * FROM vibetype.event e + WHERE ( + ( + e.visibility = 'public' + AND ( + e.guest_count_maximum IS NULL + OR e.guest_count_maximum > vibetype.guest_count(e.id) + ) + AND e.created_by NOT IN ( + SELECT id FROM vibetype_private.account_block_ids() + ) + ) + OR ( + e.id IN ( + SELECT * FROM vibetype_private.events_invited() + ) + ) + ); +END +$$ LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER; + +GRANT EXECUTE ON FUNCTION vibetype_private.event_policy_select() TO vibetype_account, vibetype_anonymous; + CREATE POLICY event_select ON vibetype.event FOR SELECT USING ( - ( - visibility = 'public' - AND - ( - guest_count_maximum IS NULL - OR - guest_count_maximum > (vibetype.guest_count(id)) -- Using the function here is required as there would otherwise be infinite recursion. - ) - AND created_by NOT IN ( - SELECT id FROM vibetype_private.account_block_ids() - ) - ) - OR ( - id IN (SELECT vibetype_private.events_invited()) - ) + id IN (SELECT id FROM vibetype_private.event_policy_select()) ); COMMIT; diff --git a/src/revert/table_address.sql b/src/revert/table_address.sql index 1d0b99c4..eac792b5 100644 --- a/src/revert/table_address.sql +++ b/src/revert/table_address.sql @@ -1,7 +1,5 @@ BEGIN; -DROP POLICY address_all ON vibetype.address; - DROP TRIGGER vibetype_trigger_address_update ON vibetype.address; DROP INDEX vibetype.idx_address_updated_by; diff --git a/src/revert/table_address_policy.sql b/src/revert/table_address_policy.sql new file mode 100644 index 00000000..1abee848 --- /dev/null +++ b/src/revert/table_address_policy.sql @@ -0,0 +1,5 @@ +BEGIN; + +DROP POLICY address_all ON vibetype.address; + +COMMIT; diff --git a/src/revert/table_event_policy.sql b/src/revert/table_event_policy.sql index 3d79ea9e..10b5f26e 100644 --- a/src/revert/table_event_policy.sql +++ b/src/revert/table_event_policy.sql @@ -1,6 +1,7 @@ BEGIN; -DROP POLICY event_all ON vibetype.event; DROP POLICY event_select ON vibetype.event; +DROP FUNCTION vibetype_private.event_policy_select; +DROP POLICY event_all ON vibetype.event; COMMIT; diff --git a/src/sqitch.plan b/src/sqitch.plan index 381ecf49..cb81213a 100644 --- a/src/sqitch.plan +++ b/src/sqitch.plan @@ -35,6 +35,7 @@ function_guest_contact_ids [privilege_execute_revoke schema_public table_guest f table_contact_policy [schema_public table_contact role_account role_anonymous function_invoker_account_id function_account_block_ids function_guest_contact_ids] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table contact. function_guest_count [privilege_execute_revoke schema_public table_guest role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns the guest count for an event. table_event_policy [schema_public table_event role_account role_anonymous function_guest_count function_account_block_ids function_invoker_account_id schema_private function_events_invited] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table event. +table_address_policy [schema_public table_address role_anonymous role_account function_invoker_account_id table_event_policy function_account_block_ids] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table address. function_event_guest_count_maximum [privilege_execute_revoke schema_public table_event function_guest_count function_invoker_account_id schema_private function_events_invited role_account role_anonymous] 1970-01-01T00:00:00Z Jonas Thelemann # Add a function that returns the maximum guest count of an accessible event. table_guest_policy [schema_public table_guest role_account role_anonymous function_guest_claim_array function_invoker_account_id function_events_organized function_account_block_ids function_event_guest_count_maximum] 1970-01-01T00:00:00Z Jonas Thelemann # Add policy for table contact. type_jwt [schema_public] 1970-01-01T00:00:00Z Jonas Thelemann # Add type jwt. diff --git a/src/verify/table_address.sql b/src/verify/table_address.sql index 89a3d315..5c6411ad 100644 --- a/src/verify/table_address.sql +++ b/src/verify/table_address.sql @@ -18,26 +18,3 @@ SELECT id, FROM vibetype.address WHERE FALSE; ROLLBACK; - -BEGIN; - -\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` -SET local role.vibetype_username TO :'role_service_vibetype_username'; - -DO $$ -BEGIN - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'SELECT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'INSERT')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'UPDATE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'DELETE')); - ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'DELETE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'SELECT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'INSERT')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'UPDATE')); - ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'DELETE')); -END $$; - -ROLLBACK; \ No newline at end of file diff --git a/src/verify/table_address_policy.sql b/src/verify/table_address_policy.sql new file mode 100644 index 00000000..cdf13553 --- /dev/null +++ b/src/verify/table_address_policy.sql @@ -0,0 +1,22 @@ +BEGIN; + +\set role_service_vibetype_username `cat /run/secrets/postgres_role_service_vibetype_username` +SET local role.vibetype_username TO :'role_service_vibetype_username'; + +DO $$ +BEGIN + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'SELECT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'INSERT')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'UPDATE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_account', 'vibetype.address', 'DELETE')); + ASSERT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege('vibetype_anonymous', 'vibetype.address', 'DELETE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'SELECT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'INSERT')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'UPDATE')); + ASSERT NOT (SELECT pg_catalog.has_table_privilege(current_setting('role.vibetype_username'), 'vibetype.address', 'DELETE')); +END $$; + +ROLLBACK; diff --git a/test/fixture/schema.definition.sql b/test/fixture/schema.definition.sql index 9eef22a0..e6341b2b 100644 --- a/test/fixture/schema.definition.sql +++ b/test/fixture/schema.definition.sql @@ -2055,6 +2055,39 @@ ALTER FUNCTION vibetype_private.adjust_audit_log_id_seq() OWNER TO ci; COMMENT ON FUNCTION vibetype_private.adjust_audit_log_id_seq() IS 'Function resetting the current value of the sequence vibetype_private.audit_log_id_seq according to the content of table audit_log.'; +-- +-- Name: event_policy_select(); Type: FUNCTION; Schema: vibetype_private; Owner: ci +-- + +CREATE FUNCTION vibetype_private.event_policy_select() RETURNS SETOF vibetype.event + LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER + AS $$ +BEGIN + RETURN QUERY + SELECT * FROM vibetype.event e + WHERE ( + ( + e.visibility = 'public' + AND ( + e.guest_count_maximum IS NULL + OR e.guest_count_maximum > vibetype.guest_count(e.id) + ) + AND e.created_by NOT IN ( + SELECT id FROM vibetype_private.account_block_ids() + ) + ) + OR ( + e.id IN ( + SELECT * FROM vibetype_private.events_invited() + ) + ) + ); +END +$$; + + +ALTER FUNCTION vibetype_private.event_policy_select() OWNER TO ci; + -- -- Name: events_invited(); Type: FUNCTION; Schema: vibetype_private; Owner: ci -- @@ -6066,7 +6099,8 @@ ALTER TABLE vibetype.address ENABLE ROW LEVEL SECURITY; -- Name: address address_all; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY address_all ON vibetype.address USING (((created_by = vibetype.invoker_account_id()) AND (NOT (created_by IN ( SELECT account_block_ids.id +CREATE POLICY address_all ON vibetype.address USING ((((created_by = vibetype.invoker_account_id()) OR (id IN ( SELECT event_policy_select.address_id + FROM vibetype_private.event_policy_select() event_policy_select(id, address_id, description, "end", guest_count_maximum, is_archived, is_in_person, is_remote, language, name, slug, start, url, visibility, created_at, created_by, search_vector)))) AND (NOT (created_by IN ( SELECT account_block_ids.id FROM vibetype_private.account_block_ids() account_block_ids(id)))))) WITH CHECK ((created_by = vibetype.invoker_account_id())); @@ -6230,8 +6264,8 @@ CREATE POLICY event_recommendation_select ON vibetype.event_recommendation FOR S -- Name: event event_select; Type: POLICY; Schema: vibetype; Owner: ci -- -CREATE POLICY event_select ON vibetype.event FOR SELECT USING ((((visibility = 'public'::vibetype.event_visibility) AND ((guest_count_maximum IS NULL) OR (guest_count_maximum > vibetype.guest_count(id))) AND (NOT (created_by IN ( SELECT account_block_ids.id - FROM vibetype_private.account_block_ids() account_block_ids(id))))) OR (id IN ( SELECT vibetype_private.events_invited() AS events_invited)))); +CREATE POLICY event_select ON vibetype.event FOR SELECT USING ((id IN ( SELECT event_policy_select.id + FROM vibetype_private.event_policy_select() event_policy_select(id, address_id, description, "end", guest_count_maximum, is_archived, is_in_person, is_remote, language, name, slug, start, url, visibility, created_at, created_by, search_vector)))); -- @@ -7064,6 +7098,15 @@ GRANT ALL ON FUNCTION vibetype_private.account_password_reset_verification_valid REVOKE ALL ON FUNCTION vibetype_private.adjust_audit_log_id_seq() FROM PUBLIC; +-- +-- Name: FUNCTION event_policy_select(); Type: ACL; Schema: vibetype_private; Owner: ci +-- + +REVOKE ALL ON FUNCTION vibetype_private.event_policy_select() FROM PUBLIC; +GRANT ALL ON FUNCTION vibetype_private.event_policy_select() TO vibetype_account; +GRANT ALL ON FUNCTION vibetype_private.event_policy_select() TO vibetype_anonymous; + + -- -- Name: FUNCTION events_invited(); Type: ACL; Schema: vibetype_private; Owner: ci -- From ae6c49c71a99fd0f9f48b8570a45e7d9515b4102 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 15 May 2025 10:00:22 +0000 Subject: [PATCH 23/23] chore(release): 8.0.0-beta.10 [skip ci] ## [8.0.0-beta.10](https://github.com/maevsi/sqitch/compare/8.0.0-beta.9...8.0.0-beta.10) (2025-05-15) ### Bug Fixes * **address:** allow selects for accessible events ([dec870a](https://github.com/maevsi/sqitch/commit/dec870a9236a44adf688a4d61444e138afb9c1bb)) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46d022b0..eadc641b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [8.0.0-beta.10](https://github.com/maevsi/sqitch/compare/8.0.0-beta.9...8.0.0-beta.10) (2025-05-15) + +### Bug Fixes + +* **address:** allow selects for accessible events ([dec870a](https://github.com/maevsi/sqitch/commit/dec870a9236a44adf688a4d61444e138afb9c1bb)) + ## [8.0.0-beta.9](https://github.com/maevsi/sqitch/compare/8.0.0-beta.8...8.0.0-beta.9) (2025-05-13) ### Features diff --git a/package.json b/package.json index cce88b28..880dcc88 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,5 @@ "test:update": "pnpm run test --update" }, "type": "module", - "version": "8.0.0-beta.9" + "version": "8.0.0-beta.10" }